Eclairage à led de vélo 3W+tracker (atmega, ESP32)

J'en ai déjà testé qui s'arrêtaient à 3V pile (9.05V pour un 3S).

La carte que j'ai testé :

Over discharge protection : 2.5V typiques.

Il y a certainement une erreur de la part du vendeur.

En mode veuille avec 5micro ampère, l’autonomie théorique avec 100% de charge est de 33 333Jours avec 2 éléments 18650. Temps=2A.H*2/(5*10^-6*24h)=33 333Jour Si l’éclairage se met en mode veuille lorsque 20% restante d’énergie, Le temps de décharge pour atteindre les 100% de la batterie sera de 6666 jours.

Mais une autre solution que le bouton poussoir avec le mode veuille est possible : C’est un interrupteur sur l’alimentation. Cet interrupteur devra changer de mode de puissance de la led à chaque coupure de l’alimentation En utilisant EEPROM avec l’incrément des modes sur une adresse

Evidemment, si la personne oublie d’éteindre l’éclairage, il faudra que l’Arduino se mettent en mode veuille à 20% de la capacité énergétique.

Algorithme du setup avec l’interrupteur ; Lire le mode sur eeprom Incrémenter le mode Si eeprom est superieure à 3 alors valeur 0. Ecrire le mode eeprom

Mais L’utilisation de EEPROM diminue la durée de fonctionnent de l’éclairage. En effet, le nombre d’écriture avoisine 100 000 fois par adresse et dure 3.3ms. Donc avec 2 utilisations d’éclairage par jour et une extinction éteint 3 fois l’alimentation à chaque fois pour revenir Durée de vie =100 000/2J*3=16666J=>45 ans

Evidemment, il serait possible aussi d’utiliser une iteration de la mémoire EEPROM pour écrire dans une adresse différente mais vu les 45 ans, ce n’est pas très utile. https://www.arduino.cc/en/Tutorial/EEPROMIteration

Il n’y a pas qu’une solution, mais plusieurs….

En fonction du besoin, la programmation Arduino permet d’ajuster la puissance led et de la capacité énergétique. On pourrait faire aussi un programme avec un seul mode pleine puissance en mode flash et il n’y plus besoin EEPROM. Exemple :

Avec une seule batterie lithium de 1A.h mais d’utilisation que de 0.8Ah à cause des 20%, l’autonomie en 3Watt mode flash avec rapport cyclique de 0.5, l’autonomie chute à 1heure. mais cette batterie permet de minimiser la masse et l'encombrement |500x168 Mais pourquoi pas faire un rapport cyclique de 0.1 sur 1s. L’autonomie théorique en mode veuille avec cette batterie est toujours correcte Temps=0.2A.H/(5*10^-6*24h)=1666Jour

Il y a de nombreux à choix à faire sur ce sujet

33 333Jour : n'y compte pas trop, car l'auto-décharge de la batterie n'est pas négligeable. J'ai flingué une LIPO comme ça : oubliée dans un tiroir pendant 1 an.

Evidemment, c’est une valeur théorique de l’autonomie qui permet de donner un ordre de grandeur.
Elle ne prend pas en compte, l’autodécharge de la batterie par exemple.

Pour débuguer le programme, on aime utiliser ISIS, ce qui permet de tester le programme sans détruire hacheur et led, batterie….
Mais dans ISIS, l’EEPROM ne fonctionne pas si l’on coupe l’alimentation Vcc.
Par contre, cela fonctionne à chaque fois que l’on redémarre la simulation ou que l’on active le reset.
Voici la copie d’écran de la simulation ou le programme demande 0.5A, puis demande 1A, avec une initailisation de la valeur integral de 148 et ki=4

Donc, le courant est directement à 0.5A avec cette valeur de PWM à 148, mais il faut attendre 2.5s pour avoir un PWM de 169 pour atteindre la valeur de 1A comme on peut l’observer sur la figure suivante :

Evidemment, dans le programme final, il vaut mieux augmenter la valeur de cette initialisation dans le cas le plus défavorable de la tension batterie 3.2V.
Donc, il y aura un léger dépassement du courant lorsque l’alimentation sera de 4.2V à cause de l’initialisation du coefficient intégral.

On pourra observer la variation du courant qui est de 10% autour de la valeur moyenne correspondant aux choix de notre inductance mais cela ne gene pas la regulation. donc, pas besoin de filtrer le courant de façon analogique ou numerique

Voici le nouveau programme utilisant EEPROM en PJ

Pour visualiser les dynamiques de la régulation en réel, il faut mesurer en fonction du temps, la tension image du courant de la résistance shunt avec la valeur moyenne de la PWM.
Pour mesure la valeur de la PWM à l’oscilloscope, il faudrait utiliser un filtre passe bas de fréquence de coupure bien inférieur à la période de hachage et supérieur à 10Hz correspondant à l’inverse de la période d’échantillonnage.
Un filtre sallen key du deuxième ordre de fréquence de coupure de 100hz est un bon compromis ou un RC du premier ordre.

Une autre solution et d’utiliser la liaison série et le terminal et faire un copier-coller du terminal pour faire un fichier CSV dans Excel….D’ailleurs c’est pour cela que l’on a jamais utilisé le Tx sur ce post
pour cela, il faut inclure la bibliothèque #include <SoftwareSerial.h>
Initialisation à Serial.begin(9600);
Ces enregistrements prouvent le bon fonctionnement des régulations en simulation et en réel.

led_velo_sans_5V_eeprom.ino (6.44 KB)

Notre système n’a pas besoin d’une grande précision de la mesure de température de la led (plus ou moins quelques °C suffit) Une PTC (positive température coefficient) (kty81) est 2 fois moins cher qu’une PT 1000 (environ 0.4 euros) |500x184 Mais, est qu’il y a plus de sensibilité dans une PTC que dans une PT 1000 ?

Remarque, Dans Isis, c’est la kty 81/110 1000ohms à 25°C qui est simulable http://www.farnell.com/datasheets/1503771.pdf?_ga=2.252704713.1576310020.1552658034-1358927439.1552558264

Le modèle mathématique d’une PTC est bien présenté sur ce lien http://mathscinotes.com/2011/07/thermistor-mathematics/ Car ce n’est pas terrible dans wiki https://en.wikipedia.org/wiki/Thermistor Voici le modelé mathématique exponentiel et la linéarisation de la tension image de la température entre 0°C et 140°C Dans les datasheet, si la résistance R25 est donné, le coefficient B (kelving) est parfois pas donné, mais c’est facile de le retrouver |500x463 |500x455 Le boitier des kty 81 est souvent, un TO92 et pas TO220; donc il y a une erreur de la mesure en fonction du contact et un retard de la mesure à cause de la constante de temps thermique. Le boitier TO220 permet de fixer correctement le capteur mais prend de la place D’ailleurs, la kty 81 dans ISIS est paramétré avec une constante de temps de 10s, une résistance thermique de 2000°C/W et une résistance de contact de 0.5°C/W. Mais un boitier TO 92, a une constante de temps de 30s avec une résistance thermique de 140°C/W et une résistance de contact de 30°C/W. Le temps de réponse du capteur est bien inférieur à celui du dissipateur de la LED grâce au dissipateur. Exemple : si la température mesurée est de 53°C avec une température ambiante de 20°C, alors la température du radiateur sera de 60°C. Il y a une différence de 7°C Si la température mesurée est de 80°C, la température réelle est de 91°C. La différence est de 11°C On peut observer cette différence sur la simulation suivante et en réel avec une caméra infrarouge |500x269 Donc, il faut corriger cette différence, avec l’équation précédente, mais la mesure de la température ambiante n’étant pas mesuré, elle sera estimée à 25°C ce qui donnera une erreur par défaut sur la température ambiante est plus grande. On peut observer sur la simulation que la valeur de la température du capteur et identique à celle donné par l’Arduino avec la correction précédente |500x169

