Carte Extension Arduino

De Wiki de Projets IMA

Introduction

Le but de ce projet est de réaliser une carte d'extension pour une plateforme open-source Arduino afin de repousser les limites de ce matériel. Ce projet se divise en deux parties : Réalisation électronique et Réalisation informatique.

Réalisation électronique (Extrait du sujet)

  • Carte d'extension pour Arduino : Des cartes d'extension pour Arduino existent déjà, mais ne permettent en général que d'ajouter une seule fonctionnalité. Il s'agit ici de réaliser une carte d'extension permettant d'ajouter deux, voire trois fonctionnalités à une carte Arduino. Il pourrait s'agir, par exemple d'intégrer un affichage (écran TFT) et une connectivité sans fil de type ZIGBEE ou WIFI.

Réalisation informatique (Extrait du sujet)

  • L'écriture d'une API permettant de réaliser - a minima - les fonctions de base est à prévoir.

Préparation

Des fonctionnalités à réaliser

  • Détection du volume de son
  • Connexion sans fil de type "Zigbee"
  • Affichage sur écran TFT

Description détaillée

  • Traitement du signal analogique émis par le microphone
  • Affichage d'infomations concernant le volume sur écran TFT
  • Réalisation de la transmission de chaînes de catactères entre un ordinateur équipé d'un "XBee Explorer" et un Arduino avec "XBee Shield"
  • Affichage pour des chaînes de caractères transmises via Zigbee sur écran TFT
  • Ajout d'un bouton poussoir permettant de réinitialiser l'affichage d'écran.

Matériel Requis

  • une grande platine d'essai; (reçu)
  • micro-contrôleur Arduino ; (reçu)
  • un micro (reçu) + un AOP + des résistances et des contensateurs pour l'adaptation (reçu)
  • un écran TFT en couleur : Color LCD Shield - Ref.LCD-09363 (reçu)
  • un module Wifi pour arduino : WiFly Shield - Ref.WRL-09954 (reçu) --- Non utilisé à cause de l'infaisabilité
  • deux puces XBee + XBee Shield + XBee Explorer (reçu)


Réalisation

Prise en main du module Wifi

  • Téléchargement de la bibliothèque sur le forum officiel Sparkfun
  • Création du programme de base permettant l'utilisation de l'interface de configuration du module Wifi. Voir la documentation du module Wifi
  • Configuration du module Wifi pour établir une connexion "Point à Point" sans fils :

IP : 192.168.0.2 Masque : 255.255.255.0 Passerelle : 192.168.0.1

  • Configuration d'un ordinateur portable équipé d'une carte réseau sans fils :

SSID : ProjetIMA4_LV_CHEN IP : 192.168.0.1 Masque : 255.255.255.0

  • Finalement, on a réussi à se connecter à cet ordinateur à partir du module Wifi (ping OK)

Développement sur la communication de type Zigbee

Paramétrage et configuration de XBee

  • Dans un premier temps, on télécharge puis installe le logiciel "X-CTU" qui est un logiciel de paramètrage spécialement conçu pour tous les modules Radio (dont les modules XBee)
  • On peut paraméter le module XBee soit avec "XBee Shield", soit avec "XBee Explorer", si on veut utiliser le "XBee Shield", il faut mettre l'interrupteur "USB/XBEE" à la position "USB"
  • On met une puce XBee sur le "XBee Shield" ou "XBee Explorer" puis branche sur l'ordinateur
  • On lance le logiciel X-CTU pour commencer la configuration du module Xbee, dans l'onglet « PC Settings », on effectue un test en utilisant les paramètres par défaut

Image1.jpg

  • Ensuite, une fenêtre s'apparaît qui nous informe que le test de la connexion a été réussi :

Image2.jpg

  • Dans l'onglet « Modem configuration », on clique sur le bouton « Read » afin de récupérer les paramètres de configurations du module Xbee :

Image3.jpg

  • Dans la capture d'écran ci-dessus, on s'intéresse aux paramètres CH, PAN ID, DH&DL, MY et SH&SL.
    • CH : Le numéro du canal à utiliser pour la transmission des informations. Il existe 16 canaux dans la bande Zigbee allouée.
    • PAN ID : Il signifie l'identifiant du PAN (Personnal Area Network) dans lequel seront immergés les modules.
    • MY : Il désigne l'adresse de source en 16 bits
    • DH&DL: Ces deux paramètres constituent l'adresse de destination, DH représente les bits de poids fort et DL représente les bits de poids faible.
    • SH&SL : Ces deux paramètres constituent le numéro de la liaison série, SH représente les bits de poids fort et SL représente les bits de poids faible.
  • Ensuite, on procède à la communication entre 2 modules XBee, voici la configuration que l'on a mise en oeuvre ci-dessous :

