Fórum témák

» Több friss téma
Cikkek » Nyolc lábbal AVR IV. rész
Nyolc lábbal AVR IV. rész
Szerző: Topi, ZsirosDani, idő: Dec 19, 2008, Olvasva: 45974, Oldal olvasási idő: kb. 5 perc
Lapozás: OK   2 / 5

Az előző részekben megismerkedhettünk már sok hardver elemével az ATtiny45-nek. A következő feladatot, többféle, akár ATtiny13-as processzorral is meg lehet valósítani, így nézzük most erre a processzorra.

Kilószámra lehet kapni a vacakabbnál vacakabb akkumulátor töltőket. Az ember ha véletlen valamelyik legkisebb is számít, vagy zöld-piros madárkás boltban vesz egy ilyen csoda készletet, akkor rendszerint az akku minősége legalább olyan "jó" mint a töltőé.

Igazából azidő alatt, amire azokat tervezik, tökéletesen is működik, ám a helytelen töltés szép lassan kinyírja az akksikat.

A NiMH töltéséről röviden

A korrekt töltést dT/dt vagy -dV/dt módszerrel szokás megvalósítani.
dT/dt: "Bonyolult", mert hőmérséklet változást kell az idő függvényében mérni. Illetve, nem is bonyolult, de kell hozzá hőmérő szenzor. Ennek ellenére, ez az egyik legjobb töltési módszer, ugyanis: A NiMH (Nickel Metal Hybrid) akkumulátorokban a töltési folyamat végefelé a belső kémiai szerkezetében az oxigén rekombinálódik, ami hőt fejleszt. Tehát, a hőmérséklet hirtelen megugrása jelzi a töltőnek a töltés végét.
-dV/dt: Ez már nem annyira bonyolult, ám ezzel a technikával csak cella szintű töltést lehet megvalósítani, ugyanis a töltés elve a töltőáram hiányában az adott időegység alatti feszültség visszaesés. Egy komolyabb, töltés-kisütés funkcióval rendelkező cellaszintű akkumulátortöltő már e módon tölt.

Töltés: A NiMH akkumulátort konstans árammal kell tölteni minden esetben! Míg a NiCd (Nickel Cadnium) akkumulátorokat még lehetett tölteni konstans feszültséggel is (bár nem szerették, de feltöltődtek), addig a NiMH akkumulátorokat már nem. A töltés annyit jelent, hogy x áramot "pumpálunk" bele a cellába. A töltési áram határozza meg a töltés idejét. Ezek alapján megkülönböztethetünk: Csepptöltést, Normál töltést (egy éjszakás töltés), Gyorstöltést és Ultra gyors töltést. A töltő áramot az akkumulátor névleges kapacitásához mérten kell beállítani. Az akku névleges kapacitását a szakirodalom C-vel jelöli. Figyelem, ez nem Coulomb!

Tehát, egy 1000mAh-ás akkumulátor esetében:
- Csepptöltés: 0,03-0,05C (0,05*1000mA = max. 50mA)
- Normál töltés: 0,1C (max. 100mA)
- Gyorstöltés: 0,3C (max. 300mA)
- Ultra gyors töltés: 1C (max. 1000mA)

Gyorstöltést és ultra gyors töltést csakis dT/dt által felügyelt töltőkészülékben szabad! (Nagyon, és hirtelen megugrik a hőmérséklet -> Bumm )

Apropó: Mi is az a mAh? A mAh (kis h-val) az akkumulátor névleges kapacitását jelenti (innen a C - Capacity. Névleges kapacitás: Nominal Capacity), azaz egy 2500mAh-ás akkumulátor 1órán keresztül képes 2,5A-t szolgáltatni.

Memória effektus: Ez a NiMH akkumulátorok egyik gusztustalan velejárója. Lényeg az, hogy a nem teljesen feltöltött akkumulátor sok töltés-kisütési ciklus után emlékszik arra a feltöltöttségi szintre, amire sokszor fel lett töltve, így szép lassan egyre kevésbé lehet feltölteni. Ez az akkumulátorhalálozási indok 99%-ban. Ha először csak pl. 90%-ára töltjük fel, és onnan terheljük, akkor a következő feltöltésnél a mindig 90%-ra "töltő töltőnk", csak a 90%, 90%-ára fogja feltölteni, és ez így a halálig.

A kis elmélet után, nézzük meg, mit csinál a mi processzoros automata töltőnk.

Töltőnk működése

A töltőnk konstans árammal dolgozik. A konstans áramot célszerű processzorral felügyelni, amennyiben annyira intelligensre akarjuk töltőnket építeni, hisz a töltés befejeztével célszerű lenne átállnia csepptöltésre. Ám ezzel elbonyolódik a dolog.

