Go Down

Topic: Eclairage à led de vélo (7.5W à l’avant et 3 W à l’arrière) avec Arduino (Read 2192 times) previous topic - next topic

iutgeiisoissons

Voici une publication pour les choix de la programmation d'un éclairage arrière de 3W avec Arduino qui reprend toutes les problématiques de ce post
https://www.fichier-pdf.fr/2019/03/06/arduino--led-eclairage-velo-v2/


https://www.fichier-doc.fr/2019/03/11/iut-geii-soissons-2019-arduino-regulation-led-v2-sivert/


Les leds de puissance doivent être régulé en courant par l'intermédiaire d'un hacheur
Voici 2 articles scientifiques qui en parlent
http://www.fichier-pdf.fr/2017/06/14/eclairage-velo-revue-2017-light-bike/
http://www.fichier-pdf.fr/2017/06/14/led-regulation-hystereris-eclairage-pour-velo/
https://docplayer.fr/65126810-Convertisseur-regulateur-de-led-blanche-de-10-a-100w.html


Sur ce forum, il est possible de commander tous les éléments pour créer son éclairage
http://velorizontal.bbfr.net/t16874p525-eclairage-a-del-pour-velo-led-light-for-bike-light-emitting-diode

Dans un premier temps, nous allons voir comment gérer un éclairage arrière qui est constitué d'une led principale de 3W et de 3 petites leds de 0.1W.
Un BP poussoir permet de gérer les différentes puissances et le clignotement par une routine d'interruption extérieure.  Ce BP permettra de mettre en veille et reveiller l'Arduino.
Un afficheur LCD est utilisé juste pour verifier la programmation.
2 batteries 2.5A.H série 18650 seront utilisées pour alimenter la carte Arduino et le hacheur qui fera varier le courant dans la led.
L'affichage de l'état de charge  SOC (state of charge) est déterminé approximativement en fonction de la tension OCV (open circuit voltage) par linéarisation.

Avec la pente a et b correspondant à l'équation suivante sachant que pour Umax=8.4V le  SOCmax sera de 100% et pour Umini=6V pour SOCmini de 5%:




Un capteur de température LM35 permettra de diminuer de mode, si la température du dissipateur de la led devient trop grande à cause de la température ambiante.


On peut observer sur la figure suivante la liste des entrées sorties et la simulation sous ISIS qui est telechargeable sur ce lien.

https://drive.google.com/open?id=16xHdWM1WZgy7pqlgEqLEWeQsasbsGW7F




Voici l'Algo pour gérer la led de 3W
Code: [Select]

Routine interruption toutes les 1ms qui permet de gérer le temps

Routine d'interruption extérieur par le bouton poussoir active les diffèrent mode de 0 à 6.
Mode 0 :  (0A)
Mode 1 : régulation de courant led P 0.35A (0.75W) mais clignotement de toutes les leds avec une période de 1s et un rapport cyclique de 0.4.
Mode 2 : régulation de courant  led P 0.7A (1.5W) avec clignotement
Mode 3 : régulation de courant led P  1.4A  (3W) avec clignotement
Mode 4 : régulation de courant led P 0.35A (0.75W) sans clignotement
Mode 5 : régulation de courant  led P 0.7A (1.5W) sans clignotement
Mode 6 : régulation de courant  led P 1.4A (3W) sans clignotement

Main
Tous les 100ms
Affichage du courant de consigne
Mesure du courant et réajustement de la PWM pour avoir le courant désiré
Mesure de la tension de 2 batterie lithium série dont la tension varie de 8.4V (100% chargé) à 6V (0% de charge)
Affichage de l'état de charge avec 4 leds
Mesure de la temperature
Si la température est supérieure à une certaine temperature minimisation de puissance


le programme en Piece Jointe


Perspectives :
Pour préserver la durée de vie de la batterie
Lorsque l'état de charge sera inférieur à  40% alors le mode 4 sera activé
Lorsque l'état de charge sera inférieur à 30% alors le mode 1 sera activé
Lorsque l'état de charge sera inférieur à 10% alors l'éclairage sera éteint et l'Arduino en veuille.


Utilisation d'un mode veuille, pour minimiser la consommation de l'Arduino lorsque l'éclairage n'est pas activé pour ne pas mettre d'interrupteur entre l'Arduino et la batterie.
https://pandauino.com/fr/comment-economiser-lenergie-dune-carte-arduino/


