Sari la conținut
ELFORUM - Forumul electronistilor

Încărcător acumulatori NI-MH cu Arduino Uno


mihai 7

Postări Recomandate

/*
 
NiMh Charger 0.9
with AtTiny85 @ 1Mhz
by Luca Soltoggio
10/03/2012 - 20/04/2012

 

La 28.07.2022 la 20:02, mihai 7 a spus:

Menționez că procesorul este setat la clock 8 Mhz internal.

 

Am schimbat frecvența ceasului microprocesorului Attiny85 la 1 Mhz internal, așa cum  se cere în cod. Deocamdată nu știu dacă acum oprește încărcarea, nu mai am acumulatori de încărcat, pentru teste.

Editat de mihai 7
Link spre comentariu
  • Răspunsuri 32
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • mihai 7

    17

  • Mircea

    8

  • XAN77

    3

  • validae

    1

Top autori în acest subiect

Din codul sursă, eu înțeleg că în primă instanță, are loc o încărcare de întreținere, apoi urmează încărcarea rapidă (1C), ulterior survenind o nouă încărcare de întreținere. În realitate, din teste, eu am observat că în prima clipă  ampermetrul indică 800mA, apoi se trece foarte rapid la o intensitate de 100-200mA pentru câteva minute bune, apoi indicația era

de 200-700-800mA, iar încărcarea nu s-a mai oprit, în condițiile descrise mai sus (de temperatură a acumulatorului măsurată cu un multimetru, de timp de încărcare).

 

La 29.07.2022 la 7:16, mihai 7 a spus:
  interval2=(interval-(interval-interval2b)/5);

Pentru o valoare inițială a  interval2=500, rezultă o nouă valoare  interval2= (1000 -(1000-500)/5)=900. După codul sursă, aceasta ar fi formula pentru a rezulta o valoare a interval2 specifică încărcării trickle - de întreținere (în primele 10 minute și ultimele 15 minute).

 

Ce credeți, codul pare corect în raport cu constatările practice? Vă mulțumesc!

Link spre comentariu

Salut Mihai, speram ca printre colegii care lucreaza cu Arduino sa raspunda cineva. Eu nu lucrez cu Arduino, insa ce inteleg este ca sursa de curent constsnt (construita in jurul lui Q1 si un LED rosu neaparat) este controlata doar ON-OFF, nu exista posibilitatea de ajustare a curentului din iesirea care controleaza Q2/Q1. Acest ON-OFF se face pe baza citirii analogice a tensiunii pe acumulator.

 

Acuma, la fiecare proiect ai nevoie sa validezi ca merge inainte sa faci orice modificare. Deci, codul original si configuratia originala. Singura modificare posibila este curentul, dupa cum e explicat in proiectul original. 

Link spre comentariu

Mihai, parerea mea este ca acest soft este scris 'cu picioarele', de genul "asa NU!".
Este foarte greu de urmarit. Din cauza asta nu cred ca intervine prea multa lume.
Poate gasesti altceva pe github ca sa incerci.
Banuiesc ca este o schema clasica de comanda a incarcarii.
 

Link spre comentariu

N-am urmărit îndeaproape subiectul deci ceea ce spun poate nu este relevant .

Atrag totuși atenția că metoda de detectare a sfârșitului încărcării prin depistarea ușoarei scăderi a tensiunii (NDV - negative delta voltage) funcționează doar la curenți de încărcare de peste 0.5C . De asemenea ea lucrează mult mai prost la NiMH față de NiCd și, în fine, cu cît sunt mai multe celule în serie cu atât e mai nesigură (nu toate celulele prezintă scăderea simultan).  

Link spre comentariu
Acum 13 ore, UDAR a spus:

(NDV - negative delta voltage) funcționează doar la curenți de încărcare de peste 0.5C

După cum spuneam mai sus, încărcarea acumulatorului începe cu o încărcare de întreținere (100-200mA) și abia apoi continuă cu 700-800mA (1C). Întrebarea mea este: să folosesc 100-200mA pentru început, și să aștept să ajungă la 800mA (1C) sau să setez o intensitate mai mare pentru prima fază ( în loc de 100-200mA, să setez o intensitate mai mare de 500mA)?

  

Acum 14 ore, Mircea a spus:

Salut Mihai, speram ca printre colegii care lucreaza cu Arduino sa raspunda cineva.

  Vreau să vă întreb, dacă intensitatea la încărcare variază cu ritmicitate între anumite limite (100-200mA; 300-500-700-800mA), mai poate fi vorba de încărcare în curent constant, sau e o eroare de cod? Menționez că încărcarea se face în impulsuri, așa cum se poate observa din filmulețul atașat de autor.

  

Acum 14 ore, Liviu.Mihaiu a spus:

Mihai, parerea mea este ca acest soft este scris 'cu picioarele', de genul "asa NU!"

 

Poate ar fi trebuit să aștept mai multe păreri înainte să proiectez un cablaj în Kicad, să-l corodez și să amplasez componentele pe acesta. Acum că am făcut aceste demersuri, voi mai face teste, în  speranța că este totuși funcțional (mai ales că la testele cu Arduino uno îmi întrerupea încărcarea).

Mulțumesc!

Editat de mihai 7
Link spre comentariu

Salut Mihai.

 

Nu vad in cod (repet, nu programez pentru Arduino) unde face impulsurile. Sincer, ma asteptam sa vad un PWM acolo, si atunci se putea varia curentul. Daca ma insel, si iesirea este modulata, scuze. 

 

Da, daca iesirea e modulata tot se poate numi curent constant, pe perioadele respective.

 

PS: nu te supara pe ce zic colegii, n-are cum sa nu functioneze. 

Link spre comentariu

pur informativ...

M-a preocupat și pe mine acest subiect, construisem un montaj cu care și încărcam și descărcam cu curent constant și trimiteam pe serial cu arduino datele ca să generez niște grafice ca să văd de fapt ce se întâmplă.

Din constatările mele cea mai sigură metodă de detecție a finalizării încărcării, este cea termică. Cu măsurări la intervale egale de 30secunde sau 1 minut și cu oprirea încărcării dacă temperaturile la intervale de 1 minut diferă cu peste 1 sau 1,5 grade, nu mai știu exact. Cu ignorarea pantei de la pornirea încărcării când evident e o creștere mai rapidă a temperaturii. Din păcate detecția termică e mai nepractică datorită necesității unui contact mecanic ferm între senzor și  acumulator. Dar este singura metodă ce nu dă greș, temperatura crește lin fără oscilații mari cum este tensiunea de la borne, care este influențată atât de calitatea ADC cât și de pulsurile de încărcare.

Detecția DeltaV sună frumos, dar nu mereu o și prinde, caz în care se duce bine în overcharge, fiind necesare celelalte metode de rezervă precum over time sau temperature cut off care tot necesită senzor. Pentru time out, e necesar setarea înaintea încărcării a capacității acumulatorului ca arduino să poată calcula timpul limită funcție și de curentul de încărcare. Mă rog, asta ipotetic u un alt soft nu cu ce ai postat. Pentru o pantă negativă Delta mai pronunțată trebuie o încărcare cu un curent cât mai mare. 1C e preferabil. Cu 0,5C un arduino o s-o prindă spre niciodată.

Până la urmă am renunțat, mă limitez la a folosi un Liitokala care are și discharge.

 

Aici curent de încărcare 1,5A pe un acumulator Sanyo-Eneloop de 2000mA. Curba orange este temperatura, albastru tensiunea.

1-5-A-Sanyo-eneloop.jpg

Link spre comentariu

Domnule @x_dadu, m-am lămurit, detecția DeltaV nu pare să fie cea mai bună metodă...

Apoi, mai am o rugăminte: ar putea cineva să modifice programul italianului pentru ca încărcarea să fie oprită după 1 oră de la inițierea procesului de încărcare (curentul de încărcare l-aș stabili eu, prin măsurători inițiale)? Sau să introducă oprirea prin detecția temperaturii - folosind senzorul LM335? (Aș vrea să folosesc configurația  actuală, montajul actual, cu Attiny85). Vă mulțumesc foarte mult!

Editat de mihai 7
Link spre comentariu

Am încercat să fac eu modificările pe care le-am indicat mai sus, după cum se vede în codul de mai jos:

 

/*
 
NiMh Charger 0.9
with AtTiny85 @ 1Mhz
by Luca Soltoggio
10/03/2012 - 20/04/2012
 
Use negative deltaV to determine end of charge.
Suitable for NiMh and NiCD battery pack.
Default is for 6 cells 2500mAh.
Need some hardware/software adjustment for changing current / cells number
See http://arduinoelettronica.wordpress.com/
 
*/
float cutoffTemperatureC =35;     //maximum battery temperature that should not be exceeded (in degrees C) 35
long cutoffTime = 20000;     //maximum charge time of 13 hours that should not be exceeded 46800000
long milliscutoff;
 float rawvoltage;
 float millivolts;
 float celsius;
 float kelvin;