A fentiek miatt a kapcsolásba egy LM317T-t terveztem bele, ezzel állítjuk elő a konstans áramot. Ám, mivel az LM317 nem rendelkezik kikapcsolási funkcióval, így az ADJ lábát (tehát a referencia komparátor lábát) kapcsoljuk földre, ha ki akarjuk kapcsolni a töltő áramot. A töltés befejezése, a cellafeszültség elérésével történik. Ahhoz, hogy ez ne adjon fals értéket, és ne mondja a töltő nem feltöltött terheletlen akksira, hogy feltöltött, így a következő ciklikusság le beépítve:

1. Töltőáram bekapcsolása
2. Töltés 6mp-ig
3. Töltőáram ki, sönt bekapcsolása
4. 1mp söntölés
5. Sönt kikapcsolás, mérés, kiértékelés

Ezen lépések, még jót is tesznek az akkumulátornak, hogy töltés közben egy rövid kisütési fázisba vált a töltő. Ez egyfajta formázási szerepet is ellát. A sönt, pedig nem más, mint egy 60-120R körüli ellenállás, melyet akkor kapcsolunk be, ha a töltőáram már megszűnt.
Töltésnél cellánként legalább 1,41V-nak meg kell lennie, amint feltöltődött erre az akkumulátor, az jelzi a töltés befejezését is.

LED jelzései:

Piros: Nincs akkumulátor a töltőn, vagy az akkumulátor szakadt.
Sárga: Töltés folyamatban
Zöld: Töltés befejeződött.

A kész állapot egyfolytában ellenőrzött, tehát ha világít zölden, de közben bennthagyjuk és elkezd merülni az akksi, akkor ahogy ezt érzékeli, automatikusan visszaáll töltésre -> Bennthagyható a töltőben az akkumulátor.

Az áramkörünk nem valami bonyolult. Fontos, hogy ne ilyen-olyan kósza 5V-ot adjunk a processzornak. Ezesetben kivételesen szűrt és stabil, pontos 5V-ra van szükség a digitális rész táplálásához.


Kattints a képre, a nagyobb változathoz

A kész áramkört próbapanelen dobtam össze:

Miután összeépítettük, először csak a digitális résznek adjunk tápfeszültséget, (és ilyenkor programozzuk be) Majd utánna célszerű egy áramkorlátos tápegységgel kipróbálni.

Két alkatrész értéke rendkívül kritikus:

Az áramkorlátozó ellenállás: Az LM317 konstans áram módban úgy szabályzódik vissza, hogyha a soros ellenálláson 1.25V-nál több esik, akkor kapcsol ki -> csökken az áram. Ezért ennek az ellenállásnak az értéke az LM317 belső referenciája segítségével számolható:

R = 1.25V / I (ahol I a töltőáram, R a szükséges soros ellenállás)

Ezenfelül szükséges számolni a soros ellenállás teljesítményét is:

P = 1,25 * 0.1A = 0.125W -> 0,4-0,6W (0,1A a töltőáram, ez folyik keresztül az ellenálláson. P az eldisszipált teljesítmény)

Továbbá, az LM317 hűtéséről is esetleg gondoskodni kell:

P = ( U - Uf ) * I (Uf = terhelésen eső feszültség) Ami nem a terhelésen esik feszültség, az mind az LM317-en disszipálódik el, tehát (12V - 4*1,41V)*0,1A = 0,6W => Legalább 1,5W-al kell számolni. Ám ezt az LM317 még jócskán el tudja disszipálni hűtés nélkül csak a saját hűtőzászlóján.

Sönt értéke: A söntnek nem rövidzárnak kell lennie, hanem egyfajta műterhelésnek. Én igazából a fiókból elsőre előkerülő 100R körüli ellenállást választottam. A kisütőáramnak nem kell feleslegesen nagynak lennie, mert többet sütne ki, mint amennyit feltölt. Ahhoz kell ez az ellenállás, csak hogy ne egy terheletlen kapocsfeszültséget mérjünk. Max olyan 40-50mA-nek kell lennie. Maximálisan feltöltött akkumulátor 1,41V/cella. Tehát a 4 cella: 4*1,41 = 5,64. R = 5,64/0,05A = 112,8 -> 120R. Ám, ennek már huzal ellenállásnak kell lennie, ugyanis P=I^2*R = 0,3W, de ez jócskán 1-2W is lehet.

A többi alkatrész, pl. a terhelést kapcsoló FET sem kritikus. IRFZ44, IRFZ24/34, IRF540, IRF560, IRF610. Erre a funkcióra bármelyik jó. Sőt, bipoláris tranzisztort is használhatunk. Érdemes ezesetben valami darlington típust használni, pl. BD681.