Image4.jpg

Pour une autre puce XBee, on utilise la même configuration, en effet, pour réussir à établir la connexion Zigbee, il faut que les paramètres CH et PAN ID soient identiques, ainsi, les paramètres DH&DL de l'émetteur et le paramètre du récepteur MY doivent également être identiques.

  • Tableau Récapitulatif de la configuration :

Image5.jpg

  • On rajoute qu'il est aussi possible de configurer les paramètres du module XBee à partir du « Terminal » (équivalent à la configuration par interface graphique) :
    • Pour l'envoi : il suffit d'entrer directement le message à envoyer dans le terminal, le message envoyé sera affiché en bleu.
    • Pour la réception : ce que le module Xbee reçoit va afficher automatiquement dans le terminal et en rouge.
    • Pour la configuration :
 - +++ : Activer le mode de configuration
            - atch : affichage du numéro du canal utilisé
            - atid : affichage de l'identifiant du PAN
            - atmy : affichage de l'adresse de source
            - atdl : affichage de l'adresse de destination de poids faible
            - Pour modifier le paramètre, il faut ajouter la valeur après le nom de commande, par exemple : « atid3322 »
 - atcn : sortir du mode de configuration

Programmation pour le module XBee et TFT

  • Faisabilité à vérifier : Le module XBee utilise le port série (UART) , et le module TFT utilise le SPI (Serial Peripheral Interface), cela ne pose donc pas de conflit...
  • Pour envoyer ou recevoir une chaîne de caractères à partir d'un ordinateur (module XBee + XBee Explorer), ceci se fait en utilisant le Terminal du logiciel X-CTU, dans ce terminal, le caractère envoyé est en bleu, le caractère reçu est en rouge
  • Pour envoyer ou recevoir une chaîne de caractères à partir de l'Arduino (module XBee + XBee Shield), sachant que le module XBee communique le micro-contrôleur Arduino par le port série, au niveau de la transmission d'un caractère, on peut directement lire ou écrire la donnée au port série à l'aide des fonctions "Serial.read()" et "Serial.print()"
    • La fonction "Serial.read()" ne peut lire qu'un seul caractère chaque fois, afin de pouvoir afficher une chaîne de caractère sur écran TFT, il est nécessaire d'utiliser un tampon qui enregiste le caractère reçu par arduino au fur et à mesure,

Prise en main de l'écran TFT

  • Téléchargement de la bibliothèque sur un site d'amateur un site d'amateur
  • Essai d'un exemple pour l'affichage sur l'écran TFT, on est arrivé à afficher des figures géométriques sur cet écran (par exemple : des cercles, des carrés, des triangles, etc..)

Test du micro

Etude de composants analogiques

Le signal du micro est très faible par rapport au arduino, alors, il faut un AOP pour amplifier le signal du micro. On a trouvé un circuit sur internet comme ci-dessous, on s'intéresse seulement à la partie "micro et AOP". Figure 1.png

  • Simplification du montage.

Figure2.png

  • Analyser et tester pour définir les valeurs des résistances et des condensateurs
    • Le micro est comme un condensateur, quand il n'y a pas de ton, la tension du point entre R1 et le Micro est à peu près +5v, on l'a bien vérifié par des expériences avec oscilloscope, etc.
    • C1: C1 est une capacité de découplage, il permet de mettre la source à la masse en régime dynamique. Alors il faut une capacité de nF, et on a choisi la valeur 47nF pour elle.
    • R1: C'est un résistance de protection, il faut une grande valeur, alors on a choisi un résistance de 10ko.
    • C2: C'est une capacité de liaison, alors il faut une capacité de grosse valeur sans fuite, on a choisi un condensateur de 1nF.
    • R3 et R4: D'abord, il faut des grandes valeurs pour R3 et R4. Et puis le ration entre eux correspondent les tensions V(A) et V(B):