int outputPin_2= A5;
const int inputPin = A1;
const int outputPin = 7;
 
const int numReadings = 30; // number of analog read before checking battery status
const int multi = 1614; // multi coefficent for obtaining millivolts from analogread
 
long interval = 1000;     // interval for pulse charging and analog read - don't change this
long interval2 = 800;     // pulse off interval - you can adjust power with this. Use 100 for 2-4Ah battery packs, 500 for 1-2Ah battery pack
long interval2b=interval2;
long previousMillis,currentMillis,currentMillis2,trickleMillis = 0;
 
unsigned int readingtemp;
unsigned int total = 0;
unsigned int average,medium,maxmedium = 0;
 
boolean executed,endcharge,trickle=false;  // booleans for controlling various activities (for example "end of charge")
 
unsigned int myarray [7];   // array for keeping last 7 readings
int index,i = 0;

 
void setup()
{
  Serial.begin(9600);
  pinMode(7,OUTPUT);
  pinMode(A5, OUTPUT);
  
  // Some readings for initial check
  for (i=0;i<10;i++) {
    readingtemp = analogRead(inputPin);
    total=total+readingtemp;
  }
  average = (((float)total / 1023.0) * (float)multi) / 10.0 + 0.5;
  if (average<=70) endcharge=true;  // If there is no battery, end charge
  Serial.println(average);
 
  total=0;
  average=0;
}
 