Gérer un accéléromètre qui détectera si le vélo ne bouge plus et dans ce cas au bout de 2 minutes, il éteindra la lumière et se mettra en veuille
un capteur MPU6050 pourra etre utilisé
https://www.instructables.com/id/MPU6050-Arduino-6-Axis-Accelerometer-Gyro-GY-521-B/

Réguler le courant de 3 leds rouge à 0.2W pour avoir une puissance lumineuse constante et ne plus avoir de perte d'énergie dans la résistance de limitation de courant R3.


le driver CH340 de nos arduinos peut etre telechargé ici
http://www.wch.cn/download/CH341SER_EXE.html

iutgeiisoissons

Pour un courant led de 3A, la puissance utile dans une led blanche qui a une tension de seuil de 3V
P=tension de seuil*Iled=3V*3A=9W

Pour ce  courant de 3A,  les pertes dans le transistor bipolaire PNP TIP127
P=Vce sat*Iled*PWM=1V*3A*0.5=1.5W   sachant que la PWM varie en fonction de la tension de la batterie
La puissance dans le diode de roue libre est egale à l'equation suivante
P=Ud seuil*Iled*(1-PWM)=0.3V*3A*(1-0.5)=0.45W  

Ces 2 puissances sont relativement important par rapport à la puissance utile dans la led.

Donc, pour ameliorer les performances du hacheur, pour augmenter l'autonomie de l'eclairage et  pour minimiser l'encombrement des dissipateur, un transistor MOS surdimensionné a été choisi

En appliquant filtres dans farnell, le transistor  FDD4243 a été choisi en fonction de son prix faible et de ces performances
https://fr.farnell.com/on-semiconductor/fdd4243/mosfet-canal-p-40v-14a-to-252/dp/2323170

Le FDD4243 pouvant supporter 23A avec une résistance RDS on=0.036Ω  pour 0.25€ boitier CMS TO252.
La résistance thermique jonction ambiant d'un boitier to252 simple couche est de 132°C/W
http://rohmfs.rohm.com/en/products/databook/applinote/ic/power/linear_regulator/to252-3_rth_bd4xxm5fp_an-e.pdf
Donc la puissance max dissipable sans dissipateur
Pdissipable=(TJontoin max-Tambiante)/RTHja=(150-25)°C/ 132°C/W)=1Watt
Avec une surface de cuivre de 200mm^2, alors la resistance RTHJA=70°C et permettra de dissiper 2W.

Alors qu'un boitier TO220 a une résistance thermique environ 62°C/W aurait été plus facile à utiliser mais le prix minimum est de 0.85€ pour le transistor IRF9540.

https://fr.farnell.com/infineon/irf9540npbf/trans-mosfet-canal-p-to-220-100v/dp/8648620?MER=sy-me-pd-mi-alte


Mais quel est la puissance que devra dissiper le transistor ?

La puissance théorique  perdue dans ce transistor FDD4243 sans prendre en compte les pertes à la commutation
P=Rds on*Iled^2* PWM =0.12*3A^2*PWM =1.35W,    il faudra
Les pertes à la commutation théorique sont négligeables comme on peut l'observer sur la figure suivante
P=Ubattery* Iled*(trise+tfall)*FrequenceHachage/2=8V*3A*(26+14)*10^-9*32khz/2=0.015W


Le choix de la diode Switch-mode Power Rectifier ,

MBRS320T3G supportant 4A en boitier    DO-241 à 0.14€ pourrait etre utilisé.
https://fr.farnell.com/w/c/semiconducteurs-composants-discrets/diodes/diodes-schottky/prl/resultats?courant-if-moy-=4a&st=diode%204A&sort=P_PRICE

Mais une MBRD835LT4G supportant 8A en boitier    TO-252 à 0.2€ est plus pertinent car elle chauffera moins
http://www.farnell.com/datasheets/2353974.pdf?_ga=2.243937932.867156930.1548826576-1436130221.1548826576&_gac=1.251268402.1548832333.EAIaIQobChMIrIvPhvqU4AIVSIXVCh3j6wdsEAAYASAAEgLzqvD_BwE

Avec le transistor MOS, le courant dans la led, n'est plus le meme en fonction de la PWM.
Un réajustement des valeurs du correcteur integral a du etre fait.