A program:

  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. #define PIN_RED          PB1
  5. #define PIN_GRN          PB0
  6. #define SHT_DWN          PB3
  7. #define SHUNT            PB2
  8.  
  9.  
  10. #define RED_ON()         PORTB |=  (1<<PIN_RED)
  11. #define RED_OFF()        PORTB &= ~(1<<PIN_RED)
  12. #define GRN_ON()         PORTB |=  (1<<PIN_GRN)
  13. #define GRN_OFF()        PORTB &= ~(1<<PIN_GRN)
  14.  
  15. #define DO_SHTDOWN()     PORTB |=  (1<<SHT_DWN)
  16. #define DO_CHARGE()      PORTB &= ~(1<<SHT_DWN)
  17. #define SHUNT_ON()       PORTB |=  (1<<SHUNT)
  18. #define SHUNT_OFF()      PORTB &= ~(1<<SHUNT)
  19.  
  20.  
  21. #define CELL_NUM            4
  22. #define CELL_COMPLETED_V    CELL_NUM*1.41
  23. #define CELL_ERROR_V        CELL_NUM*1.78
  24.  
  25. const unsigned short CELL_COMPLETED_ADC     = 1024*CELL_COMPLETED_V/5/2;
  26. const unsigned short CELL_ERROR_MAX_ADC     = 1024*CELL_ERROR_V/5/2;
  27. const unsigned short CELL_ERROR_MIN_ADC     = 1024*1.42/5/2;
  28.  
  29. //-------------------------------------
  30. void m_delay_10ms(unsigned short val) {
  31. //-------------------------------------
  32.     while(val--) _delay_ms(10);
  33. }
  34.  
  35. //-------------------------------------
  36. void init() {
  37. //-------------------------------------
  38.     DDRB = (1<<PIN_RED)|(1<<PIN_GRN)|(1<<SHT_DWN);    //kimenetek
  39.  
  40.     //Init ADC
  41.     ADMUX = 0x00;
  42.     ADCSRA =  (1<<ADEN)
  43.            |  (0<<ADATE)
  44.            |  (0<<ADSC)
  45.            |  (1<<ADPS2)
  46.            |  (1<<ADPS1)
  47.            |  (1<<ADPS0)
  48.            ;
  49. }
  50.  
  51. //-------------------------------------
  52. unsigned short ADConvert(unsigned char channel) {
  53. //-------------------------------------
  54.     ADMUX &= ~(1<<MUX1|1<<MUX0);
  55.     ADMUX |= channel;
  56.     ADCSRA |= (1<<ADSC);
  57.     while(ADCSRA & (1<<ADSC));
  58.     return ADC;
  59. }
  60.  
  61. //-------------------------------------
  62. int main(void) {
  63. //-------------------------------------
  64. unsigned short adc;
  65.  
  66.     init();
  67.  
  68.     for(;;)  {
  69.         adc = ADConvert(2);    //mérés
  70.         if(adc>=CELL_ERROR_MAX_ADC || adc<CELL_ERROR_MIN_ADC) {
  71.             //ERROR LED
  72.             RED_ON();
  73.             GRN_OFF();
  74.         } else {
  75.             //Sárga, töltődik...
  76.             RED_ON();
  77.             GRN_ON();
  78.  
  79.             DO_CHARGE();        //töltés be
  80.             m_delay_10ms(600);    //6mp töltés
  81.             DO_SHTDOWN();        //töltés ki
  82.             m_delay_10ms(1);    //vár töltés ki-re
  83.  
  84.             SHUNT_ON();            //sönt be
  85.             m_delay_10ms(100);    //1mp sönt
  86.             adc = ADConvert(2);    //mérés
  87.             SHUNT_OFF();        //sönt ki
  88.  
  89.             while(adc>=CELL_COMPLETED_ADC && adc<CELL_ERROR_MAX_ADC) {
  90.                 DO_SHTDOWN();//töltés ki
  91.                 RED_OFF();
  92.                 GRN_ON();
  93.                 adc = ADConvert(2);
  94.                 m_delay_10ms(1);
  95.             }//Completed - While
  96.         }//Voltage Detect
  97.     }//for
  98. }

Letöltés: akkutolto.c

Más, nem 4-es AkkuPack töltéséhez csak a "CELL_NUM" nevű definíciót kell javítani, és automatikusan kalkulálódik az összes többi.

Nah gyerünk, vezéreljünk ki... Lapozz...


A cikk még nem ért véget, lapozz!
Következő: »»   2 / 5
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem