Arduino, pomoc s pwm regulací

Raspberry, Arduino, Mini-PC a další

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

Arduino, pomoc s pwm regulací

#1 Příspěvek od volente »

Naprogramoval jsem arduino jako spinací regulator pro FV panel. Pro Pb baterii stačí, ale budu zároveň nabíjet LiIon baterii a tam bych potřeboval regulovat nabíjecí proud a ke konci nabíjení napětí. Potřebuji nakopnout správným směrem jak na tuto regulaci. Prostě nevím jak mu říct Teď drž proud na max. 2.5A. Ta ůměra analogRead a analogWrite.
Jestli mě teda rozumíte. Tady je můj výtvor.

int voltagepb = A0; //mereni napeti Li baterie
int voltageli = A1; //mereni napeti Pb baterie
int voltagefv = A2; //mereni napeti panelu
int currentli = A3; //mereni proudu pro Li baterie
int IRFli = 3; //MOSFET nabijeni Li
int IRFpb = 6; //spinac nabijeni Pb
int IRFliv = 7; //MOSFET zateze Li
int IRFpbv = 8; //MOSFET zateze Pb
int Vpb = 0;
int Vli = 0;
int Vfv = 0;
int Ili = 0;
void setup()
{
Serial.begin(9600);
pinMode(IRFpb, OUTPUT); //vystupy pro ULM2003 spinac P-MOSFET
pinMode(IRFli, OUTPUT);
pinMode(IRFliv, OUTPUT);
pinMode(IRFpbv, OUTPUT);
}
void loop()
{
int Vpb=analogRead(voltagepb); //napeti Pb baterie
int Vli=analogRead(voltageli); //napeti Li baterie
int Vfv=analogRead(voltagefv); //napeti FV panelu
int Ili=analogRead(currentli); //proud do Li baterie
float voltpb = Vpb * ((5.0/1023.0)*6.8); //prepocet podle delice napeti
float voltli = Vli * ((5.0/1023.0)*6.8);
float voltfv = Vfv * ((5.0/1023.0)*6.8);
float ampli = (.19 * (Ili) -25) / 1000; //pro ACS712 20A ???
Serial.println(voltli);
Serial.println(voltpb);
Serial.println(voltfv);
Serial.println(ampli);

if((voltfv > 14.40)&&(voltli < 12.40))
{
digitalWrite(IRFli, HIGH);
}
if((voltfv > 14.40)&&(voltpb < 12.60))
{
digitalWrite(IRFpb, HIGH);
}
if((voltli > 12.55)||(voltfv < 14.00))
{
digitalWrite(IRFli, LOW);
}
if((voltpb > 13.60)||(voltfv < 14.00))
{
digitalWrite(IRFpb, LOW);
}
if(voltpb > 12.10)
{
digitalWrite(IRFpbv, HIGH);
}
if(voltli > 11.60)
{
digitalWrite(IRFliv, HIGH);
}
if(voltpb < 11.50)
{
digitalWrite(IRFpbv, LOW);
}
if(voltli < 11.10);
{
digitalWrite(IRFliv, LOW);
}

delay(1000);
}
Naposledy upravil(a) volente dne 02 pro 2015, 21:32, celkem upraveno 2 x.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#2 Příspěvek od Cowley »

Nejsem si jistej se zapisem."or". Nema tam byt || dve svisle?

Edit: || autorem dodatecne vlozeny ve 21:32

A AnalogWrite z vystupu bude primo krmit nejakou soucastku ve vnejsim obvodu? Bude na to ta soucastka pripravena?

A ty vypocty, co potom zobrazujes jsou spravne?

Nejak mi nesedi ty IF podminky, nenavazuji na sebe. Ma to byt jisty druh Hystereze?
Naposledy upravil(a) Cowley dne 02 pro 2015, 21:39, celkem upraveno 2 x.
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#3 Příspěvek od volente »

funguje i s "or", stejně jako "and" místo && .
Proud nevim, ještě jsem netestoval, měření můžu předělat.
Napětí zobrazuje správně i správně reaguje.
na výstupech bude pole darlingtonů ULN2003, a na jeho výstupech MOSFETy.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#4 Příspěvek od Cowley »