Pour la mise en veuille, on a utilisé la bibliothèque low-power,
https://github.com/rocketscream/Low-Power
Le réveil se fait par interruption extérieur en mode 5.
Mais, pour réactiver le timer1, on a du faire un reset par l'intermédiaire de la biblioteque wachdog avr/wdt.h.
on aurait pu aussi réactiver le timer1, en faisant un reset par l'intermédiaire de la sortie A5 q

L'algorithme  a donc changer

Code: [Select]



Timer1 Routine interruption toutes les 1ms qui permet de gérer le temps

Routine d'interruption extérieur par le bouton poussoir active les diffèrent mode de 0 à 5.
Mode 1 : régulation de courant led P 0.35A (0.75W) mais clignotement de toutes les leds avec une période de 1s et un rapport cyclique de 0.4.
Mode 2 : régulation de courant  led P 0.7A (1.5W) avec clignotement
Mode 3 : régulation de courant led P  1.4A  (3W) avec clignotement
Mode 4 : mode 4
Mode 5 : reset

Main
Si mode 4 mise, arret PWM et mise en veuille de l'arduino

Tous les 100ms
Affichage du courant de consigne
Mesure du courant et réajustement de la PWM pour avoir le courant désiré
Mesure de la tension de 2 batterie lithium série dont la tension varie de 8.4V (100% chargé) à 6V (0% de charge)
Affichage de l'état de charge avec 4 leds
Mesure de la temperature
Si la température est supérieure à une certaine temperature minimisation de puissance


un lien pour telecharger  le fichier ISIS
https://drive.google.com/open?id=16xHdWM1WZgy7pqlgEqLEWeQsasbsGW7F





Perspectives :


Si la connaissance de l'état de charge des batteries est facilement déterminée pas la tension avec les éléments 18650 li-ion, ce n'est pas possible de le faire avec des batteries Lipofer car la tension reste constante malgré la diminution du SOC
Par conséquent, la consommation du courant doit être déterminée (A.h). Or dans ce cas, la résistance de mesure du courant dans la led doit se faire mais aussi celle absorbée par l'Arduino.
Donc, la mesure du courant doit se faire avec une résistance shunt sur l'alimentation avec des ponts diviseurs à la place de le faire sur la masse.

Il est serait idiot que l'Arduino gère la charge des 2 batteries.
En effet, Le chargeur extérieur étant limité à 1A avec une tension identique à la tension seuil des 2 éléments donc 8.4V, donc ce n'est pas valable de réguler le courant de charge avec l'Arduino.
De plus, un BMS est obligatoire pour d'équilibrer les 2 cellules, mais aussi arrêter l'alimentation du système si la batterie est trop déchargée pour ne pas la détruire

Attention avec le programme suivant, si les 3 leds sont commandé par la PWM broche 11 et si leur puissance lumineuse peut varier grâce à la PWM, il y a toujours les pertes dans la résistance R3 de limitation de courant. Pour ne plus avoir ces pertes, il faut obligatoirement réaliser un hacheur abaisseur.

En mode 3, ou la puissance de la led est la plus importante, à la place de réguler le courant à 1.5A, il serait possible de réguler la température à 90°C ce qui permettrait d'avoir la puissance lumineuse

Mais tous ceux-ci seront d'autres histoires….




hbachetti

Salut.

Aurais-tu un schéma plus précis ?
Dans ton code je vois que tu utilises la référence VCC pour la mesure de la batterie. Je suppose que tu alimentes l'ARDUINO à travers un régulateur ?

Question : pourquoi une NANO alors qu'une PRO MINI serait bien plus économe en énergie ?

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

la batterie alimente directement la tension Vin de l'arduino par l'intermédiare du regulateur interne de l'arduino LM2940 fournit le 5V.

j'ai modifié le programme dans le post précedent et isis....
et ajouté,  un lien pour telecharger  le fichier ISIS

Nous avons utilisé l'arduino nano, car nous en avions d'avance……

Mais très bonne idée, dans la version finale d'utiliser la version pro mini que je ne connaissais pas….
Car la différence de consommation entre le pro mini et l'Arduino nano….doit etre de 15mA car  le pro mini n'a pas le convertisseur USB RS232

hbachetti

Quote
Car la différence de consommation entre le pro mini et l'Arduino nano….doit etre de 15mA car  le pro mini n'a pas le convertisseur USB RS232
Exactement.

J'ai réuni pas mal d'infos ICI au sujet de la PRO MINI :
- réduction de la consommation
- mode veille
- chargement
- etc.
Il y a des versions 5V ou 3.3V.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

