Sari la conținut
ELFORUM - Forumul electronistilor

Descărcare acumulatori NI-MH asistată de Arduino Uno


mihai 7

Postări Recomandate

Bună seara! După ce într-o postare anterioară am dezbătut realizarea unui încărcător pentru acumulatori NI-MH:

  https://www.elforum.info/topic/153778-încărcător-acumulatori-ni-mh-cu-arduino-uno/

acum aș dori să realizez și un montaj pentru a descărca acumulatorii până la limita de 0.9 V/ element, cu ajutorul microcontrolerului Attiny85. Pentru teste folosesc o placă Arduino Uno.

Proiectul este luat de la adresa:

https://forum.arduino.cc/t/arduino-based-opensource-nimh-battery-charger/90201

Codul este următorul:


const int inputPin = A5;
const int outputPin = 7;
float valueProbe;     //variable to store the value of analogPinOne
float voltageProbe;     //calculated voltage at analogPinOne


void setup()
{
  Serial.begin(9600);
  pinMode(outputPin, OUTPUT); 
  pinMode(inputPin, INPUT);
}
 
void loop() {
        
   valueProbe = analogRead(inputPin);  // read analog input
   voltageProbe = (valueProbe*5000*326)/102300;     //calculate voltage at probe one in milliVolts
   Serial.print("Voltage Probe (mV): ");     //display voltage at probe one
   Serial.println(voltageProbe);
   delay(1000);
   
    if (voltageProbe < 900)
     digitalWrite(outputPin,LOW);
    else if (voltageProbe > 900) 
      digitalWrite(outputPin,HIGH);
     else if (voltageProbe < 1700)
      digitalWrite(outputPin,HIGH);  
     else if (voltageProbe > 1700)
      digitalWrite(outputPin,LOW);      
      else if (voltageProbe < 6300)
      digitalWrite(outputPin, LOW);     
      else if (voltageProbe > 6300)
      digitalWrite(outputPin,HIGH);
      else if (voltageProbe < 10000) 
      digitalWrite(outputPin,HIGH);
      else 
      digitalWrite(outputPin, LOW);
  }

 

 

Montajul are următoarea schemă:

IMG-0300.jpg

 

După primele teste, lucrurile nu sunt așa cum m-am așteptat. Montajul funcționează, am conectat atât un acumulator de 1.2V, cât și unul de 8,4V și ledul se aprinde, doar că atunci când rezistenta Rd - rezistența de descărcare - (cu valaorea de 5 sau 10 ohmi pentru acumulatorul de 1.2V) este conectată, am oscilații mari ale tensiunii măsurate de Arduino, iar led-ul bineînțeles se aprinde și se stinge, apoi iar se aprinde...

Tensiunea măsurată în terminal arată cam așa:

 

Captur-de-ecran-la-2022-08-19-00-40-11.p

 

Cum aș putea obține o indicație liniară a tensiunii acumulatorului (în fapt, tensiunea pe bornele acumulatorului, măsurată cu multimetrul, nu scade)? Softul este în regulă? Dar schema electronică este în regulă? Menționez că montajul este momentan pe breadboard, dar am impresia că nu de acolo se trage (toată) problema. Cu ajutorul rezistențelor de 33k și 15k am realizat un divizor de tensiune, care scade tensiunea înregistrată de Arduino de 3.26 ori (am folosit acest raport în formula  de calcul a tensiunii afișată în terminal, pentru ca Arduino să afișeze aproximativ tensiunea reală). Vă mulțumesc!

 

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

Top autori în acest subiect

  • mihai 7

    30

  • nico_2010

    13

  • Mircea

    8

  • dumitrumy

    5

Top autori în acest subiect

Imagini postate

Pentru inceput, monteaza dupa divizor un buffer cu MCP601 (spre exemplu) si vezi comportamentul montajului.

In orice caz, te-ai abatut de la proiectul initial, care era gandit pentru descarcarea unei singure celule.

Link spre comentariu

Domnule @nico_2010, ce alte circuite integrate pot folosi în locul lui MCP601 (mai uzuale, pe care le-aș putea găsi prin componentele pe care le am deja)?

