Carte Extension Arduino

De Wiki d'activités IMA
Révision datée du 15 avril 2011 à 11:33 par Jchen1 (discussion | contributions) (Afficher du volume sur l'écran)

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 WIFI
  • Affichage sur écran TFT

Description détaillée (Faisaibilité à vérifier)

  • Traitement du signal analogique émis par le microphone
  • Affichage d'infomations concernant le volume sur écran TFT
  • Réalisation de la transmission de caractères et/ou d'images entre un ordinateur équipé d'une carte Wifi et un Arduino
  • Affichage pour des caractères et des images transmis via Wifi 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)
  • autres matériels à définir et à commander.

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)

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

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 !

Liens externes