Génial, le site et la consommation, superbe travail
https://riton-duino.blogspot.com/2018/02/arduino-pro-mini-basse-consommation.html

si j'ai bien compris, la carte arduino et mini peuvent fonctionner sans regulateur de 1.8V à  5.5V donc sur la plage de  tension dune  batterie lithium  qui varie de 4.2V à 3.3V. et cela permet de minimiser la consommation car le regulateur demande 5mA.
Dans ce cas, les 2 batteries lithium ion 18650 devrait etre mis en  //.
Par contre, il va falloir utiliser une tension de reference pour la Conversion analogique si la tension d'alimentation change.
il faut changer de capteur de temperature LM35 qui a besoin de 4V minimum par une PT1000

Suite aux perspectives précédentes, la led peut être commandé en régulation de température ce qui permet de la commander pour le maximum de sa puissance.

Le schéma automatique de la régulation de courant  qui s'imbrique dans la regulation de température est le suivant :


Exemple : La consigne de température maximum du dissipateur a été  choisi de 100°C sachant le dissipateur ou est placé la led est de 15°C/W à 0km/h mais passe à 7°C/W avec une vitesse de 20km/h.
Donc avec une température ambiante de 25°C, la puissance maximale dans la led en fonction de la vitesse sera de
Pmax=(100°C-25°C)/15°C/W=4.33W    à la vitesse de 0 km/h
Pmax=(100°C-25°C)/7°C/W=10W    à la vitesse de 20 km/h

La température de jonction de la led avec sa résistance thermique de 3.5°C/W sera de
Tjonction=Tboitier+ Pmax*RTHjc=100°C+10W*3.5=135°C
Mais la température de jonction peut atteindre 150°C/W

La régulation de température n'est pas trop compliquée à programmer.
Par contre, le coefficient intégral est à modifier par rapport à celui du courant.
Car si la température de la led est au départ de 30°C pour atteindre les 100°C alors la Puissance admissible par la led precedente sera tres vite dépassé.
Il faut donc limiter le courant à une certaine valeur pour ne pas detruire la led car la regulation precedente augmentera inutilement la PWM, aisni que le courant



voici le code de la programmation
Code: [Select]

#include <LiquidCrystal.h>
//#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <avr/wdt.h>   //chien de garde
//#include <avr/power.h>   //mise en veille
//#include <avr/sleep.h>
#include "LowPower.h"     //https://github.com/rocketscream/Low-Power



#define led0     10       //
#define led1     A4       //
#define led2     12       //
#define led3     13       // 13      
#define BP3        2       //
#define battery    A0      //relay magnetron



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


unsigned    int temps=0;    //temps de la routine d'interruption
            byte  temps1=0;
            byte mode=1;    // etat du bouton poussoir
            float Ic=0.35;   // courant de consigne
            float Ba=0;   //tension batterie
            byte SOC=0;  //etat de charge en pourcentage
            byte barreled=0;    
            byte PWM=0;  
            float I=0;   //courant led principal
            float erreur=0;   //courant led principal
            float kp=10;        //coefficient proportionel integral
            float ki=4;
            float Integral=34;
float   T=0;     //temperature
float   Tc=80;   //consigne de temperature
float  erreurT=0;



// the setup function runs once when you press reset or power the board
void setup() {
//  digitalWrite(A5,HIGH);
//   delay(200);

 
pinMode(led0, OUTPUT);   //
pinMode(led1, OUTPUT);   //
pinMode(led2, OUTPUT);   //
pinMode(led3, OUTPUT);   //led carte arduino
pinMode(3, OUTPUT);      //PWM
pinMode(11, OUTPUT);      //PWM


  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
 // Serial1.begin(9600);

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

  pinMode(2, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), interBP, LOW);   //routine d'interruption exterieur broche 2
//wdt_enable(WDTO_15MS);
}



// Interruptions  tous les 0.001s fait par le timer1***********************************
void callback()  {
temps++;

  //if ( digitalRead(LEDV)== 1 ) {digitalWrite(LEDV,LOW);}  else {digitalWrite(LEDV,HIGH);}
//wdt_reset();
}//fin routine