Acum 2 ore, nico_2010 a spus:

monteaza dupa divizor

"După divizor" înseamnă între divizor și intrarea Arduino?

Care ar fi schema buffer-ului, cum se adaugă amplificatorul operațional în circuitul meu?

Mulțumesc!

Editat de mihai 7
Link spre comentariu
Acum 41 minute, mihai 7 a spus:

Domnule @nico_2010, ce alte circuite integrate pot folosi în locul lui MCP601 (mai uzuale, pe care le-aș putea găsi prin componentele pe care le am deja)?

"După divizor" înseamnă între divizor și intrarea Arduino?

Care ar fi schema buffer-ului, cum se adaugă amplificatorul operațional în circuitul meu?

Mulțumesc!

MCP601 este un opamp uzual si cred ca ar putea fi inlocuit cu LM358 (dar nu bag mana in foc pentru asta, sunt operationale cu caracteristici foarte diferite), dar poti sa incerci si cu uA741, sau cu TL071/081/061 (astea NU!). Functie de intervalul de tensiune aplicat la intrarea in operational s-ar putea ca integratele mentionate de mine (cu exceptia MCP601) sa nu functioneze.

 

Schema solicitata, cu mentiunea ca divizorul 33k/15k este cel din schema postata de tine.

 

                                                                                     image.thumb.png.581f972c2f720951f3b375fe4daaa596.png

 

L.E.: Cauta printre piesele pe care le ai operationale care permit si alimentarea unipolara, cele cu alimentare exclusiv bipolara ar putea sa-ti faca greutati. 

Link spre comentariu

Merge și MCP601 și LM358 cu condiția să nu depășim 3,8V (respectiv 3,5V) tensiune de intrare (egală, desigur, cu cea de ieșire în schema noastră).  Ca să putem exploata întreg domeniul (0...5V) trebuie un OpAmp de tip RRIO ( Rail-to-rail Input and Output ), de pildă MCP6001.

Am un comentariu la folosirea IRFZ44 cu tensiune de comandă în poartă de (cel mult) 5V. Unele exemplare, în anumite condiții, s-ar putea să nu se deschidă destul. Totuși, statistic, ar trebui să meargă.

Și, în fine, legat de cod. Nu mă pricep la Arduino dar principiile sunt aceleași - ar trebui ca tensiunea pe baterie să fie măsurată de mai multe ori și apoi făcută media. Asta ar elimina în mare măsură influența zgomotului.

Link spre comentariu

 

Salut. Candva am facut si eu soft pentru un tester, partea de conectare si descarcare sarcina este mai jos. Functioneaza impecabil si acum, dupa multi ani. 

ADC CURENT a fost conectat direct la pinul pic-ului, nu au fost probleme de citire. 

Exista si varianta cu 4 canale, in loc de relee am pus mos-uri, la fel, functioneaza impecabil cu baterii de pana la 7.6 volti (banuiesc ca am pus si niste divizoare pe acolo)

 

image.thumb.png.82e8ea2646bf9754f6c8c001b7c01f0e.png

Editat de costi002
Link spre comentariu

 

Cu LM 358 montajul se comportă la fel ca în descrierea de mai sus (pentru un acumulator de 1.2V), și tensiunea de intrare nu depășește 3.5 V.

Editat de mihai 7
Link spre comentariu

Cred ca ai o problema si cu schita. De ce spun asta?

Pai, spre exemplu:

else if (voltageProbe < 1700)
      digitalWrite(outputPin,HIGH);  
     else if (voltageProbe > 1700)

Si daca volatgeProbe este egal cu 1700, ce se intampla? La fel si in celelalte cazuri. Cred ca ar fi fost mai corect ceva de genul:

else if (voltageProbe <= 1699.0)
      digitalWrite(outputPin,HIGH);  
     else if (voltageProbe > 1700.0)

Oricum 1 mV va fi greu decelabil, avand in vedere ca 1LSB = 4.88mV, iar erorile pot trece cu usurinta de 2LSB!

In alta ordine de idei, corect ar fi in loc de :

voltageProbe = (valueProbe*5000*326)/102300;

sa scrii:

voltageProbe = (valueProbe*5000*326)/102400;