A co ten radek s postupnym navysovanim ampli?

Ze je pred i za rovnitkem? A z ceho se vypocte pri prvnim vypoctu, kdyz se ma uz vlastne k nemu neco zmereneho pripocitat? Vychozi hodnotu nema?

Co tim radkem zamyslis?

Edit: radek je jiz ve 21:37 autorem upraven.
Naposledy upravil(a) Cowley dne 02 pro 2015, 21:37, celkem upraveno 4 x.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#5 Příspěvek od Cowley »

https://www.arduino.cc/en/Reference/Boolean

Naucil jsem se zapisovat takto, s "or" jsem to nezkousel :)
Otazkou je, co na to prekladac.
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#6 Příspěvek od volente »

Ten řádek ma chybu v tom že se něco pričítá, ale to teď není podstatné. To měřění přepíšu podle použitého způsobu. Ten jsem odněkud převzal více méně kvůli těm konstantám pro čidlo. Ani nevím jestli je funkční. Ovšem to není co jsem chtěl že?
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#7 Příspěvek od Cowley »

Sorry, vsechno souvisi se vsim.

Nemam kristalovou kouli a z podkladu, ktere nabizis, neni jasne, jak vlastne chces regulovat.

Jestli merit proud a po prekroceni urcite hranice zastavit nabijeni nebo bude vne arduino nejaky specialni obvod, ktery bude pracovat podle toho, co arduino zmeri a vypocte?
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#8 Příspěvek od volente »

Proste chci na Li nabijeni udrzovat konstatni proud do napeti 12,50, a potom dobijet kostantnim napetim 12.60. Proste charakteristika nabijeni CC - CV.
Tan zapis programu jsem opravil. Funkcnost mereni proudu je ted nepodstatna.
Nechci po nikom aby mi psal program, jen zapis te spojitosti .
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#9 Příspěvek od Cowley »

Neni prece problem v tom vyslat AnalogWrite na dany vystup s hodnotou 0 - 255 po te co se neco zmeri a vypocte. Otazkou zustava, jak rychle hodnoty obmenovat aby to cele necyklovalo "nahoru dolu".

Zacit od 0, zmerit proud, vyhodnotit, pridat po jedne nebo po deseti, zase zmerit a kdyz proud preleze limit, tak ubrat a tak porad dokola. No a s dalsi podminkou kontrolovat i to vlastni napeti.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#10 Příspěvek od Cowley »

volente píše:...Funkcnost mereni proudu je ted nepodstatna.
Nechci po nikom aby mi psal program, jen zapis te spojitosti .


Asi jsem natvrdlej nebo ospalej, ale jak muze byt nepodstatna, kdyz ma hlidat velikost proudu? :)

A co zjisti, jakej proud tece do baterky pri AnalogWrite 255, coz je vlastne 100% PWM, nebo-li naprimo...?
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#11 Příspěvek od volente »

Psal jsem TED nepodstatne. Samozrejme to musi byt prvni vec, ktera musi v realu fungovat, a to docela presne. Jinak jsi me ted nakopl asi spravnym smerem, jen jsem myslel ze tu hodnotu omezeni dam primo do podminky.
Diky

No ze dvou 250Wp panelu do male asi 20Ah baterky by to asi naprimo dlouho nevydrzela.
O olovo strach nemam.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#12 Příspěvek od Cowley »

Tak dej pak vedet...

Dobjou :)
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#13 Příspěvek od volente »

Může mě prosím někdo napsat těch pár řádků programu, aby byla spojitost mezi pwm a naměřenými hodnotami, stále se mi nedaří.
Potřebuji se od něčeho odpíchnout.
Děkuji
Uživatelský avatar
volente
Příspěvky: 172
Registrován: 18 lis 2015, 00:00
Bydliště: Brno-venkov

#14 Příspěvek od volente »

Tak jsem to vytvoril takto:

#include <PWM.h>

//PWM regulace nabijeni Li baterie.
float voltpb=0;
float voltli=0;
float voltfv=0;
float ampli=0;
float adjA=0;
float sample1=0;
float sample2=0;
float sample3=0;
float sample4=0;
float sample5=0;

int IRFli = 3; //MOSFET nabijeni Li
int IRFpb = 6; //MOSFET nabijeni Pb
int IRFliv = 7; //MOSFET zateze Li
int IRFpbv = 8; //MOSFET zateze Pb

int pwm = 0;
int fadeAmount = 5;
int32_t frequency = 35;

void setup()
{
Serial.begin(9600);
pinMode(IRFpb, OUTPUT); //vystupy pro ULM2003 spinac P-MOSFET
pinMode(IRFli, OUTPUT);
pinMode(IRFliv, OUTPUT);
pinMode(IRFpbv, OUTPUT);
InitTimersSafe();
bool success = SetPinFrequencySafe(IRFli, frequency);
}
void loop()
{
for(int i=0;i<150;i++)
{
sample1+=analogRead(A0);
sample2+=analogRead(A1);
sample3+=analogRead(A2);
sample4+=analogRead(A3);
sample5+=analogRead(A4);
delay(4);
}
sample1=sample1/150;
sample2=sample2/150;
sample3=sample3/150;
sample4=sample4/150;
sample5=sample5/150;


voltpb = (sample1 * (5.0/1023.0)*8.38); //prepocet podle delice napeti
voltli = (sample2 * (5.0/1023.0)*8.38);
voltfv = (sample3 * (5.0/1023.0)*8.38);
ampli = ((sample4-513)*47)/1000; //pro ACS712 20A ???
adjA = (sample5 * (5.0/1023.0)*2);
Serial.println(voltli);
Serial.println(voltpb);
Serial.println(voltfv);
Serial.println(ampli);
Serial.println(adjA);

//pwm=(sample4=sample5);
if((voltfv<voltli)||(voltli>12.58)||(ampli>5.00))
{
(pwm=0);
}

else if((voltfv>voltli)&&(voltli<12.50)&&(ampli<4.00))
{
(pwm=255);
}
else if((voltfv>voltli)&&(ampli>4.00)&&(ampli<4.10)&&(voltli<12.50))
{
(pwm=230);
}

else if((voltfv>voltli)&&(ampli>4.10)&&(ampli<4.20)&&(voltli<12,50))
{
(pwm=205);
}
else if((voltfv>voltli)&&(ampli>4.20)&&(ampli<4.30)&&(voltli<12,50))
{
(pwm=180);
}
else if((voltfv>voltli)&&(ampli>4.30)&&(ampli<4.40)&&(voltli<12,50))
{
(pwm=155);
}
else if((voltfv>voltli)&&(ampli>4.40)&&(ampli<4.50)&&(voltli<12,50))
{
(pwm=130);
}
else if((voltfv>voltli)&&(ampli>4.50)&&(ampli<4.60)&&(voltli<12,50))
{
(pwm=100);
}
else if((voltfv>voltli)&&(ampli>4.60)&&(ampli<4.70)&&(voltli<12,50))
{
(pwm=75);
}
else if((voltfv>voltli)&&(ampli>4.70)&&(ampli<4.80)&&(voltli<12,50))
{
(pwm=50);
}
else if((voltfv>voltli)&&(ampli>4.80)&&(ampli<4.90)&&(voltli<12,50))
{
(pwm=25);
}

analogWrite(IRFli, pwm);


}

Na stole to pokusne chodi, Uvidime jakou charakteristiku bto bude mit s baterii. Ale to uz se da prepsat podle potreby.
Jeste bych chtel v budoucnu zapracovat nastaveni proudu trimrem. Proto adjA.
Diky za pripominky.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#15 Příspěvek od Cowley »

Vypada to dobre...
Ja tam vidim:
1) nenavazuji ti jednotlive podminky na sebe (treba pro ampli==4.10 neplati zadna podminka atp., resp. beze zmeny)
2) je tam u hodne podminek parametru desetinna carka a ne tecka
Odpovědět

Zpět na „Miniaturní počítače (Arduino, Raspberry a další)“