//interruption exterieur
void interBP() {
//interrupts();

mode++;                  //incrementation des modes
if (mode>=6) mode=1;

  switch (mode) {
  case 1:Ic=0.35;Integral=34;   break;   //donne un ordre de grandeur de la valeur de la PWM=255*(Rshunt*Ic-Useuil)/Ubattery
  case 2:Ic=0.75;Integral=43;   break;
  case 3:Tc=80;Ic=1.5;   break;
  case 4:analogWrite(3,0); analogWrite(11,0);digitalWrite(led0,LOW);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);  break; //puis mise  en veuille
  case 5: wdt_reset();    break;   //remise à zero    https://www.instructables.com/id/two-ways-to-reset-arduino-in-software/
     }
                              
   }


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


if (mode==4)  {lcd .clear ();LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);}
           //   LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
           //mode veuille



if (temps>1)         //affichage tous les 100ms
{
Ba=analogRead(A0);     //mesure tension
Ba=Ba/79;              //
SOC=40*Ba-233;    // cacul de l'etat de charge
lcd.setCursor(0,1);   //colonne, ligne
lcd.print("SOC");
lcd.print(SOC);
barreled=(SOC/18)-1;    

  switch (barreled) {
  case 0:digitalWrite(led0,LOW);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);     break;               //valeur deu courant dans la led principale
  case 1:digitalWrite(led0,HIGH);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);   break;
  case 2:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,LOW);digitalWrite(led3,LOW);   break;
  case 3:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,HIGH);digitalWrite(led3,LOW);   break;
  case 4:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,HIGH);digitalWrite(led3,HIGH);   break;          }

I=analogRead(A1);
I=I/102;
lcd.setCursor(7,1);
lcd.print("I=");
lcd.print(I,1);

  
T=analogRead(A2);   //mesure temperature
T=T/2;
lcd.setCursor(13,1);
lcd.print(T,0);
lcd.print(" ");

if ((T>90) && (mode==2)) {erreurT=Tc-T; Ic=Ic+erreurT*0.05;}    //diminution du courant si la temperature atteint 90°C
if (mode==1 || mode==2 )  {lcd.setCursor(0,0);lcd.print("I"); }    //limitation du courant à cause de la  temperature
 
              
if (mode==3) {erreurT=Tc-T; Ic=Ic+erreurT*0.05 ;lcd.setCursor(0,0);lcd.print("T");}  // regulation temperature
if (Ic>=2) {Ic=2; }             // limitation du courant de la consigne
if (Ic<=0.35) {Ic=0.35; }      

lcd.setCursor(1,0);
lcd.print(Ic);
erreur=Ic-I;

//Proportionnel=kp*erreur;
//derive=(erreur-erreurP)*kd;             //derive=(erreur-erreur*Z^Ts)/Ts   avec Ts=Tsampleur
//output=Proportionnel+Integral;   //ce n'est pas la peine de divisée par Ts car si Ts est petit cela donne des valeurs enormes
Integral= Integral+erreur*ki;
if (Integral>=255) Integral=255;
if (Integral<=0) {Integral=0;}
PWM=Integral;
if (Ic==0) {PWM=0;}  

lcd.setCursor(7,0);
lcd.print("PWM=");
lcd.print(PWM);
lcd.print("  ");
analogWrite(3,PWM);    //broche et valeur PWM
//analogWrite(11,127);


temps1++;
if (temps1<2)  {analogWrite(11,255);          }
if (temps1>2)  {analogWrite(11,0);temps1=0;   }
              


temps=0;
}//temps>100

  
} // fin loop  








Perspectives :


On pourrait aussi faire un mode qui gere l'eclairage en fonction de la lumière extérieure en mettant un capteur LDR sur le dessus de l'éclairage.
En effet en plein jour cela permettrait de couper l'éclairage. Attention, parfois on veut meme en plein jour ce faire voir. Donc, il faut garder les anciens modes.

Maintenant que le programme est effectué l'afficheur LCD peut etre retiré.
Etant donné que l'on a plus des sorties non utilisées,  les 8 leds du barled pourraient etre utilisées sachant que leur consommation est dérisoire par rapport à la led de puissance

De plus à la place du LCD, la liaison serie pourrait exporter les dynamiques de la regulation de courant et de temperature pour optimiser la commande.


hbachetti

Quote
il faut changer de capteur de temperature LM35 qui a besoin de 4V minimum par une PT1000
PT1000 c'est surdimensionné.
DS18B20 plutôt (-55°C à +125°C et 3.0V - 5.5V) ?

Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