Si les PTC sont très courantes pour mesurer la température, les NTC sont très utilisées aussi.

Perspectives futur; Avec le programme, le bargraphe n’indique pas s’il y a un état de charge. Or, ce serait bien qu’il clignote lors de la charge pour indiquer à l’utilisateur que le micro usb est bien connecté.

La régulation de courant de l’Arduino Nano est avec un hachage à 32 kHz. Contrainte : La taille de l’inductance du hacheur est relativement importante. Pour 320 kHz elle serait divisée par 10. Perspective : Le hacheur de la carte électronique peut-être remplacer par un composant électronique FL7760. Ce composant est destiné aux applications d’éclairage à Led et comporte des hacheurs.

http://www.farnell.com/datasheets/2363644.pdf

Suivant la documentation du constructeur, nous avons réaliser une carte électronique de régulation de courant. Sur la doc on peut trouver les performances de la fréquence de hachage (1MHz) et la consommation du circuit intégrer (300 microA). L’hystérésis est de plus ou moins 30mV, le reste n’est pas trop indiquée. Donc pour un courant Led de 0,4 A

|500x37

On néglige dans un premier temps la puissance du transistor et de la diode., qui sont surdimensionnés par rapport au courant Led pour ne pas mettre de dissipateur.

Voici le schéma ISIS avec le choix des composants |500x410

|500x202

Voici nos mesures expérimentales visant à caractériser les performances du régulateur 7760 : D’une part pour une tension d’alimentation de 10 V puis 16 V. Puis en variant la résistance de mesure de 1 Ω à 0,5 Ω. Car elle n’est pas précisée dans la documentions constructeur... - Détermination du rapport cyclique - Détermination de la fréquence de fonctionnement - Vérification de l’ondulation de courant - Mesure du courant d’entrée et détermination de la puissance absorbé - Détermination des caractéristiques de la Led (tension, courant et puissance utile) - Calcul du rendement - Éclairement Tableau récapitulatif des mesures : |500x61 Pour l’éclairement : 860 Lux à 10 cm pour une puissance de 0,42 W.

La régulation de courant dans la Led fonctionne bien Les pertes deviennent négligeables pour un courant supérieur à 0.4A avec une résistance Rsense de 0,5ohms, donc un rendement de 70% à la place de 90% théorique. On a effectué une mesure à vide de la consommation du 7760 et on trouve 400 μA au lieu de 300microA Mais ça ne change pas tant que ça la valeur théorique du rendement. On pense que cette différence de 100 μA est dû à la commande du transistor…c’est une hypothèse.

Avec une inductance de 100 μH, on a une fréquence entre 300 kHz et 200 kHz correspondant à l’équation théorique suivante avec 60mV Donc, en théorie, si on divise notre inductance par deux on multiplie d’autant notre fréquence. On a effectué une vérification pratique avec une valeur d’inductance de 50 μH. On obtient une valeur de 400 kHz. Mais une valeur de 33 μH, On obtient une toujours une fréquence de 400 kHz qui est certainement dû aux ondulations parasite du typon que l’on peut observer sur les figures suivantes.

Ondulation pour 200 kHz

Ondulation pour 400 kHz

Mais comment faire varier la puissance de la led avec l’arduino

A partir de la doc constructeur et sur notre schéma, il y a une broche DIMMING du FL7760. Cette broche sert à faire varier le courant de la LED. Il faut pour cela appliqué un signal PWM et faire varier le rapport cyclique normalement supérieure à 2KHz. On a appliqué un signal PWM de 32 kHz et d’amplitude 5 V, en faisant varié le rapport cyclique on observe une variation de la tension Vsense image du courant de notre LED. On a effectué une série de mesures sur la broche DIM ainsi que sur la résistance Rsense : |500x38 Donc le courant led correspond à l’équation suivante :

Conclusions : Avec le choix de nos composant, le courant led peut atteindre 3A avec une fréquence de 400khz en minimisant l’inductance à 30μH avec un rendement qui va être aux alentours de 90%. Mais qu’il faudra vérifier.

Test de la durée d’exécution du programme utilisant EEPROM

On souhaite connaître la durée d’exécution de notre programme, cependant arduino ne réalise pas de fichier .cof que l’on peut simuler sur ISIS pour visualiser la durée du programme. Donc on décide tout simplement, d’allumer une LED au lancement de la boucle des 100ms puis de l’éteindre à la fin de son exécution ; ensuite on visualise ce changement d’état à l’oscilloscope et on effectue notre mesure en simulation et en réalité.

|500x350

