Carte Extension Arduino
Sommaire
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) -- qui remplacent le module Wifly...
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
- Ensuite, une fenêtre s'apparaît qui nous informe que le test de la connexion a été réussi :
- Dans l'onglet « Modem configuration », on clique sur le bouton « Read » afin de récupérer les paramètres de configurations du module Xbee :
- 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 :
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 :
- 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 le module 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... Voici le schéma de principe ci-dessous :
- 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
- On peut termenier la saisie d'une chaîne de caractères en entrant un caractère '@', lorsque l'Arduino reçoit ce caractère, il appelle la fonction de l'écran pour afficher les caractères précédemment sauvegardés dans le tampon, c'est donc une chaîne de caractères
- Il faut vider le tampon avoir affiché les caracrtères sauvegardés dans ce tampon
- Dans le programme, on a utilisé deux tampon permettant d'afficher une longue chaîne de caractères en deux lignes
- L'Arduino envoie un accusé de réception à l'ordinateur pour chaque chaîne de caractères reçue et affichée sur écran TFT, on pourra retrouver cet accusé de réception (en rouge) dans le Terminal du logiciel X-CTU
- Sur le module TFT, il se trouve 3 boutons que l'on peut définir soi-même leurs utilisations dans le programme
- Voici le code source pour la 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" et l'affichage des chaînes de caractères transmises via Zigbee sur écran TFT
//************************************************************************
- include "LCD_driver.h"
- include <string.h>
- include <stdlib.h>
- include <stdio.h>
- include <ctype.h>
- include <avr/io.h>
- include <avr/interrupt.h>
- include <avr/pgmspace.h>
- include "WProgram.h"
- include "HardwareSerial.h"
//************************************************************************
int val; char tamponA[15],tamponB[15]; int i = 0, j = 0, k;
void setup() {
Serial.begin(9600); initEcran();
}
void initEcran(){
ioinit(); //Initialize I/O LCDInit(); //Initialize the LCD LCDContrast(44); LCDClear(WHITE); // Clear LCD to a solid color LCDPutStr("Bienvenue!", 0, 4, ORANGE, WHITE); // Write instructions on display LCDPutStr("01/05/2011", 16, 32, GREEN, WHITE); LCDPutStr("La realisation", 32, 4, BLACK, WHITE); LCDPutStr("du projet", 48, 4, BLACK, WHITE); LCDPutStr("Par: Yuchang LV", 64, 4, BLACK, WHITE); LCDPutStr("IMA4 - SC", 80, 4, BLACK, WHITE); LCDPutStr("Amusez-vous :)", 96, 4, BLACK, WHITE);
}
void XBee(){
val = Serial.read(); //Lire le port serie ... le module XBee if (-1 != val) //On a recu quelque chose... { if('@' != val){ if(i<15) { tamponA[i] = val; i++; } else { tamponB[j] = val; j++; } } else{ LCDClear(WHITE); LCDPutStr("PROJET - IMA4SC", 4, 4, PINK, WHITE); LCDPutStr("Demonstration", 20, 16, GREEN, WHITE); LCDPutStr("Message recu", 110, 10, BLUE, WHITE); LCDPutStr(tamponA, 56, 4, BLACK, WHITE); LCDPutStr(tamponB, 72, 4, BLACK, WHITE); ligneColeur(); Serial.print(" --- Le message recu:"); Serial.print(tamponA); Serial.println(tamponB); delay(1000); for(k=0;k<15;k++) { tamponA[k] = '\0'; tamponB[k] = '\0'; } i=0; j=0; } }
}
void ligneColeur(){
LCDSetLine(43, 5, 43, 130, GREEN); LCDSetLine(44, 5, 44, 130, GREEN); LCDSetLine(45, 5, 45, 130, BLUE); LCDSetLine(46, 5, 46, 130, BLUE); LCDSetLine(47, 5, 47, 130, RED); LCDSetLine(48, 5, 48, 130, RED); LCDSetLine(97, 5, 97, 130, RED); LCDSetLine(98, 5, 98, 130, RED); LCDSetLine(99, 5, 99, 130, BLUE); LCDSetLine(100, 5, 100, 130, BLUE); LCDSetLine(101, 5, 101, 130, GREEN); LCDSetLine(102, 5, 102, 130, GREEN);
}
void boutonControl() {
int s1,s2,s3; s1 = !digitalRead(kSwitch1_PIN); s2 = !digitalRead(kSwitch2_PIN); s3 = !digitalRead(kSwitch3_PIN); if(s1) { LCDClear(WHITE); LCDPutStr("Bouton 1", 16, 32, GREEN, WHITE); LCDPutStr("Appuye!", 32, 32, GREEN, WHITE); } else if(s2) { LCDClear(WHITE); LCDPutStr("Bouton 2", 16, 32, GREEN, WHITE); LCDPutStr("Appuye!", 32, 32, GREEN, WHITE); } else if(s3) { LCDClear(WHITE); LCDPutStr("Bouton 3", 16, 32, GREEN, WHITE); LCDPutStr("Appuye!", 32, 32, GREEN, WHITE); }
}
void loop() {
boutonControl(); XBee();
}
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".
- Simplification du montage.
- Analyser et tester pour définir les valeurs des résistances et des condensateurs
- On peut considérer le micro en tant que condensateur, quand il n'y a pas de son, la tension du point entre R1 et le Micro est à peu près +5v, on l'a bien vérifié d'après des expériences en utilisant l'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 avoir une capacité de quelque 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 qui doit avoir une grande valeur de quelque ????????????F, on a choisi un condensateur de 1nF sans fuite.
- R3 et R4: D'abord, il faut des grandes valeurs pour R3 et R4. Et puis le rapport entre eux correspondent les tensions V(A) et V(B):
(V(A) - V(-)) / R3 = (V(-) - V(B)) / R4; V(-) = 0; d'où R4/R3 = - V(B)/V(A) ( On adjuste le rapport entre R3 et R4 en regardant la tension de sortie au point B pour que cette dernière puisse atteindre 5V).
- La puissance du signal change avec le volume de son détecté, 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 quelques mv.
- Sachant que l'on utilise le micro dans le cas où l'on parle normalement, alors, on définit la valeur des tenstions et des résistances dans le cas où l'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 rapport 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.
- 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 connaît 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.
- 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.
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.
- Le code du arduino est comme ci-dessous:
- include "LCD_driver.h"
- include <string.h>
- include <stdlib.h>
- include <stdio.h>
- include <ctype.h>
- include <avr/io.h>
- include <avr/interrupt.h>
- include <avr/pgmspace.h>
- include "WProgram.h"
- 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(sensorValue2 >=0 && sensorValue2 <= 50) { LCDClear(WHITE); // Clear LCD to WHITE LCDSetRect(85, 58, 89, 72, 1, BLACK); // filled rectangle } if(sensorValue2 >= 50) LCDSetRect(80, 56, 84, 74, 1, BLACK); if(sensorValue2 >= 100) LCDSetRect(75, 54, 79, 76, 1, BLACK); if(sensorValue2 >= 150) LCDSetRect(70, 52, 74, 78, 1, BLACK); if(sensorValue2 >= 200) LCDSetRect(65, 50, 69, 80, 1, BLACK); if(sensorValue2 >= 250) LCDSetRect(60, 48, 64, 82, 1, BLACK); if(sensorValue2 >= 300) LCDSetRect(55, 46, 59, 84, 1, BLACK); if(sensorValue2 >= 350) LCDSetRect(50, 44, 54, 86, 1, BLACK); if(sensorValue2 >= 400) LCDSetRect(45, 42, 49, 88, 1, BLACK); if(sensorValue2 >= 450) LCDSetRect(40, 40, 44, 90, 1, BLACK); if(sensorValue2 >= 500) LCDSetRect(35, 38, 39, 92, 1, BLACK);
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 le module Wifly (résolu)
On a dépensé beaucoup de temps pour la communication entre le module TFT et le module 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.
- Remarque : On ne peut pas considérer ce remplacement (Wifi --> Zigbee) comme une triche, parce que le module XBee est également une carte d'extension comme le module Wifly, ainsi, le sujet du projet autorise l'utilisation du module XBee
- Extrait du sujet : "Il pourrait s'agir, par exemple d'intégrer un affichage (écran OLED) et une connectivité sans fil de type ZIGBEE ou WIFI. "
Liens externes
- (fr) Sujet sur TWiki
- (en) Site Officiel Arduino