Bonne idée pour le DS18B20 mais en boitier TO92 ce n'est pas idéal ni en 8 pin So. Prix plus cher qu'une PT1000 qui est de l'ordre de 1€

La PT1000 est assez facile d'utilisation, par rapport aux circuits intégrés mais consomme tout le temps 0.7mA sous 4.1V.
Alors que DS18B20 consomme 1 mA lorsqu'il est actif et 0.0001mA en standby. Mais il faudrait faire un test.

Etant donné que la tension de référence 5V n'existe plus. L'utilisation de la référence interne 1.1V sera utilisée. Donc, il faut changer aussi le pont diviseur
analogReference(INTERNAL) ;   //1.1V tension de référence internal        
La résistance shunt de mesure de courant passe à 0.1 ohms, ce qui permet d'avoir moins de perte de puissance.

Donc, pour minimiser la consommation, la broche A3 en sortie numérique sera utilisée pour alimenter les 2 ponts diviseurs sachant que la chute de tension dans les transistors interne de l'ATMEL  est négligeable.
La PT 1000 est linéaire et vaut 1346 ohms à 100°C
Mais la tension fournie par la mesure de température, va varier en fonction de la tension de la batterie mais comme cette tension est mesurée, cela se corrige mathématiquement
L'équation pour la PT1000, T=(A2-816*Ba/5)/(0.48*Ba)  
avec Ba correspondant à la tension de la batterie.

Voici les nouvelles valeurs du schéma électrique
Lors de la simulation la sortie A3 sera de 5V et pas à la valeur de la tension Vin malheureusement.
Attention, il faut obligatoirement mettre VCC sur 5V sur l'Arduino, les convertisseurs de l'Arduino nano de la simulation du programme ne fonctionnent pas.

Le coefficient du programme de la mesure de tension change, ainsi que l'état de charge
Ba=A0/221;              //4.2V*pont diviseur=1V   1*1023/(1.1V*4.2)=221
SOC=79*Ba-232;    // calcul de l'état de charge.
Le coefficient de la mesure de courant change aussi est passe à I=A1/93

le shema de simulation est telechargeable sur ce lien
https://drive.google.com/open?id=1uhA8GpavQT-Ov3SpcyT3Rqr05n0EuWH9



Réalisation du typon
Proteus (ISIS et ARES) n'a pas les packages de l'Arduino nano….Donc, il faut le créer et le voici  il sur mon drive et ainsi que mes librarys car j'ai du réalisé de nombreux composants  qui faudra mettre dans la Library  userpkg et userdevice


Le schéma du typon n'est pas identique à celui de simulation donc le voici aussi téléchargeable

Le fichier du typon de l'eclairage
https://drive.google.com/file/d/1NGjCxoRsMxuMwiFWGkKO1xVeSQM2Rhdh/view?usp=sharing
mes differentes  library et le cours ISIS ARES peuvent etre retrouvé ici
https://drive.google.com/drive/folders/0B_fB3GAsM02FfkRxVFRzVG8zeU52QkZ3cFR4RFRRS3NQakRQZnpvaDBBVElkZExQMkxPSWc?usp=sharing





Pour ne pas avoir de fil à souder, toute l'électronique doit s'emboiter.
- La Première carte est l'Arduino évidement
- La Deuxième carte est le  hacheur
- La Troisième carte est pour la led d'éclairage, la band graph, le Bouton poussoir et le capteur de température.


Une inductance 0.1mH/3A en CMS (IDP1451 128x550    INDC3225X135   BOBINE05MH) est assez grosse donc cela ne vaut pas être pas trop le cout de mettre des  transistors et diode CMS à plat….autant mettre les composants debout en boitier T0 220
Pour un prototype, mettre des composants à trous est plus facile si l'on doit changer quelques composants.

Perspectives ;
Dans un futur, un nouveau typon avec que des composants CMS sera effectué, pour savoir si c'est cela prend moins de place ou pas.

Est-ce que la simulation du programme fonctionne avec la version Pro mini avec la tension Vin ?



hbachetti

Quote
Mais la tension fournie par la mesure de température, va varier en fonction de la tension de la batterie mais comme cette tension est mesurée, cela se corrige mathématiquement
La référence interne varie aussi pas mal en fonction de la température.

Si ça peut aider : Alimenter un arduino sur pile ou batterie :  7.1. Mesure
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