Comme on peut le voir, le programme s’exécute en 15ms avec l’afficheur LCD et un temps d’échantillonnage de 100ms (boucle d’affichage et de régulation si temps= 100ms (if temps>100).

Mais pour faire cet éclairage, il n’est pas utile d’utiliser un afficheur LCD (qui est utilisé pour faire du debuggage), donc le programme s’exécute en 3,3ms sans l’afficheur LCD avec un temps d’échantillonnage de 100ms.

|500x355

On en conclut qu’on peut diminuer la période d’échantillonnage à 5ms tout en sachant que l’œil à une persistance rétinienne de 20 Hertz, donc un rafraichissement des valeurs de l’afficheur LCD toutes les 0,1s.

pour faire un feu stop arriere automatique un accelerometre va être utilisé

Les accéléromètres numériques sont nombreux avec des micro-usiné capacitif intelligent à trois axes et à faible consommation avec des résolutions de 10bits à 14 bits. Des fonctions intégrées sont multiples avec des options flexibles programmables par l’utilisateur (filtrées passe-bas, et passe haut, interruption). Pour ce projet, nous n’avons pas besoin d’une grande résolution pour détecter la décélération du vélo pour activer l’éclairage arrière. S’il y a une décélération en roue libre, on passe de 15km/h (4.1m/s) à l’arrêt en 19s minimum sur du plat. Donc la décélération est de -0.22m/s^2 Lors de freinage intensif, on passe de 16.6m/s à l’arrêt en 2.5s onc décélération de -6.6m/s^2

Donc pour une déclaration de -1m/s^2 mettra l’éclairage arrière en action full pendant 10s Mais une accélération de +1m/s^2 arrêtera l’éclairage et remettra à 0. Car cela voudra dire que l’on a redémarré

Remarque 1 g est égale à 9,81 m/s² D’ailleurs, le programme suivant a choisi la valeur -30=>-0.117g=-1.14m/s^2 pour actionner sa lumière arrière https://www.instructables.com/id/passive-brake-light/ Quels sont les capteurs d’accélération possibles ? Sachant que l’on veut minimiser le cout de fonctionnement. L’accéléromètre analogique tel que ADXL335 est relativement cher (environ 3€) mais c’est possible de faire un filtre analogique. L’accéléromètre numérique tel que ADXL345 est vendu pour environ 1€ |500x154 Le MCU 6050 qui a un gyroscope interne est plus cher que le composant précédent |500x180

Voici, les Performances ADXL345 https://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf

Alimentation: 2,0 Vcc à 3,6 Vcc Consommation: - en mesure: 40 µA à 2,5 Vcc - au repos: 0,1 µA à 2,5 Vcc Interface: I2C ou SPI 16 bits Plage de mesure: ±16 g Sensibilité: 3,9 mg/LSB 2g Résolution: 4 mg/LSB (13 bits) 1bits(signe) 16g/2^12=16/4096=3.9mg Filtre interne de ? FiFo de 32 valeurs Le temps de mesurer l’accélération sur un axe est de ?

Pour notre programme precedent ; L’échantillonnage de la commande de la led a été choisi à 0.1seconde (fréquence 10hz). Pour ne pas avoir de décélération intempestifs, un filtre passe bas de la mesure d’accélération à la fréquence de coupure légèrement inférieur à 10hz serait souhaitable. Donc, un filtre avec une fréquence de coupure de 0.05s ne nuira pas aux dynamiques de détection de l’accélération qui est de quelques secondes. Remarque avec notre programme qui a une routine d’interruption de 1ms, la période d’échantillonnage de l’accélération se fera à cette valeur. Il est facile de faire un filtre passe bas numérique qui atténue les fréquences les plus élevées du signal, offrant ainsi une variation plus douce de la sortie. Ce filtre passe-bas est facilement implémentable en utilisant l'équation suivante avec correspondant à la constante de temps désirée : |500x134 Mais comment vérifier les résultats les dynamiques du filtre numérique ?

On peut vérifier le filtrage en mettant un signal carré de période 0.1s et la sortie du filtre passe bas devra donner une exponentielle croissante et décroissante comme en analogique. Exemple avec une constante de temps de 10ms, donc e^-aTe= e^-(1ms/10ms)= 0.91 Matlab permet de faire cette vérification très facilement |500x305 On peut observer que la constante de temps est bien de 10ms et que le gain statique du filtre est de 1 car l’amplitude en sortie est identique à celle de l’entrée. |500x353

Maintenant, si l’on désire, une constate de temps de 50ms e^-aTe= e^-(1ms/50ms)= 0.98 On peut observer sur la figure suivante que la sortie du filtre à bien correspond à la valeur moyenne du signal carré d’entré qui a un rapport cyclique de 50% donc de 0.5V mais avec une oscillation d’amplitude de 20%. |500x353

Pour tester le filtre, il serait possible de rajouter sur le signal carré precedent du bruit à haute frequence pour bien vérifier que ce dernier serait atténué. Evidemment, il est possible de faire des filtres plus complexes pour avoir encore plus d’atténuation

Il aurait été possible que l’Arduino lise un signal carré extérieur et de faire une sortie analogique des valeurs sur une PWM pour démontrer l’utilisation d’un filtre numérique sur un oscilloscope avec une routine d’interruption de 1ms pour faire les calculs du filtrage qui a été présenté précédemment. Mais, nous avons utilisé juste le terminal pour observer les calculs du filtre et vérifier que le float avec ces 7 chiffres significatif fonctionne bien comme on peut l’observer sur le code suivant qui ont été placé dans Excel pour observer les dynamiques du filtre.

#include 
#include 
#include 
#include    //chien de garde
//#include "LowPower.h"     //https://github.com/rocketscream/Low-Power


LiquidCrystal lcd(9, 8, 4, 5, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables


unsigned    int     temps=0; 
            float  entree=0;
            float  sortie=0;



// Filtre numerique premier ordre
void setup() {
     

  Timer1.initialize(1000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
  lcd.begin(16, 2);                   //modifier pour un afficheur 20x4
  Serial.begin(9600); 

  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 10  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet
                                            

//wdt_enable(WDTO_15MS);
}



// Interruptions  tous les 0.001s fait par le timer1***********************************
void callback()  {
temps++;
sortie=entree*0.008+sortie*0.992;   //filtre passe pas
  Serial.print(temps);
  Serial.print(";");
  Serial.print("\t");
    
  Serial.print(entree);
  Serial.print(";");
  Serial.print("\t");
  
  Serial.print(sortie,2);
  Serial.print("\t");
  Serial.println(";");  //mise à la ligne

//wdt_reset();
}//fin routine



///////////////////////////////////////////// Boucle correspondant à la fonction main 
void loop() {  

if (temps>=50)         //1=singnal carré de 100ms
{
temps=0;  //reset : attention cette boucle doit etre infereir à son temps d'execution
if (entree==16384) {entree=0;}  else {entree=16384;}  
  
}//temps>100

   
} // fin loop

Avec le terme 0.91 du filtre échantillon à 1ms, On peut observer que la constante de temps est environ celle théorique de 10ms, pour une amplitude de 1023 de l’entrée (10bits).

Avec le terme 0.98 du filtre échantillon à 1ms, On peut observer que la constante de temps est légèrement inférieure à la valeur théorique de 50ms, pour une amplitude de 16384 (14bits) de l’entrée. Lorsque la constante de temps devient très grande devant la période du signal, la sortie du filtre donnera une oscillation avec une amplitude correspondant à l’équation suivant autour de la valeur moyenne du signal d’entrée |500x258 Avec le terme 0.992 du filtre échantillon à 1ms, la constante de temps theorique on peut observer que l’amplitude |500x200 Donc, il y a des petites différences entre la théorique et la pratique mais globalement, cela fonctionne correctement.

Remarque : ne jamais depasser la valeur de 1, sinon c'est instable, d'ou l'obligation de declarer en float faut il des bibliotheques filtre pour cela ? ? ? ? ? ? ? ? https://playground.arduino.cc/Code/Filters/ https://github.com/sebnil/FIR-filter-Arduino-Library

Pour améliorer le filtrage précédant, il est possible de prendre un filtre d’ordre supérieur.

Mais, les livres pour bien comprendre les filtres numériques ne sont pas très vulgarisé et ils n’ont pas beaucoup d’exemple comme on a pourrait le voir sur le post précèdent : http://people.rennes.inria.fr/Olivier.Sentieys/teach/filtragepourlesnuls.pdf http://public.iutenligne.net/electronique/le-bars/num/fnum_ana.pdf http://public.iutenligne.net/electronique/le-bars/num/fnum_syn.pdf http://www.f-legrand.fr/scidoc/docimg/numerique/filtre/filtrenum/filtrenum.html il y a sur ce lien, sur le filtage avec Arduino http://www.f-legrand.fr/scidoc/docimg/sciphys/arduino/filtrage2/filtrage2.html

Mais la vulgarisation n’est pas simple, car il y de nombreuses méthodes pour déterminer les coefficients d’un filtre numérique à partir d’un gabarit désiré ou à partir d’un filtre analogique. Evidemment, il y a des softs qui déterminent les coefficients assez facilement tel que : Matlab filterBuilder pour Mathcad Plus avec des fonctions spécifiques des soft en C http://iowahills.com/8DownloadPage.html Je n’ai pas réussi à faire fonctionner ce lien http://www.schwietering.com/jayduino/#Filter |500x151 Pas mieux avec celui la http://t-filter.engineerjs.com/

Je n’ai pas de trouver de tuto sur le forum en anglais, ni en francais ????

Autant, le faire par soi meme....avec mathcad c'est assez facile Mais pourquoi pas faire les calculs du filtre avec Excel, IDE arduino.... les calculs avec les complexes vont etre plus penible...mais why not....

Le calcul mathématique d’un butterworth numérique quel que soit son ordre va être présenté. Dans le lien suivant, un article présente la méthode bilinéaire mais avec un filtre de coupure de 1 rad/s ???????? Ce qui n’aide pas à la compréhension. https://www.dsprelated.com/showarticle/1119.php

Quelques soient l’ordre du filtre butterWorth, il n’y a pas de gain positif, le lien dans Wikipédia présente bien ce filtre analogique et il est très facile de déterminer la courbe d’atténuation avec Mathcad. Nous allons prendre une fréquence de coupure de 10hz et une fréquence d’échantillonnage de 100Hz https://fr.wikipedia.org/wiki/Filtre_de_Butterworth |468x500 Puis de déterminer les pôles du filtre pour les transformer en zéro du filtres numérique |500x407 |500x256 Enfin de vérifier, l’atténuation du filtre avec les coefficients déterminés, la courbe de fréquence est tracé. On retrouve bien une atténuation de 0.707 ou de -3db à la fréquence de coupure. |500x288

Plus, l’écart entre la fréquence d’échantillonnage et la fréquence de coupure est grande, plus l’ordre N du filtre pourra être grand. mais plus le gain devra etre petit et la résolution des zeros devront etre precis. pour bien tester le filtre numerique, il faut générer un signal sinusoïdal en entrée et voir en sortie l’atténuation pour chaque fréquence testée

sinon, en utilisant, la décomposition de série de fourriers d’un signal carré, L’amplitude de l’ondulation sera égale à l’équation suivante exemple avec une frèquence de coupure de 1hz.

Si on utilise, un ordre 1, alors l’ondulation theorique sera de 14% |500x134 Si on utilise un ordre 3, ondulation sera de 0.1% |500x121

Maintenant, il reste à implanter dans l’Arduino. Evidement les coefficients a(z) sont en float car il faut une certaine précision. Quel est le temps de calcul de l’Arduino en fonction de l’ordre ? Mais ce sera pour plus tard.

Précédemment, pour un filtre butteworth d’ordre 3, avec une fréquence d’échantillonnage de 100z et de fréquence de coupure de 10hz, Si l’on choisit les coefficients au centième près par défaut, le gain passe 1/55 à 1/53 et la courbe d’atténuation fréquentielle sera légèrement modifiée avec une fréquence de coupure légèrement décalé |500x250 |500x294

Le temps de calcul du filtre avec l’ATMEL 328 est de 120us pour un troisième ordre J’aurai pensé que le temps de calcul aurait été bien plus long. le compilateur doit faire des simplifications

Voici les résultats simuler avec Matlab dans un premier temps avec une fréquence d’échantillon de 100Hz, un signal carré de 10hz, et une fréquence de coupure de 10hz donc avec 10 échantillons par période du signal, ce n’est pas terrible |500x171 |500x353 Si l’on essaye de faire avec une fréquence d’échantillon de 1000hz, il y a une divergence du signal de sortie même avec 3 chiffres ou 4 chiffres après la virgule des coefficients zéros du filtre. C’est là que l’on voit qu’entre la théorie et la pratique, il y a un monde Plus l’ordre est élevé et plus s'il y a un écart entre fe et fc et plus il faudra une précision sur les coefficients du filtre. Remarque : Lorsqu’il y a un trop grand écart entre le gain statique avec les coefficients pris par défaut ou avec des coefficients avec 7 chiffres significatifs alors le filtrage devient divergent.

Donc, nous allons le faire avec un butterworth numerique du deuxième ordre Voici les valeurs pour une fréquence d’échantillonnage de 1000Hz et une fréquence de coupure de 10hz. |500x271 |500x331 La simulation dans Matlab, avec ces coefficients de ce deuxième ordre et un gain de 1/1000. Donne la courbe suivante. Ce signal de sortie a 100 valeurs par période donc il est moins échantillonné que le précèdent. |500x353 Toujours avec les mêmes coefficients que précèdent mais pour une fréquence de coupure de 1Hz avec une fréquence d’échantillonnage de 100Hz et toujours notre signal carré à 10Hz, on peut observer sur la figure suivante que l’ondulation de la sortie est bien de 13decimal comme en théorie et on garde bien la valeur moyenne. |500x353 |500x136

Voici les résultats avec l’Arduino, Le temps de calcul du filtre 2 ordre est de 80us Voici le programme,

#include 
#include 
#include 
#include    //chien de garde



#define LED13    13       
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables


unsigned    int    temps=0; 

            float  entree=0;
            float  entree1=0;
            float  entree2=0;
         
            float  sortie=0;
            float  sortie1=0;
            float  sortie2=0;
            
            float  out=0;
 const float b1 =2;
 const float b2 =1;

             
            const float a1 =-1.911;
            const float a2 =0.915;
            
            const float gain =1000;   
                    

void setup() {
  pinMode(LED13, OUTPUT);

  Timer1.initialize(10000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
  lcd.begin(16, 2);                   //modifier pour un afficheur 20x4
  Serial.begin(9600); 

  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 10  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet
}



// Interruptions  tous les 0.01s fait par le timer1***********************************
void callback()  {

temps++;  
if (temps>4)         //1=singnal carré de 0.1s  5*routine d'interruption*2
{
temps=0;  //reset : attention cette boucle doit etre infereir à son temps d'execution
if (entree==1023) {entree=0;}  else {entree=1023;}  

}//temps>1


      /* ----filtre passe pas Butterwoth 3émé ordre  pour fc=10hz,  fechantillon=1000Hz------   */
digitalWrite(LED13,HIGH);  //permet de mesurer à l'oscillo, le temps du calcul du filtre et le temps de la routine d'interruption
entree2=entree1;      //entree(n-2)
entree1=entree;       //entree(n-1)

sortie2=sortie1;      //sortie(n-2)
sortie1=sortie;     //sortie(n-1)

//sortie=entree+entree1*b1+entree2*b2+entree3*b3-sortie1*a1-sortie2*a2-sortie3*a3 ;   //filtre passe pas recursif ordre 3
sortie=(entree+entree1*b1+entree2*b2-sortie1*a1-sortie2*a2) ;   //filtre passe pas recursif ordre 2
out=sortie/gain;       

digitalWrite(LED13,LOW);
//if ( digitalRead(LED13)== 1 ) {digitalWrite(LED13,LOW);}  else {digitalWrite(LED13,HIGH);}

  Serial.print(temps);
  Serial.print(";");
  Serial.print("\t");
    
  Serial.print(entree);
  Serial.print(";");
  Serial.print("\t");
  
  Serial.print(out);
  Serial.print("\t");
  Serial.println(";");  //mise à la ligne

}//fin routine



///////////////////////////////////////////// Boucle correspondant à la fonction main 
void loop() {  
  lcd.setCursor(0,0); 
  lcd.print(temps);


   
} // fin loop

La sortie de l’Arduino correspond bien à la théorie |500x263

En synthèse : avec ce filtre RII du deuxième ordre filtre qui est bien mieux que le premier ordre alors extraire l'information de notre capteur accélérateur en atténuant les vibrations de la route est plus efficace.

Encore pour tester le filtre, on aurait pu utiliser le traceur série pour tester le filtre du deuxième ordre numérique, mais on peut aussi utiliser une sortie PWM.

En effet, si l’on désire lire le signal carré ou un signal alternatif est connaitre les résultats du filtre numérique, il est possible d’utiliser une sortie PWM filtré analogiquement par un RC. Avec une fréquence PWM de 32kHz, et un RC de (10kohms et une capacité de 33nF) donc une fréquence de coupure de 482Hz atténuera l’ondulation de la PWM de On peut observer l’ondulation pour un rapport cyclique de 50% sur la figure suivante : |500x265 Cette ondulation est de 0.075V autour de la valeur moyenne.

Avec un signal sinusoïdal ou carré de 10Hz et la fréquence de coupure de 1Hz, on retrouve bien que la valeur moyenne du signal carré qui est donc bien filtré en réel et dans ISIS. |500x265 Mais si l’on met un signal sinusoïdale de fréquence de 1hz, l’atténuation est de 0.35 à la place de 0.7 par contre le déphasage est bien de -90°. |500x269 Evidemment pour une fréquence sinusoïdale de 0.1Hz, il n’y a plus d’atténuation et le déphasage est presque à 0°. |500x349

Le code avec la pwm et la conversion analogique est le suivant :

#include 
#include 
#include 
#include    //chien de garde


#define PWM3   3      //   timer2    
#define LED13    13       
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables


unsigned    int    temps=0; 

            float  entree=0;
            float  entree1=0;
            float  entree2=0;
         
            float  sortie=0;
            float  sortie1=0;
            float  sortie2=0;
            
            float  out=0;
 const float b1 =2;
 const float b2 =1;

             
            const float a1 =-1.911;
            const float a2 =0.915;
            
            const float gain =1000;   
                    

void setup() {
  pinMode(LED13, OUTPUT);
  pinMode(PWM3,OUTPUT);

  Timer1.initialize(10000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
  lcd.begin(16, 2);                   //modifier pour un afficheur 20x4
  Serial.begin(9600); 

  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 10  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet

  
}



// Interruptions  tous les 0.01s fait par le timer1***********************************
void callback()  {

/*
temps++;  
if (temps>4)         //1=singnal carré de 0.1s  5*routine d'interruption*2
{
temps=0;  //reset : attention cette boucle doit etre infereir à son temps d'execution
if (entree==1023) {entree=0;}  else {entree=1023;}  

}//temps>1
*/

      /* ----filtre passe pas Butterwoth 3émé ordre  pour fc=10hz,  fechantillon=1000Hz------   */
entree=analogRead(A0);         
//digitalWrite(LED13,HIGH);  //permet de mesurer à l'oscillo, le temps du calcul du filtre et le temps de la routine d'interruption
entree2=entree1;      //entree(n-2)
entree1=entree;       //entree(n-1)

sortie2=sortie1;      //sortie(n-2)
sortie1=sortie;        //sortie(n-1)

//sortie=entree+entree1*b1+entree2*b2+entree3*b3-sortie1*a1-sortie2*a2-sortie3*a3 ;   //filtre passe pas recursif ordre 3
sortie=(entree+entree1*b1+entree2*b2-sortie1*a1-sortie2*a2) ;   //filtre passe pas recursif ordre 2
out=sortie/gain;       //plus facile de diviser  que de multiplier


out = map(out, 0, 1023, 0, 255);   //mise à l'echelle

analogWrite(PWM3,out); 


//digitalWrite(LED13,LOW);
if (entree>=850) {digitalWrite(LED13,HIGH);}  else {digitalWrite(LED13,LOW);}  //test de la lecture du signal

/*  Serial.print(temps);
  Serial.print(";");    //creation du fichier CSV
  Serial.print("\t");
*/    
  Serial.print(entree);
  Serial.print(";");
  Serial.print("\t");
  
  Serial.print(out);
  Serial.print("\t");
  Serial.println(";");  //mise à la ligne dans le terminal

}//fin routine



///////////////////////////////////////////// Boucle correspondant à la fonction main 
void loop() {  
  lcd.setCursor(0,0); 
  lcd.print(entree,0);
   lcd.print("   ");

   
} // fin loop

Réalisation complète et finie du typon sur ares : |500x281

Les 2 cartes arduino doivent venir s'empiler l'une sur l'autre

La carte à été réalisée à partir du schémas isis de base, légèrement modifé : |500x281

En effet j'ai modifié les entrées et sorties au niveau des ports arduino dans le schéma isis, pour relier tous les composants entre eux sur une même carte arduino sur ares. (Aucun composant devait être relié d'une carte à l'autre car les cartes s'empilent) Voici les ports affectés aux cartes arduino : |312x500

Remarquez que seul un fil est présent entre les 2 cartes, il s'agît de la broche 4 de la première carte qui doit être reliée au composant U1, il suffit de relier U1 à la broche 4 de la deuxième carte puisque les cartes s'empilent.

Le reste des différents fils non reliés doivent simplement être reliées par un pont.

J'ai également rajouté une résistance R10 en parallèle à R20 pour éviter une surchauffe de R20. |500x416

Enfin, remarquez que je n'ai mis que la led D10 par manque de place sur la carte arduino sur ares. |500x219

super

MAINTENACE ARDUINO NANO

|500x268

lorsqu'on alimente l'Arduino nano sous 5V ça marche mais lorsqu'on l'alimente en USB cela ne fonctionne pas. Quel est le composant dans le schéma qui ne fonctionne plus ?

|500x328

donc, ce n'est pas le régulateur 5V qui est est incriminé car cela fonctionne en 5V Mais l'erreur se trouve au niveau de la diode shotky D1 alimentée par l'USB.

Cette diode D1 se trouve sur le PCB (Printed Circuit Board)

|500x245

mais, on ne voit pas correctement ou est l'anode et la cathode sur le composant donc, on a identifié l'anode avec la mesure de la tension d'entrée VUSB à 5v. La diode MBR0520 supporte 0,5 A, donc nous l'avons remplacé par un boitier sod 123 supportant 0,3A

|500x256

https://i12.servimg.com/u/f12/20/05/80/21/710.png

nous avons fait un petit programme pour vérifier le bon fonctionnent des sorties. Celle -ci passe de 0 à 5V toutes les 5secondes pour pouvoir vérifier avec un multimètre les différentes tensions programme

/* * SANKHE Abdou Clignotement de LED Allume toues les LED pendant 5 seconde, puis les éteint pendant 5 seconde puis le programme se répète indéfiniment

Cet exemple est dans le domaine public Traduction française par X. HINAULT - www.mon-club-elec.fr */

define Led13 13

define Led12 12

define Led11 11

define Led10 10

define Led9 9

define Led8 8

define Led7 7

define Led6 6

define Led5 5

define Led4 4

define Led3 3

define Led2 2

define LedA0 A0

define LedA1 A1

define LedA2 A2

define LedA3 A3

define LedA4 A4

define LedA5 A5

define LedA6 A6

define LedA7 A7

// Définition des broches

void setup() { // initialise la broche 13 en sortie numérique // la broche 13 a une LED déjà connectée sur la plupart des cartes Arduino : pinMode(13, OUTPUT); pinMode(12,OUTPUT); pinMode(11,OUTPUT); pinMode(10,OUTPUT ); pinMode(9,OUTPUT ); pinMode(8,OUTPUT); pinMode(7,OUTPUT); pinMode(6,OUTPUT); pinMode(5,OUTPUT); pinMode(4,OUTPUT); pinMode(3,OUTPUT); pinMode(2,OUTPUT); pinMode(A0,OUTPUT); pinMode(A1,OUTPUT); pinMode(A2,OUTPUT); pinMode(A3,OUTPUT); pinMode(A4,OUTPUT); pinMode(A5,OUTPUT); pinMode(A6,OUTPUT); pinMode(A7,OUTPUT);

}

void loop() { digitalWrite(Led13, HIGH); digitalWrite(Led12, HIGH); digitalWrite(Led11, HIGH); digitalWrite(Led10, HIGH); digitalWrite(Led9, HIGH); digitalWrite(Led8, HIGH); digitalWrite(Led7, HIGH); digitalWrite(Led6, HIGH); digitalWrite(Led5, HIGH); digitalWrite(Led4, HIGH); digitalWrite(Led3, HIGH); digitalWrite(Led2, HIGH); // allume la LED

digitalWrite(LedA0, HIGH); digitalWrite(LedA1, HIGH); digitalWrite(LedA2, HIGH); digitalWrite(LedA3, HIGH); digitalWrite(LedA4, HIGH); digitalWrite(LedA5, HIGH); digitalWrite(LedA6, HIGH); digitalWrite(LedA7, HIGH);

delay(5000); // ne fait rien pendant 1 seconde digitalWrite(13, LOW); digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,LOW ); digitalWrite(9,LOW ); digitalWrite(8,LOW ); digitalWrite(7,LOW ); digitalWrite(6,LOW); digitalWrite(5,LOW ); digitalWrite(4,LOW ); digitalWrite(3,LOW ); digitalWrite(2,LOW );

digitalWrite(A0,LOW ); digitalWrite(A1,LOW ); digitalWrite(A2,LOW ); digitalWrite(A3,LOW); digitalWrite(A4,LOW ); digitalWrite(A5,LOW ); digitalWrite(A6,LOW ); digitalWrite(A7,LOW );

// éteint la LED delay(5000); // ne fait rien pendant 1 seconde }

schéma de simulation

|450x500

on peut observer que la sortie analogique A6 et A7 ne peuvent pas être commandé en numérique.

malgré que l'on soit à vide , la tension de sortie est seulement de 4.3V à cause de la chute de tension interne du transistor.

les tensions sont les suivantes :

|254x500 |360x500

Fonctionnement du MPU6050 Le capteur MPU6050 est la combinaison d’un accéléromètre et d’un gyroscope. Il est aussi doté d’un capteur de température que nous ne servirons pas ici. L’objectif était d’éteindre la l’éclairage lorsque le vélo ne bougeait plus pendant au moins 2 minutes (je me suis aussi amusé à faire le cas inverse ou lorsque le vélo bouge on allume). Cela nous permet d’avoir une meilleure autonomie et une meilleure gestion des batteries. Pourquoi avoir choisis le MPU6050 ? Nous utilisons le matériel que nous avons dans notre université, nous essayons de « recycler » un maximum pour éviter de faire des dépenses alors que nous pouvons utiliser d’autres composants.

Voici le programme que j’ai fait :

|340x500

Nous utilisons seulement l’accéléromètre du MPU6050, j’ai commencé par trouver par quel coefficient il fallait diviser la mesure pour obtenir quelque chose de cohérent, sur internet et les différents tutos explicatifs que l’on peut trouver personne ne parle de ce coefficient, j’ai donc cherché dans la datasheet et en regardants les différents paramètres que j’avais sur mon MPU6050, il s’avère qu’il fallait que je choisisse 16384. Ensuite j’ai effectué une correction à chaque démarrage ou redémarrage du module pour que son accélération d’origine soit 0,0,0 lors de son démarrage car nous devions tenir compte de l’inclinaison du vélo et la force gravitationnelle de 1G vers le centre de la terre. Par la suite j’ai calculé le module de l’accélération et j’ai fais en sorte que lorsque que l’on marche normalement à une vitesse d’environs 6km/h le module est d’environs 12/13, alors dans le programme lorsque le module est supérieur a 10 il active une boucle qui fait clignoter une led (cette même boucle sera remplacée par l’extinction de là l’éclairage du vélo). Pour trouver le module de l’accélération lorsque l’on marche nous avons dû effectuer des test e utilisant un Arduino nano, un écran LCD, le MPU6050 et 2 batteries lithium 18650.

J'ai vérifié la mesure du courant du processeur de l'arduino PRO MINI ainsi que celui de l'arduino NANO, les deux possèdent un processeur ATMEGA 328.

Pour réaliser cette mesure sur nous allons mettre une résistance 100 Ohms brancher en série sur l'alimentation et de l'autre côté sur l'entrée Vcc (pour l'arduino PRO MINI) ou sur l'entrée Vin (pour l'arduino NANO) Ensuite nous allons mesurer la tension aux bornes de la résistance, puis nous allons appliquer la loi d'Ohms: I = U/R

Pour la PRO MINI nous allons réaliser les mesures en utilisant les deux entrées l'entrée VCC et l'entrée RAW.

Voici les entrées RAW et VCC représenter sur le schéma de la carte arduino PRO MINI

Voici les entrées RAW et VCC représenter sur le diagramme de la carte arduino PRO MINI |500x336

Pour l'arduino PRO MINI en 16MHz alimenter sur VCC avec la led d'alimentation qui demande :

  • avec une alimentation de 3.3V, la consommation est de 1.9 mA, sachant que la led alimentation consomme 0.15mA
  • avec une alimentation de 5V, la consommation est de 9.7 mA, sachant que la led alimentation consomme 0.32mA

Pour l'arduino PRO MINI avec l'alimentation utilisant le régulateur de tension brancher sur l'entrée RAW, ce port peut être alimenté de 7V à 12V.

avec une alimentation de 7.5V, la consommation est de 13 mA, sachant que la led alimentation consomme 0.57mA avec une alimentation de 10V, la consommation est de 21 mA, sachant que la led alimentation consomme 0.82mA

Pour l'arduino NANO alimenter sur VIN on a avec une alimentation de 5V une consommation de 23 mA.

J'ai réalisé le schéma ISIS ci-dessous représentant un hacheur. |500x275 Ce montage est composé de resistances allant de 1 ohm à 100 kohms, d'un transistor TIP 122, d'une diode Schottky (PBYR745), d'une inductance de 0.5 mH, d'une led de puissance et d'un mosfet IRF 9530. |500x375

Voici le montage final avec la platine d'essai : |500x375

La PWM est généré par un signal carré de fréquence 32 KHZ Le hacheur est alimenté à 8.4 V j'ai préferer utiliser un mosfet IRF9530 au lieu d'un transistors TIP 122 car une mosfet à une haute impédance et ne demande qu'un petit courant pour s'allumer.

L'utilisation de la diode schottky fait office de protection des autres composants. Elle a un temps de commutation trés court ce qui lui permet d'être trés réactive.

Suite à la commande de la LED avec le CI FL7760 de mar 19 2019 précèdent

On souhaite réaliser un programme pour augmenter le rapport cyclique de la PWM, de 0% à 100% avec un pas de 10%, par l’appui d’un bouton poussoir. Ce circuit demande une pwm de dimming minimale de 2kHz.

Mais comment gérer l’incrément de cette PWM avec le bouton poussoir ?

Pour vérifier notre programme, nous l’avons simulé avec ISIS, avec une carte Arduino Nano, donc nous avons utilisé le pin 3 pour la PWM et le pin 2 pour notre bouton poussoir.

Dans le setup de notre programme, on déclare le pin connecté au bouton poussoir comme une entrée et la PWM comme une sortie (voir figure ci-dessous).

|500x124

Fonction Loop :

Nous avons déclaré et initialisé un boolean « relâcher_bouton » qui nous permettra d’augmenter l’intensité lorsque on relâche le bouton poussoir. La variable intensité ne peut que varier de 0 à 255 car à « analogWrite() » avec Atmel 328 est sur 8bit. Donc pour cela nous avons créé une condition : si l’intensité est supérieure à 255 on revient à 0 qui permettra d’éteindre la LEDde puissance. Au niveau de l’affichage, on affiche la valeur de la variable pourcentage, cette variable reçoit la valeur de l’intensité en pourcentage, en sorte que analogWrite (PWM,255) demande un cycle de travail de 100 % et analogWrite(PWM,127) correspond à un cycle de travail à 50%.

Voici le programme de la fonction loop :

void loop() {  
  lcd.setCursor(0,0); // position du cousor en haut à gauche 
  analogWrite(3, intensite);    //on envoie sur le pignal PWM la valeur de l'intensité
  lcd.print("Duty cycle ");lcd.print(pourcentage);lcd.print("%  "); // affichage du rapport cyclique
  boolean relacher_bouton= false; 
    
  if(digitalRead(bouton)==HIGH){ // si on appuie sur le bouton alors
    while(!relacher_bouton){      // on rentre dans cette boucle jusqu'à ce qu'on relâche le bouton
      if(digitalRead(bouton)==LOW){ // si on relâche le bouton alors 
        relacher_bouton=true; // relâcher_bouton est vrai et
        intensite=intensite+25.5; // dès qu'on rêlache le bouton, on augmenté l'intensité
        if (intensite > 255){ // si le rapport cyclique arrive à 255, soit 100% alors
          intensite=0; //Reviens à 0
        }      
        pourcentage = ((100*intensite)/255); //formule pour afficher le rapport cyclique en pourcentage
      }
    }
  }
}

Voyons la simulation sur ISIS, on remarque bien que pour un rapport cyclique de 30 %, nous avons 1,8 carreaux à 5V sur 6 ce qui correspond à 0,3=1.8/6 donc 30%.

|500x350">

De même, pour un rapport cyclique de 90%, on remarque que 5,4 carreaux sont à 5V sur 6 ce qui corresponde à 0,9=5.4/6 donc 90%

|500x348">

Ci-dessous le programme complet réalisé sur Arduino

#include 

int bouton = 2;  //init bouton 
float intensite=0;
int pourcentage=0;
LiquidCrystal lcd(9,8,4,5,6,7); 

void setup() {
  pinMode(3, OUTPUT); // PWM en sortie 
  pinMode(bouton, INPUT); // Bouton en entrée
  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 10  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet                                       
}

void loop() {  
  lcd.setCursor(0,0); // position du cousor en haut à gauche 
  analogWrite(3, intensite);    //on envoie sur le pignal PWM la valeur de l'intensité
  lcd.print("Duty cycle ");lcd.print(pourcentage);lcd.print("%  "); // affichage du rapport cyclique
  boolean relacher_bouton= false; 
    
  if(digitalRead(bouton)==HIGH){ // si on appuie sur le bouton alors
    while(!relacher_bouton){      // on rentre dans cette boucle jusqu'à ce qu'on relâche le bouton
      if(digitalRead(bouton)==LOW){ // si on relâche le bouton alors 
        relacher_bouton=true; // relâcher_bouton est vrai et
        intensite=intensite+25.5; // dès qu'on rêlache le bouton, on augmenté l'intensité
        if (intensite > 255){ // si le rapport cyclique arrive à 255, soit 100% alors
          intensite=0; //Reviens à 0
        }      
        pourcentage = ((100*intensite)/255); //formule pour afficher le rapport cyclique en pourcentage
      }
    }
  }
}

Communication avec Arduino:

Le MPU6050 utilise le protocole de communication I²C dont la connexion est réalisée par l'intermédiaire de deux lignes : • SDA (Serial Data Line) : ligne de données bidirectionnelle • SCL (Serial Clock Line) : ligne d'horloge de synchronisation bidirectionnelle Dans le monde Arduino, il existe une librairie dédiée à ce protocole : Wire. En lisant la doc de la librairie Wire Arduino, on voit que sur un Arduino NANO ce sont les entrées analogiques A4 et A5 qui correspondent respectivement à SDA et SCL. On câble donc tout cela ensemble. Le MPU a besoin d'être alimenté en 3.3V, on relie donc la broche Vcc à la broche 3.3V de l'Arduino et le GND au GND de l'Arduino. Ce qui nous donne au final ce câblage :

|500x262

Configuration :

Sensibilité de l’accéléromètre :

Le registre ACCEL_CONFIG permet de configurer la plage de fonctionnement de l'accéléromètre.

Une plage de ±2g est suffisante pour l'étude, ce qui nous amène à utiliser le facteur AFS_SEL = 0

https://servimg.com/view/19537397/6 Structure du registre ACCEL_CONFIG

La paramètre AFS_SEL est codé sur les bits 3 & 4. La valeur 0 en binaire s'écrit alors 0 aussi. Les bits 0, 1 et 2 sont réservés, on les laisse donc à 0. Les bits 5, 6, 7 servent à effectuer un auto-test des axes X Y Z respectivement. Cela ne nous intéresse pas, on les laisse donc à 0.

Plus loin dans la datasheet, on arrive sur la page du registre Power Management. Ce registre nous permet de choisir la source d'horloge que le MPU va utiliser au travers du paramètre CLKSEL.

https://servimg.com/view/19537397/7

Nous allons utiliser ici son horloge interne de 8MHz, soit CLKSEL = 0.

|500x44

Structure du registre PWR_MGMT_1

Là encore, on voit que ce registre est codé sur 8 bits. CLKSEL est codé sur les bits 0, 1 & 2. La valeur 0 en binaire s'ecrit alors 000 Le bit 3 TEMP_DIS (temparture disabled) sert à désactiver la lecture de la température lorsqu'il est à 1. On va garder cette information, on laisse donc ce bit à 0. On laisse le reste à 0, ce qui nous donne au final 00000000 en binaire, soit 0x00 (hex). Enfin, l'adresse du registre est 0x6B en hexadécimal. Ce qui nous donne le code Arduino suivant :

Wire.beginTransmission(MPU);        // Start communication with MPU6050 // MPU=0x68
Wire.write(0x6B);                  // Talk to the register 6B
Wire.write(0x00);                  // Make reset - place a 0 into the 6B register

Filtre passe bas :

Le registre, de nom CONFIG, va nous servir à configurer la fréquence de coupure du filtre passe-bas de l'accéléromètre au travers du paramètre DLPF_CFG.

Digital Low Pass Filter

On va partir sur une fréquendce d'environ ~43Hz, ce qui nous amène à DLPF_CFG = 3. On laisse les autres bits à 0, ce qui nous amène à en binaire, soit 0x03 en hexadécimal. Enfin, l'adresse du registre est 0x1A en hexadécimal. Ce qui nous amène au code Arduino suivant :

Wire.write(0x1A);             // Request the CONFIG register
Wire.write(0x03);             // Apply the desired configuration to the register : DLPF about 43Hz

Fréquence d’horloge :

Plus loin dans la datasheet, on arrive sur la page du registre Power Management. Ce registre nous permet de choisir la source d'horloge que le MPU va utiliser au travers du paramètre CLKSEL. https://servimg.com/view/19537397/10 Nous allons utiliser ici son horloge interne de 8MHz, soit CLKSEL=0

|500x44

Structure du registre PWR_MGMT_1 Là encore, on voit que ce registre est codé sur 8 bits. CLKSEL est codé sur les bits 0, 1 & 2. La valeur 0 en binaire s'ecrit alors 000. Le bit 3 TEMP_DIS (temparture disabled) sert à désactiver la lecture de la température lorsqu'il est à 1. On va garder cette information, on laisse donc ce bit à 0. On laisse le reste à 0, ce qui nous donne au final 00000000 en binaire, soit 0x00 (hex). Enfin, l'adresse du registre est 0x6B en hexadécimal. Ce qui nous donne le code Arduino suivant :

Wire.beginTransmission(MPU_ADDRESS); // Start communication with MPU
Wire.write(0x6B);                    // Request the PWR_MGMT_1 register
Wire.write(0x00);                    // Apply the desired configuration to the register
Wire.endTransmission();              // End the transmission

LECTURE DES DONNEES BRUTES DU MPU6050 :

Maintenant que le MPU6050 est câblé et configuré, il ne reste plus qu'à lire les données brutes du capteur.

On constate dans la table des registres que les registres 59 à 64 stockent les valeurs de sorties de l'accéléromètre .

|500x209

On va donc simplement parcourir le contenu de ces 6 registres, en commençant à l'adresse 0x3B :

Wire.beginTransmission(MPU_ADDRESS);// Start communicating with the MPU-6050
Wire.write(0x3B);                   // Send the requested starting register
Wire.endTransmission(false);             // End the transmission
Wire.requestFrom(MPU_ADDRESS,6);   // Request 14 bytes from the MPU-6050

Mesure de l’accélération :

Un accéléromètre mesure l'accélération subite et l'exprime en g. 1g représente l'accélération de pesanteur sur Terre, soit environ 9,8m.s−29 et des bananes. L'accéléromètre au repos mesure donc une accélération de 1g.

Script intégral en C sur l’IDE Arduino :

#include // include la bibliothèque Wire.h

#define MPU_ADDRESS 0x68  // I2C address of the MPU-6050

#define X  0        // X axis
#define Y  1        // Y axis
#define Z  2        // Z axis
float acc_total_vector;

int acc_raw[3] = {0,0,0};

/**
* Configure la plage de fonctionnement de l'accéléromètre :
*  - accéléromètre: +/-2g

*
* @return void
*/
void setup() {
analogReference(EXTERNAL);
Serial.begin(19200);
Wire.begin();  
// Configure power management
Wire.beginTransmission(MPU_ADDRESS); // Start communication with MPU
Wire.write(0x6B);                    // Request the PWR_MGMT_1 register
Wire.write(0x00);                    // Apply the desired configuration to the register
Wire.endTransmission();              // End the transmission

// Configure the acceleromter's sensitivity
Wire.beginTransmission(MPU_ADDRESS); // Start communication with MPU
Wire.write(0x1C);                    // Request the ACCEL_CONFIG register
Wire.write(0x00);                    // Apply the desired configuration to the register : ±8g
Wire.endTransmission();              // End the transmission

// Configure low pass filter
Wire.beginTransmission(MPU_ADDRESS); // Start communication with MPU
Wire.write(0x1A);                    // Request the CONFIG register
Wire.write(0x00);                    // Set Digital Low Pass Filter about ~43Hz
Wire.endTransmission();              // End the transmission

Wire.endTransmission(true);        //end the transmission
}

void loop() {
Wire.beginTransmission(MPU_ADDRESS);// Start communicating with the MPU-6050
Wire.write(0x3B);                   // Send the requested starting register
Wire.endTransmission(false);             // End the transmission
Wire.requestFrom(MPU_ADDRESS,6);   // Request 14 bytes from the MPU-6050

// Wait until all the bytes are received
while(Wire.available() < 6);

acc_raw[X]  = (Wire.read() << 8 | Wire.read())/ 16384.0; // Add the low and high byte to the acc_raw[X] variable
acc_raw[Y]  = (Wire.read() << 8 | Wire.read())/ 16384.0; // Add the low and high byte to the acc_raw[Y] variable
acc_raw[Z]  = (Wire.read() << 8 | Wire.read())/ 16384.0; // Add the low and high byte to the acc_raw[Z] variable

acc_total_vector = sqrt(pow(acc_raw[X], 2) + pow(acc_raw[Y], 2) + pow(acc_raw[Z], 2));

Serial.print(acc_raw[X]);
Serial.print("/");
Serial.print(acc_raw[Y]);
Serial.print("/");
Serial.print(acc_raw[Z]);
Serial.print("/");
Serial.println(acc_total_vector);
delay(10);

}

Résultats moniteur Arduino:

1g suivant +X :

1g suivant -Y :

1g suivant +Z:

Conclusion:

Quant aux différents filtres, j’ai utilisé le filtre passe-bas numérique intégré dans le MPU6050 avec une bande passante d’environ 45Hz, quand j’essaie de bouger le capteur pour voir les réponses suivant plusieurs axes, les réponses sont quasi-stables dans le moniteur série d’IDE Arduino, le fait d’implanter des équations récurrentes de différents types de filtre (pass_bas pass_haut passe bande …), c’est facile, mais je n’y vois pas l’intérêt, car tous les résultats qu’on trouve sur le moniteur série Arduino, sont soit 1g suivant X soit 1g suivant Y soit 1g suivant Z.

Allumer un feu stop après un freinage ou un arrêt normal du vélo, est tout à fait possible avec un accéléromètre détectant la décélération, toutefois cela nécessite une étude comparatives de plusieurs accéléromètres analogiques et numériques, sans oublier les autres solutions technologiques pour répondre à cette problématique, comme par exemple un compteur de vitesse (Tr/min)