(V(A) - V(-)) / R3 = (V(-) - V(B)) / R4, V(-) = 0, alors R4/R3 = - V(B)/V(A)(On le calcule avec delta entre la valeur maximame et la valeur minimume pour définir la gamme de tension du point B = 5v).

      • La puissance du signal change avec la force de parler, c-à-d, quand on parle plus fort, le signal est plus grand, comme la figure ci-dessous, delta de point A va être plus grand. Par exemple, si on souffle dans le micro, le signal au point A est déjà très grand, delta du point A arrive à 5v , et quand on parle normalement, le signal est très faible, delta est seulement mv.
      • Puisque on utilise le micro dans le cas qu'on parle normalement, alors, on définie la valeur des tenstions et des résistances dans le cas qu'on parle normalement. comme le figure ci-dessous, on a mesuré les valeurs des tenstions du point A et du point B avec l'oscilloscope, donc, on peut obtenir le ratio entre R4 et R3 est R4/R3 # 27. Alors, on a mis R4 = 30ko et R3 = 1ko au début, mais quand on teste, on a trouvé que la tension au point B n'arrive pas à 5v, alor, on a mis 40ko pour R4 et ça marche très bien. Avec la normalisation, on met R4=39ko.

Ampli.png

  • Changement du tension de (-2,5v ) - (+2,5v) à 0-5v avec deux résistances et limitation de tension à 5v avec diode zener
    • Maintenant, le signal du point B est (-2,5v~+2,5v), et on envoie le signal au arduino, mais l'arduino ne connais que (0~+5v), alors , il faut changer de (-2,5v~+2,5v) à (0~+5v). Il y a deux solutions pour le résoudre: additionneur ou les résistances. On a choisi la deuxième solution comme la figure ci-dessous, on met R1' = 10ko et R2 = 10ko pour que la tension de V(+) = 2,5v, donc V(-) = 2,5v, on sait que (V(A) - V(-)) / R3 = (V(-) - V(B)) / R4 ~~R4 / R3 = (V(-) - V(B)) /(V(A) - V(-)), R4/R3 ne change pas, alors, delta ne change pas, juste on augemente 2,5v la valeur de V(B) . la tension du point B est 0 ~ 5v quand on parle normalement.

CircuitFinal.png

    • L'alimentation pour l'AOP (V++, V--) est au minimum +12v ~ -12v, alors, si on parle très fort, la tension va dépasser 5v, ça va abîmer l'arduino, alors on utilise la diode zener pour limiter la tension à 0~5v. Avec la normalisation, on a choisi la diode zener -5,1v, la caractéristique de la diode zener est comme la figure ci-dessous, donc la tension du point C est limité à +5,1v.

Diode zener.pngDiodeZener2.jpgDiode zener3.png

Afficher du volume sur l'écran

  • On lie la sortie du montage micro+AOP( point C ) à A0 du arduino. Le fonctionnement du micro est comme le potentiommètre, avec le CAN, on change les signaux analogiques 0~5v aux signaux numériques 0~1024. Quand on parle pas, il y a déjà de tension au point C, et avec du bruit, les signaux numérique( on les a vu sur le monitor du arduino) sont à peu près 500, alors, pour simuler la force du son, on calcule les valeurs des signaux numériques avec "volume = abs( sensorValue(A0) - 500)"(Les valeurs éfficaces sont propotionnelles que les valeurs maximums, alors, on change pas la valeur à la valeur éfficace).
  • Les tensions des sigaux du son sont alternatives avec haute fréquance, alors, les valeurs des tensions changent toujours, mais on s'intéresse seulement la valeur efficace(propotionnelle que la valeur maximume), alors, si on parle fort, on peut toujours voir des grands volumes, et si on parle moin fort, le taille du volume diminue.

Volume.png

  • Le code du arduino est comme ci-dessous:
  1. include "LCD_driver.h"

//#include "nokia_tester.h" // Included files

  1. include <string.h>
  2. include <stdlib.h>
  3. include <stdio.h>
  4. include <ctype.h>
  5. include <avr/io.h>
  6. include <avr/interrupt.h>
  7. include <avr/pgmspace.h>
  8. include "WProgram.h"
  9. include "HardwareSerial.h"


void setup() {

 Serial.begin(9600);

ioinit(); //Initialize I/O LCDInit(); //Initialize the LCD

       LCDContrast(44);
       LCDClear(WHITE);    // Clear LCD to a solid color
       

}