Super bien écrit ce blog et tres pedagogique
https://riton-duino.blogspot.com/
Mais, je suis un spécialiste des batteries, des chargeurs, régulations….par contre découvreur de l'Arduino
http://velorizontal.bbfr.net/t20802-bms-et-depannage-ou-maintenance-de-pack-de-batterie
D'ailleurs, j'ai bien avancé sur le programme et la réalisation du chargeur lithium mais je ne peux encore le mettre sur le forum Arduino car j'attends le résultat de mes étudiants.
https://forum.arduino.cc/index.php?topic=538070.0
En effet, j'utilise le forum comme départ avec mes étudiants et voir l'avancement des différentes possibilités de réalisation.

Entre 0 et 100°C, il y a environ 5% de variation de la tension de référence et même si la tension de refendre a une variation de 5%. Mais ce n'est pas très grave puisque le barographe est à 25% (avec ces 4 leds) et que la mesure du courant et de température ne sont pas à 10% près.
Nous avons un BMS

Avec la pro mini Malgré qu'il n'y ait pas la sortie A4 pour la led 1, le compilateur compile quand même
Là encore, la simulation des convertisseurs analogique numérique ne fonctionnent pas correctement si +5V, n'est pas à Vcc.


En simulation, la nano ne peut lire la tension reference encore un bug de isis

Etant donné, qu'il n'y a plus que 2 batteries 18650 en //
La charge se fera par ce module


Code: [Select]

#include <LiquidCrystal.h>
//#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <avr/wdt.h>   //chien de garde
//#include <avr/power.h>   //mise en veille
//#include <avr/sleep.h>
#include "LowPower.h"     //https://github.com/rocketscream/Low-Power



#define led0     10       //
#define led1     A4       //
#define led2     12       //
#define led3     13       // 13     
#define BP3        2       //
#define battery    A0     



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


unsigned    int temps=0;    //temps de la routine d'interruption
            byte  temps1=0;
            byte mode=1;    // etat du bouton poussoir
            float Ic=0.35;   // courant de consigne
            float Ba=0;   //tension batterie
            byte SOC=0;  //etat de charge en pourcentage
            byte barreled=0;   
            byte PWM=0;   
            float I=0;   //courant led principal
            float erreur=0;   //courant led principal
            float kp=10;        //coefficient proportionel integral
            float ki=4;
            float Integral=150;
float   T=0;     //temperature
float   Tc=80;   //consigne de temperature
float  erreurT=0;



// the setup function runs once when you press reset or power the board
void setup() {
 
pinMode(led0, OUTPUT);   //
pinMode(led1, OUTPUT);   //
pinMode(led2, OUTPUT);   //
pinMode(led3, OUTPUT);   //led carte arduino
pinMode(3, OUTPUT);      //PWM
pinMode(11, OUTPUT);      //PWM
pinMode(1, OUTPUT);     
pinMode(A3, OUTPUT);
digitalWrite(A3,HIGH);


  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
 // Serial1.begin(9600);

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

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), interBP, LOW);   //routine d'interruption exterieur broche 2
//wdt_enable(WDTO_15MS);

analogReference(INTERNAL) ;   //1.1V tension de refenrence inernal
//analogReference(DEFAULT) ;
}



// Interruptions  tous les 0.001s fait par le timer1***********************************
void callback()  {
temps++;

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

//wdt_reset();
}//fin routine


//interruption exterieur
void interBP() {
//interrupts();

mode++;                  //incrementation des modes
if (mode>=6) mode=1;

  switch (mode) {
  case 1:Ic=0.35;Integral=150;  digitalWrite(A3,HIGH);   break;   //donne un ordre de grandeur de la valeur de la PWM=255*(Rshunt*Ic-Useuil)/Ubattery
  case 2:Ic=0.75;Integral=170;   digitalWrite(A3,HIGH);   break;
  case 3:Tc=80;Ic=1.5;   digitalWrite(A3,HIGH);  break;
  case 4:analogWrite(3,0); analogWrite(11,0);digitalWrite(led0,LOW);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);digitalWrite(A3,LOW);  break; //puis mise  en veuille
  case 5: wdt_reset();    break;   //remise à zero    https://www.instructables.com/id/two-ways-to-reset-arduino-in-software/
     }
                               
   }


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


if (mode==4)  {lcd .clear ();LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);}
           //   LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
           //mode veuille






