====== Un volte mètre en Arduino ====== ===== Intro ===== Vous ne le connaissez pas encore (sur ce wiki), mais la maison de jeunes Port'Ouverte à réalisé un vélo générateur d'électricité.\\ Au départ, il n'était pas de plus efficace, le chargement était lent et il fallait beaucoup pédaler pour recharger les batteries. Plusieurs solutions ont été trouvées, mais certaines n'ont pas fonctionné.\\ On s'est beaucoup cassé la tête, et la solution trouvée est d'une simplicité affligeante :D.\\ Bon je vous le dis tout de suite, ce n'est pas ici que vous trouverez la solution en question Mosfet ;). Hé! pas de solution j'ai dis :D Plus sérieusement, il s'agit ici de mesurer le courant généré par la dynamo. Dans le cadre du festival écolanta, il nous a été demandé d'utiliser le vélo. Comme il s'agissait d'une épreuve à devoir passer, j'ai proposé de fabriquer un petit module Arduino pour afficher le courant générer par l'utilisateur. Voici donc, étape par étape, le moyen de mesurer un voltage avec Arduino. Par la suite, nous ajouterons un vue mettre en LED, ou un afficheur OLED par la suite. ===== Le schéma ===== {{:ateliers:robotique:volte-metre-scemat.png?direct&600 |}} ==== Matériels ==== 1 Arduino (ou Nano Pro, plus petit)\\ 1 résistance 1KΩ (brun, noir, rouge, or)\\ 1 résistance 10KΩ (brun, noir, orange, or)\\ 1 BroadBord 1 source d'alimentation à tester. Vous voilà maintenant équipé pour commencer !\\ Regardons un peu le schéma, histoire d'y voir plus claire. Côté Arduino, nous avons une entrée (en A1) qui récupérera les données, mais attention il y a aussi une entrée GND (négative) qui est absolument vital !\\ Au début je ne l'avais pas mis et c'était pas terrible :s. Les voltes montaient, mais stagnais à 57 V, avec une pile 1.5 V, imaginez ma tête :D \\ Pour le reste, rien de bien complexe, le courant positif passe par la résistance 10KΩ jusqu'au câble de donnée puis par la résistance 1KΩ.\\ Sur la même colonne nous trouverons aussi le fameux pont jusqu'à l'entrée GND de l'Arduino. Si étrange que cela puisse paraître, c'est tout ! Oui oui, c'est aussi simple que cela ! Pour être sur de ne pas avoir fait d'erreur (et je n'en doute pas), voici le schéma de montage. ===== Le montage ===== {{ :ateliers:robotique:volte-metre-montage.png?direct&800 |}} ===== Le code ===== Une fois le montage effectué, il ne nous reste plus qu'à écrire notre Script.\\ Je ne vais pas entrer dans tous les détailles de ce code car certaines notions sont plus complexe, mais globalement, là aussi, c'est assez simple ! int tensionInput = A1; // source électrique à mesurer float Vout = 0.00; // On crée la variable Volt Output float Vin = 0.00; // On crée la variable Volt Output float R1 = 100000.00; // On crée la variable pour la résistance de 10KΩ float R2 = 10000.00; // On crée la variable pour la résistance de 1KΩ int val = 0; // On crée la variable pour stocker la valeur de A1 void setup(){ pinMode(tensionInput, INPUT); // On indique le sens de communication de A1 Serial.begin(9600); // On ouvre le canal de communication Serial.println("START"); // On indique "START" dans la console en cas de Bug } void loop(){ val = analogRead(tensionInput); // On lies la valeur A1 et on la stocke dans la variable "val" Vout = (val * 5.00) / 1024.00; // On récupère "val" multiplié par le tension de l'Arduino (5V) // et divisée par la fréquence (en Bits) de l'Arduino (1024) // Puis on la stocke dans la variable "Vout" Vin = Vout / (R2/(R1+R2)); // On récupère "Vout" que l'on divise par le résultat de l'équation (R2/(R1+R2)), // je ne vais pas m'étendre sur ce sujet ici ;) if (Vin<0.09){ // On crée une condition SI le courant est inférieur à 0.09V Serial.print("Pas de courant : "); // Si pas de courant, nous l'indiquons Vin=0.00; // SI la condition est TRUE, on donne à la variable "Vin", la valeur 0 } Serial.print(Vin); // On affiche le résultat "Vin" dans le moniteur Série Serial.println(" Volt"); // On précise qu'il s'agit de Volts delay(500); // On laisse un délais de 0.5 seconde entre chaque boucle } ==== Explications ==== Pour les plus curieux d'entre vous, voici quelques explications concernant les deux formules "Vin" et "Vout".\\ En premier lieu, nous avons : Vout = (val * 5.00) / 1024.00; Mais ca fait quoi çà ?\\ "Val" est la valeur lue par l'Arduino en tant qu'entrée analogique, jusque là, facile\\ Ensuite, la valeur est multipliée par la tension fournie par l'Arduino et donc, pour obtenir Vout, elle est divisée par le cycle de temps qui est couvert après chaque bit, pour obtenir la valeur à stocker dans la variable "Vout"\\ Bon, là c'est un peu plus complexe.\\ En gros, nous avons une tension nominal à mesurer, disons de 10V. L'arduino luit fait 5V à une cadence de 1024 Hz et il faut en tenir compte ! Nous avons donc : (10*5)/1024 Comme vous le savez, nous commençons **TOUJOURS** une équations par les **parenthèses** ensuite par les **multiplications** et **divisions**, pour finir avec les **sommes** et les **soustractions**. Le résultat est donc : X = (10*5)/1024 X = 50/1024 X = 0,048828125 Nous voilà avec la valeur 0,048828125 stockée dans la variable "Vout"\\ Cà, c'est fait ;) Passons ensuite à : Vin = Vout/(R2/(R1+R2)); Décortiquons l'équation : Y = 0,048828125/(10000/(100000+10000)) Y = 0,048828125/0,090909091 Y = 0,09765625 ===== Aller plus loin avec un écran OLED ==== Pour aller plus loin et facilité l'affichage des voltes mesurés, nous pouvons ajouter un écran OLED\\ Pour cela, il nous faudra la Librairie SSD1306 que vous trouverez sur le dépôt GitHub ICI #include "SSD1306Ascii.h" #include "SSD1306AsciiAvrI2c.h" // 0X3C+SA0 - 0x3C or 0x3D #define I2C_ADDRESS 0x3C #define RST_PIN -1 SSD1306AsciiAvrI2c oled; int analogInput = A0; float Vout = 0.00; float Vin = 0.00; float R1 = 100000.00; // R1 (100K) float R2 = 10000.00; // R2 (10K) int val = 0; void setup() { pinMode(analogInput, INPUT); Serial.begin(9600); Serial.println(" START "); #if RST_PIN >= 0 oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); #else oled.begin(&Adafruit128x64, I2C_ADDRESS); #endif oled.setFont(Adafruit5x7); uint32_t m = micros(); oled.clear(); oled.set2X(); oled.println(); oled.println(" Volts : "); oled.println(); } void loop() { val = analogRead(analogInput); Vout = (val * 5.00) / 1024.00; Vin = Vout / (R2 / (R1 + R2)); if (Vin < 0.09) { Vin = 0.00; } Serial.print(" \t Voltage : "); Serial.println( Vin ); oled.set2X(); oled.print(" > "); oled.println( Vin ); delay(300); } Diable ! Mais qu'est cette ligne ? #if RST_PIN >= 0 Et bien c'est assez simple, n'oubliez pas qu'en Arduino, nous codons en C++, de plus vous remarquerez que cette condition tient sur une seule ligne !\\ Il s'agit en fait d'un raccourcis !\\ plutôt que d'écrire : if( RST_PIN >= 0 ){ oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); } Il est possible de condenser cette syntaxe en : #if RST_PIN >= 0 oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); Personnellement, je préfère la version longue !\\ Non seulement je la trouve plus claire, mais il ne faut pas jongler entre "je mets un point virgule, je ne mets pas de point virgule, patati patata.\\ On met des points virgules POINT ;)\\ Mais ce commentaire est purement subjectif, à vous de faire votre propre popote et à acquérir vos propres habitudes ! C'est aussi çà le code, la liberté !