void pusharray() {
  // push the array
  for (i=0;i<=5;++i) {
    myarray[i]=myarray[i+1];
   }
  myarray[6]=average;
}
 
void voltread() {
  readingtemp = analogRead(inputPin);  // read analog input
  total= total + readingtemp;
  index++;
 
  // if numReadings reached, calculate the average
  if (index==numReadings) {
    index=0;
    average = (((float)total / 1023.0) * (float)multi) / numReadings + 0.5;
    if (average<=70) endcharge=true;  // stop charge if battery is detached
    total=0;
    pusharray(); // insert new average in array
    medium=(float)(myarray[6]+myarray[5]+myarray[4]+myarray[3]+myarray[2]+myarray[1]+myarray[0])/7.0+0.5; // calculate the average of the last 7 readings
    if (medium>maxmedium) maxmedium=medium; // save the value of highest medium in "maxmedium"
    Serial.print(medium);
    Serial.print(",");
    Serial.print(maxmedium);
    Serial.print(",");
    Serial.println(myarray[6]);
    
    if ( ((medium+1) < maxmedium) && ((millis()/60000)>=11) ) {  // if battery charged (average voltage is dropped 0.02v), but not in the firsts 11 mintues
      if (!trickle) trickleMillis=millis(); // start trickle timer
      trickle=true; // enter final trickle charging mode
      if (((millis()/60000)<=15) || (milliscutoff > cutoffTime) || (celsius > cutoffTemperatureC) ) endcharge=true; // if battery is charged in the firts 15 minutes, don't apply trickle charge (maybe was yet charged)
    }
  }
}

 void temperatureread()  {
 rawvoltage= analogRead(outputPin);
 millivolts= (rawvoltage*5000) /1024;
 kelvin= (millivolts/10);
 celsius= kelvin - 273; 
 Serial.println("Temp");
  Serial.println(celsius);
  delay(1000);
 }
 
void loop() {

temperatureread();
  milliscutoff=millis(); 
  currentMillis = millis();
 
 
  // executed every "interval" millis
  if(currentMillis - previousMillis > interval) {
    voltread();  // call reading and check volts function
    digitalWrite(outputPin,LOW);  // temporaly stop charging
    previousMillis = currentMillis;
    executed=false;  // boolean for setting and checking if has been yet turned ON charge
 
    // in the firsts 10 minutes and in the endings 15 minutes do a trickle charge (change OFF interval)
    if ( ( (trickle) && (((millis()-trickleMillis)/60000)<15) ) || ((millis()/60000)<10) ) {
      interval2=(interval-(interval-interval2b)/5);
    } else if ((millis()/60000)>=10) interval2=interval2b;  // after initial trickle charghe set back right time
    if ( (trickle) && (((millis()-trickleMillis)/60000)>=15) || (milliscutoff > cutoffTime)|| (celsius > cutoffTemperatureC) ) endcharge=true;  // if final trickle charge end, end charge
  }
 
  currentMillis2 = millis();
 
  // executed "interval2" millis after turning OFF charge
  if ((currentMillis2 - previousMillis > interval2) && (!executed)) {
    executed=true;
    if (!endcharge) {
      digitalWrite(outputPin,HIGH); // if battery is not charged, re-enable charging
    }
  }
 
}

 