void loop() {

 int sensorValue1 = analogRead(A0);
 int sensorValue2;
 
 sensorValue2=abs(sensorValue1-500);
  Serial.println(sensorValue2,DEC);
// if(sensorValue == 1)com  
if(sensorValue2 >=0 && sensorValue2 <= 50) {
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=50 && sensorValue2 <= 100){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=100 && sensorValue2 <= 150){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=150 && sensorValue2 <= 200){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle

}

else if(sensorValue2 >=200 && sensorValue2 <= 250){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
}
else if(sensorValue2 >=250 && sensorValue2 <= 300) {
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=300 && sensorValue2 <= 350){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
   LCDSetRect(55, 46, 59, 84, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=350 && sensorValue2 <= 400){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
   LCDSetRect(55, 46, 59, 84, 1, BLACK); // filled rectangle
   LCDSetRect(50, 44, 54, 86, 1, BLACK); // filled rectangle
 }
else if(sensorValue2 >=400 && sensorValue2 <= 450){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
   LCDSetRect(55, 46, 59, 84, 1, BLACK); // filled rectangle
   LCDSetRect(50, 44, 54, 86, 1, BLACK); // filled rectangle
   LCDSetRect(45, 42, 49, 88, 1, BLACK); // filled rectangle

}

else if(sensorValue2 >=450 && sensorValue2 <= 500){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
   LCDSetRect(55, 46, 59, 84, 1, BLACK); // filled rectangle
   LCDSetRect(50, 44, 54, 86, 1, BLACK); // filled rectangle
   LCDSetRect(45, 42, 49, 88, 1, BLACK); // filled rectangle
   LCDSetRect(40, 40, 44, 90, 1, BLACK); // filled rectangle
}
 else if(sensorValue2 >=500 && sensorValue2 <= 550){
   LCDClear(WHITE);    // Clear LCD to WHITE
   LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle
   LCDSetRect(80, 56, 84, 74, 1, BLACK); // filled rectangle
   LCDSetRect(75, 54, 79, 76, 1, BLACK); // filled rectangle
   LCDSetRect(70, 52, 74, 78, 1, BLACK); // filled rectangle
   LCDSetRect(65, 50, 69, 80, 1, BLACK); // filled rectangle
   LCDSetRect(60, 48, 64, 82, 1, BLACK); // filled rectangle
   LCDSetRect(55, 46, 59, 84, 1, BLACK); // filled rectangle
   LCDSetRect(50, 44, 54, 86, 1, BLACK); // filled rectangle
   LCDSetRect(45, 42, 49, 88, 1, BLACK); // filled rectangle
   LCDSetRect(40, 40, 44, 90, 1, BLACK); // filled rectangle
   LCDSetRect(35, 38, 39, 92, 1, BLACK); // filled rectangle
}
 delay(5);

}

Difficultées rencontrées

Téléchargement du programme vers Arduino (résolu)

Dans l'interface de programmation Arduino, on peut compiler des programmes sans problème, cependant, il est souvent impossible de télécharger(upload) le programme vers la carte Arduino. On reçoit les messages d'erreurs commes "programmer is not responding". Mais quelquefois, le programme est téléchargé sans problème avec la même configuration de l'ordinateur, de l'IDE, etc...C'est très gênant en nous faisant perdre du temps. Enfin, on a trouvé une solution : après chaque compilation du programme et avant de le télécharger vers la carte Arduino, il faut appuyer sur le bouton "reset" d'Arduino, on doit également vérifier le connexion entre des modules complémentaires et l'Arduino. (Remarque : pendant toute la manipulation de cette partie, pas besoin de passer au compte Administrateur).

Affichage au niveau de "Serial Monitor" (résolu)

Lorsque l'on réussit à compiler puis à charger le programme pour la carte Arduino et on souhaite configurer le module Wifi dans le "Serial Monitor", il n'y a toujours aucun affichage. Solution trouvée : après l'ouverture du "Serial Monitor", il faut appuyer sur le bouton "reset" d'Arduino pendant environ une seconde, et après l'affichage sera apparue. On est donc arrivé à commencer à configurer le module Wifi.

  • Le 21 mars : c'est un jour remarquable où on a débloqué tous les deux grands problèmes rencontrés jusque-là, ceci est un grand progrès et nous permettra surtout d'accélérer l'avancement de notre projet !

Incompatibilité entre le module TFT et Wifly (résolu)

On a dépensé beaucoup de temps pour la communication entre le module TFT et Wifly, cependant, après avoir effectué de noubreaux essais (Par exemple: changement de la bibliothèque du module TFT et celle de Wifly), on trouve qu'il est impossible de réaliser cela avec un seul Arduino, parce que la bibliothèque fournie n'étant pas préalablement conçue pour ce genre de réalisation, ainsi, la vitesse de communication entre le module Wifly et l'Arduino et celle entre le module TFT et l'Arduino sont différentes. Pour ne pas être coincé ici comme la catastrophe, on a choisi un autre module qui remplace le module Wifly : c'est le module XBee avec son "Shield" adapté. Finalement, on a réussi à atteindre le but du projet grâce à ce remplacement.


Liens externes