pentru ca sunt 1024 de valori pe care le poate livra ADC, intre 0x00 si 0x3FF.

Ai decuplat cu ceva tensiunea de alimentare a montajului? Un condensator de 10uF si unul de 100n ar putea face diferenta.

Link spre comentariu
Acum 12 ore, mihai 7 a spus:
if (voltageProbe < 900)
     digitalWrite(outputPin,LOW);
    else if (voltageProbe > 900) 
      digitalWrite(outputPin,HIGH);
     else if (voltageProbe < 1700)
      digitalWrite(outputPin,HIGH);  
     else if (voltageProbe > 1700)
      digitalWrite(outputPin,LOW);      
      else if (voltageProbe < 6300)
      digitalWrite(outputPin, LOW);     
      else if (voltageProbe > 6300)
      digitalWrite(outputPin,HIGH);
      else if (voltageProbe < 10000) 
      digitalWrite(outputPin,HIGH);
      else 
      digitalWrite(outputPin, LOW);

Bucata asta de cod este tare ciudata.
Sunt numai doua if-uri care conteaza. if<900 si if>900. Restul de cod se executa doar daca V=900 (adica if<1700) :)



 

Link spre comentariu

Am alimentat separat, am folosit ca buffer LM 358, am decuplat cu 10 microfarazi și 100 nanofarazi și am "stabilizat" firele de legătură din breadboad (trebuie să realizez montajul pe cablaj de test), am înlocuit

 

voltageProbe = (valueProbe*5000*326)/102300;

cu

voltageProbe = (valueProbe*5000*326)/102400;

 obținând următoarele tensiuni în terminal:

Captur-de-ecran-la-2022-08-19-14-15-58.p

 

Acum, ledul nu se mai stinge, însă problema este că tensiunile măsurate diferă de tensiune pe acumulator (1.3 V). 

Editat de mihai 7
Link spre comentariu

Domnule @Liviu.Mihaiu, intenția mea a fost să pot "descărca", folosind același cod, atât un acumulator de 1.2V, cât și unul de 8.4 V. Îmi puteți sugera un cod pentru a realiza această cerință, mi-e teamă ca eu m-am încurcat.

Link spre comentariu
1 oră în urmă, mihai 7 a spus:

atât un acumulator de 1.2V, cât și unul de 8.4 V.

In codul cu if-uri de mai sus este vorba de 4 domenii de tensiune.
Cate tipuri de acumulatoare vrei sa utilizezi ?
Oricum nu cred ca este corect asa. Adica sa deduci tipul de acumulator dupa voltaj. Si nici sa descarci acumulatoare inseriate.
 

Editat de Vizitator
Link spre comentariu

Dar daca totusi este corect, 
poti incerca ceva de genul (te las pe tine sa completezi/corectezi codul, nu am cum sa verific):
 

float Vi[4]={1.2, 2.4, 8.4, 13.2};	// patru tipuri de acumlator 
proc=75;				// 75% minim descarcare (asa am dedus din codul tau)
float Acc_V=0;				// voltajul nominal al acumulatorului de descarcat

setup()
{
  int i;
  print("detectare acumulator...");

  while(Acc_V==0)
  {

	// aici pui cod citire ADC

    for(i=0;i<4;i++)
    {
       if(voltageProbe<=Vi[i] && voltageProbe>=Vi[i]*proc/100)
       {
        Acc_V=Vi[i];			// am gasit tipul de acumulator
        break;
       }
    } 
  }
  print("acumulator de tipul: ");
  print(Acc_V);
  print(" V");

  Acc_V=Acc_V*1000;			// in milivolti

}

loop()
{
  // aici pui cod citire ADC

  if(voltageProbe==0)            // daca se scoate acumulatorul
    reset();		         // trebuie detectat tipul (voltajul) in caz ca urmeaza descarcarea altuia.

  if(voltageProbe>Acc_V*proc/100)
  {
    print("descarc. actual = ");
    print(voltageProbe);
    print(" mV");
    pin=HIGH;			// descarc
  }
  else  
  {
    print("descarcare terminta");
    pin=LOW;
  }
}

 

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