if (temps>100)         //100 affichage tous les 100ms
{
Ba=analogRead(A0);     //mesure tension
Ba=Ba/221;              //4.2V*pont diviseur=1V   1*1023/(1.1V*4.2)=221

if (Ba<3.2)  {mode=4;}   //mise en veuil car pas de BMS.

SOC=79*Ba-232;    // cacul de l'etat de charge
lcd.setCursor(0,1);   //colonne, ligne
lcd.print("SOC");
lcd.print(SOC);
barreled=(SOC/18)-1;   

  switch (barreled) {
  case 0:digitalWrite(led0,LOW);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);     break;               //valeur deu courant dans la led principale
  case 1:digitalWrite(led0,HIGH);digitalWrite(led1,LOW);digitalWrite(led2,LOW);digitalWrite(led3,LOW);   break;
  case 2:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,LOW);digitalWrite(led3,LOW);   break;
  case 3:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,HIGH);digitalWrite(led3,LOW);   break;
  case 4:digitalWrite(led0,HIGH);digitalWrite(led1,HIGH);digitalWrite(led2,HIGH);digitalWrite(led3,HIGH);   break;          }



I=analogRead(A1);
I=I/93;               //0.1ohms*1A=0.1V   0.1V*1023/1.1=93
lcd.setCursor(6,1);
lcd.print("I=");
lcd.print(I,2);

 
T=analogRead(A2);   //mesure temperature
T=T-814;
T=T/(0.48*Ba);
lcd.setCursor(13,1);
lcd.print(T,0);
lcd.print(" ");

if ((T>90) && (mode==2)) {erreurT=Tc-T; Ic=Ic+erreurT*0.05;}    //diminution du courant si la temperature atteint 90°C
if (mode==1 || mode==2 )  {lcd.setCursor(0,0);lcd.print("I");lcd.print(Ic,2);lcd.print(" "); }    //limitation du courant à cause de la  temperature
 
             
if (mode==3) {erreurT=Tc-T; Ic=Ic+erreurT*0.05 ;lcd.setCursor(0,0);lcd.print("T");lcd.print(Tc,0);lcd.print("  ");}  // regulation temperature
if (Ic>=2) {Ic=2; }             // limitation du courant de la consigne
if (Ic<=0.35) {Ic=0.35; }     

lcd.setCursor(1,0);
lcd.print(Ic);
erreur=Ic-I;

//Proportionnel=kp*erreur;
//derive=(erreur-erreurP)*kd;             //derive=(erreur-erreur*Z^Ts)/Ts   avec Ts=Tsampleur
//output=Proportionnel+Integral;   //ce n'est pas la peine de divisée par Ts car si Ts est petit cela donne des valeurs enormes
Integral= Integral+erreur*ki;
if (Integral>=255) Integral=255;
if (Integral<=0) {Integral=0;}
PWM=Integral;
if (Ic==0) {PWM=0;} 

lcd.setCursor(6,0);
lcd.print("PWM=");
lcd.print(PWM);
lcd.print("  ");
analogWrite(3,PWM);    //broche et valeur PWM
//analogWrite(11,127);


temps1++;
if (temps1<2)  {analogWrite(11,255);          }
if (temps1>2)  {analogWrite(11,0);temps1=0;   }
           
temps=0;
}//temps>100


   
} // fin loop 


Les BMS de protection d'une batterie S1 arrête la décharge à 2,75V, voir 2,5V.  Or, c'est un peu faible pour éviter des décharges profondes

Par conséquent, on préféra s'en passer et si l'Arduino mesure une tension batterie  inférieure à 3.2V alors il devra se mettre en mode veuille.

hbachetti

Quote
Entre 0 et 100°C, il y a environ 5% de variation de la tension de référence et même si la tension de refendre a une variation de 5%. Mais ce n'est pas très grave puisque le barographe est à 25% (avec ces 4 leds) et que la mesure du courant et de température ne sont pas à 10% près.
Juste pour de l'affichage : en effet, pas très grave.

TP4056 : bon choix.

Quote
Les BMS de protection d'une batterie S1 arrête la décharge à 2,75V, voir 2,5V.  Or, c'est un peu faible pour éviter des décharges profondes
J'en ai déjà testé qui s'arrêtaient à 3V pile (9.05V pour un 3S).

Le test ICI

Quote
https://forum.arduino.cc/index.php?topic=538070.0
Je vais me pencher dessus, surtout la partie NIMH.

Bonne continuation
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

Quote
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.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

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

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


hbachetti

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.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iutgeiisoissons

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.

Go Up