Am folosit senzorul de temperatura LM 335, cu 2k2 legătură între Out și  5V dar am obținut rezultate nesatisfăcătoare, după cum se vede din afișarea serială:

Captur-de-ecran-la-2022-08-04-17-23-06.p

Obțin temperaturi negative, care oscilează foarte mult fără ca temperatura să se modifice.

 

Am facut modificări în următoarele puncte din cod (pentru evidențiere):

 if ( ((medium+1) < maxmedium) && ((millis()/60000)>=11) ) {  // if battery charged (average voltage is dropped 0.02v), but not in the firsts 11 mintues
      if (!trickle) trickleMillis=millis(); // start trickle timer
      trickle=true; // enter final trickle charging mode
      if (((millis()/60000)<=15) || (milliscutoff > cutoffTime) || (celsius > cutoffTemperatureC) ) endcharge=true; // if battery is charged in the firts 15 minutes, don't apply trickle charge (maybe was yet charged)

 

  // in the firsts 10 minutes and in the endings 15 minutes do a trickle charge (change OFF interval)
    if ( ( (trickle) && (((millis()-trickleMillis)/60000)<15) ) || ((millis()/60000)<10) ) {
      interval2=(interval-(interval-interval2b)/5);
    } else if ((millis()/60000)>=10) interval2=interval2b;  // after initial trickle charghe set back right time
    if ( (trickle) && (((millis()-trickleMillis)/60000)>=15) || (milliscutoff > cutoffTime)|| (celsius > cutoffTemperatureC) ) endcharge=true;  // if final trickle charge end, end charge

 

Vă rog, aștept sugestiile dumneavoastră. Vă mulțumesc!

Editat de mihai 7
Link spre comentariu

Ma bine lasi incarcarea la curent constant la o zecime din capacitate.
Eventual folosesti arduino pentru a masura temperatura.
Nu te juca, ca sa nu ajungi sa faci foc.
Ti-am spus ca softul este o prostioara.
Te poti juca cu el, dar pune un bec in loc de acumulator,
sau ,mai bine, un condesator de capacitate mare in paralel cu un resistor si un Zener (ca sa poti simula deltaV negativ la terminarea incarcarii).



 

 

Editat de Vizitator
Link spre comentariu
Acum 54 minute, mihai 7 a spus:
rawvoltage= analogRead(outputPin);

 

Am descoperit de ce indicatia de temperatură arăta așa:  mai sus trebuia să scriu rawvoltage=analogRead(outputPin_2) (mie îmi citea tensiunea pe pinul 7 arduino, nu pe A5).

Acum 14 minute, Liviu.Mihaiu a spus:

Ma bine lasi incarcarea la curent constant la o zecime din capacitate.
Eventual folosesti arduino pentru a masura temperatura.
Nu te juca, ca sa nu ajungi sa faci foc.

 Domnule @Liviu.Mihaiu, avertismentul dvs., precum și multiplele eșecuri de până acum, mă cam sperie. Aș dori un soft pentru Attiny85, care să oprească încărcarea dacă timpul a depășit 13 ore sau temperatura este mai mare de 35 grade celsius. Înțeleg că-mi recomandați să renunț cu totul la softul italianului, sau să inserez modificările mele în acest soft?

Link spre comentariu

Sunt si alte softuri care incearca sa supevizeze incarcarea unui NiMh.
Mai cauta pe net. Pe GitHub eventual.
Softul asta este scris tare aiurea. Poate omul a vrut sa spuna ceva util.
Nu ai cum sa intelegi prea usor ce este acolo.
Si , asa cu ai aflat si mai sus, nu te poti baza numai pe evenimentul "deltaV negativ". Pentru ca poti sa-l pierzi.



 

Link spre comentariu

Cu LM35/335 folosești tot ADC pentru care trebuiesc diverse artificii software ca să ai o afișare foarte stabilă. Eu am folosit un senzor digital DS18B20 care mai mult de 0,1 grade nu are oscilare.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări