Vzhledem k tomu, že superkondenzátory (kondenzátory s kapacitou nad 1 F) jsou dostupné už několik roků, je s podivem, že prakticky nenajdete měřicí přístoje, které by s tím počítaly, a byly schopny je měřit. Ke konstrukci takového měřiče se Arduino velmi hodí.
Následující zjednodušená konstrukce je plná kompromisů a omezení, zaměřuje se na práci s „malými“ kapacitami superkondenzátorů, které asi najdou v amatérských podmínkách nejčastější použití. Cílem bylo vytvořit přístroj, který dokáže superkondenzátor nabít na definované napětí (zde pevně nastaveno na přibližně 2,5 V), vybít superkondenzátor na nízké napětí (zde pevně nastaveno na 0,2 V), formovat superkondenzátor udržováním konstantního napětí a to nejdůležitější, změřit jeho kapacitu. Měřič je určen výhradně k práci s jednotlivými superkondenzátory, ne se sadami v sériovém zapojení, pracuje s napětím 0 až 2,5 V. Pracuje také výhradně s pravými kondenzátory (double-layer capacitance), nikoli s pseudokondezátory nebo hybridními kondenzátory, které v sobě kombinují princip kondenzátoru a elektrochemické ukládání energie jako akumulátor.
Důvod, proč kapacitu superkondenátorů kontrolovat, je především v tom, že při sestavování do sad je kriticky důležité, aby všechny kondenzátory měly pokud možno stejné parametry, především kapacitu a samovybíjení. Jakékoli rozdíly mezi nimi se projeví na větší nutnosti sady balancovat a i u sad kondenzátorů platí to, co je zjevné u řetězu, ten je jen tak silný, jak silný je jeho nejslabší článek. U značkových kvalitních výrobků (zejména se to týká výrobců z USA, i když fyzicky jsou součástky vyráběny v Číně) se lze ještě přiměřeně spolehnout na dodržení udávaného rozpětí kapacity, typicky +/- 20% nebo 0 až +20%. U levné produkce superkondenzátorů nakupované přímo z Číny jsou zaručované parametry k ničemu. Můžete se setkat s odchylkami více než 75%, a to nepočítám kusy, které jsou zkrátka zmetky a uvnitř jsou buď přerušené nebo zkratované. Přesnot měření kolem 2% pro běžnou praxi naprosto stačí.
Rozsah měřených kapacit je byl zvolen od 1 F (s přesahem dolů až k 0,1 F) po 100 F (s přesahem nahoru po 1000 F). Nabíjecí proud měřeného kondenzátoru je nastaven pevně na (přibližně) 0,3 A, přesná velikost proudu neovlivňuje přesnost měření. Vybíjecí proud, při němž se měří, je 0,500 A. Tento nabíjecí i vybíjecí proud je přijatelný pro univerzální a pohonné kondenzátory zhruba v rozsahu kapacity 10 F až 100 F. Pro menší kapacity, které ale asi nebudou tak časté, je dost velký, nedodržení standardních podmínek zhoršuje přesnot měření. Pro větší kapacity se velmi prodlužuje měřicí cyklus. Současně s tím se začne významně uplatňovat samovybíjení, které také zhoršuje přesnost, nicméně smíříme-li se s několikahodinovými dobami měření, lze změřit kvalitní kondenzátory až do řádu jednotek kF. Zálohovací kondenzátory s vnitřním odporem v řádu desítek ohmů a vyšším tímto přístrojem nejde měřit.
Měřicí metoda je velmi jednoduchá a současně dovoluje (teoreticky) dosáhnout vysoké přesnosti. Vychází ze vzorce pro výpočet kapacity
C [F] = I [A] * Δt [s] / ΔU [V],
jinak řečeno, kapacitu 1 F má kondenzátor, který zvýší svoje napětí o 1 V při nabíjení (vybíjení) proudem 1 A za 1 s. Čas umíme měřit velmi přesně a Arduino s hodinami řízenými krystalem k tomu má jednoduché prostředky, napětí je AD převodník také schopný změřit přiměřeně přesně a proud převedeme na napětí na známém odporu. Konstrukce je navržena tak, aby k oživení nebylo potřeba použít víc, než nejlevnější multimetr. Vlastně není nutné nastavit vůbec nic kromě kontrastu displeje.
Obecné doporučení (pokud výrobce neuvádí jinak) je k měření kapacity používat proud 10 mA na každý 1 F kapacity. Podobně se obecně doporučuje měřit v rozsahu napětí přibližně 40% až 80% z maximálního povoleného provozního napětí. Shodou okolností toto rozpětí pro běžné superkondenzátory na napětí 2,7 V odpovídá 1,08 V a 2,16 V, takže měření s mezemi 1,00 V a 2,00 V tomu velmi dobře odpovídá.
Přesnost měření kapacit by měla být lepší než 2 % , rozlišení a opakovatelnost měření asi o řád lepší. Víc není ani třeba. Rozdíly výsledků měření kapacity způsobené průběhem nabití, teplotou i dobou odpočinku mezi nabitím a měřeným vybíjením jsou 3 – 5%, proto je velmi důležité zachovávat stejné podmínky. A to uvažuji jen o měření kondenzátorů předem podle podmínek výrobce zformovaných a již ustálených. Pro ilustraci, velikost samovybíjecího proudu krátce po prvním nabití nového kondenzátoru může být 100x až 800x vyšší, než ustálený samovybíjecí proud po předepsaném formování po dobu 48 nebo 72 hodin. Při formování se tedy nesníží samovybíjení o „několik procent“, ale mnohonásobně, a pokud to nerespektujeme, pochopitelně se to podepíše i na výsledku měření kapacity.
Zapojení měřiče ukazuje následující schéma. Řízení zajistí Arduino Uno (nebo typ Pro Mini s mikrokontrolérem ATmega328). V nákresu jsou uvedeny vývody podle značení obvyklého u Arduina. První část se týká připojení LCD displeje k Arduinu, druhá je vlastní měřič. Rezistory označené * by měly být v toleranci 1%, všechny jsou miniaturní metalizované (RM0207) na 0,5 W.
K napájení měřiče je potřeba nestandardní napětí 6,5 až 7 V. Menší napětí není vhodné použít, protože napětí na výstupu OZ už pak není dost velké na to, aby spolehlivě otevřelo FET v obvodu vybíjení superkondenzátoru. Vyšší napětí naopak neúčelně a silně zvyšuje výkonovou ztrátu výkonového tranzistoru v obvodu nabíjení. Výsledkem jsou dvě verze napájení.
První verze pro Arduino Uno, které obsahuje vlastní stabilizátor napětí +5 V (tedy víceméně pro ty, kdo si chtějí postavit měřič jen dočasně a na pokusy), předpokládá buď napájení měřiče i Arduina společným napětím 7,0 V z univerzálního stabilizovaného (laboratorního) zdroje, nebo připojení na malý spínaný snižující měnič nastavený na 7 V a napájení z libovolného zdroje 9 – 24 V / 5 W.
Druhá verze (zejména pro Arduino Pro Mini) obsahuje i stabilizátor napětí +5 V, který ale napájí jen Arduino a LCD displej. V obou případech je nezbytné věnovat pozornost tomu, aby spoje země (GND) byly masivní a vznikal na nich jen velmi malý úbytek napětí. Posunutí úrovní země výkonové části proti zemi Arduina vede k chybám v měření napětí a tím podstatnému zhoršení přesnosti.
K zapojení měřiče. Referenční napětí se získává ze stabilizátoru TL431, který dává kvalitní napětí blízké 2,5 V. Toto napětí se zavádí jako externí reference pro AD převodníky Arduina, takže při desetibitovém rozlišení připadá na jeden krok přibližně 2,444 mV. Přesné měření napětí v podstatě není třeba ani pro mez vybíjení 0,2 V, ani mez nabíjení (formování) kondenzátoru 2,5 V.
Z reference se přesným děličem 4:1 (rezistory R3 až R6) odvozuje napětí 0,5 V pro řízení vybíjecího proudu. Použité rezistory by měly být v toleranci 1%, přitom moc nezáleží na jejich přesné hodnotě, ale je důležité, aby byly stejné a stabilní.
OZ typu LM358 porovnává napětí z reference 0,5 V a napětí na snímacím odporu v obvodu vybíjení, ten je složen z rezistorů R10 až R13. U nich záleží na přesnoti a hodnotě 1 Ω. Pokud je tranzistor T1 zavřený a OZ svým výstupem řídí T4, je úbytek napětí na snímacím odporu 0,50 V, čili jím teče stabilizovaný proud 0,50 A. LM358 je zvolen proto, že je schopen pracovat při malém a nesymetrickém napájení a jeho vstupy dobře vyhodnocují i napětí blízko země (respektive jeho záporného napájení). V tomto zjednodušeném zapojení se zanedbává vstupní napěťová nesymetrie OZ, při typické velikosti 2 mV způsobí chybu výsledku kolem 0,5 %.
FET tranzistor T4 (IRL2203N) musí být určený k ovládání výstupem TTL (napětím 5 V), ne vyšším! Je možné použít i méně výkonné typy jako IRLZ34N. Tranzistor T4 by měl být na malém chladiči (jeho maximální okamžitá ztráta je kolem 1 W), stačí třeba DO1A. Tranzistor T2 by měl být na větším chladiči (například V4330K), ztráta na něm může dosáhnout až 2,1 W.
Je zajímavé, že přesnost měření prakticky nezávisí na napětí referenčního zdroje (pokud se odchýlí v přiměřených mezích a je stabilní). Ze stejné reference se totiž odvozuje jak vybíjecí proud, tak měření napětí AD převodníky, a pokud by došlo například k poklesu o 10%, sníží se o 10% i vybíjecí proud, ale také se sníží o 10% i měřené napětí (též rozsah změny napětí), takže se změna kompenzuje. Jediné co se trochu změní, bude posunutí měřicího intervalu napětí trochu nahoru nebo dolů, ale to se na výsledné kapacitě neprojeví.
Co musí být přesné, to je spočtení mezí pro vyhodnocení napětí programem a linearita převodu. Stačí vycházet třeba z hypotetického napětí reference 2557,5 mV (tj. přesně 2,5 mV na krok převodníku) a nastavit meze měření 400 (1,000 V) a 800 (2,000 V). Když bude reference jiná (a ve skutečnosti bude mít o něco nižší napětí), posune se tento interval mírně dolů a zmenší se, ale úměrně se zmenší i vybíjecí proud. Takto se vyhneme nutnosti přesně měřit a nastavovat hodnoty!
Nabíjecí obvod tvoří zdroj proudu s tranzistorem T2 (BD140), součástky odpovídají proudu přibližně 300 mA. Červená LED v bázi T2 má dva účely, jednak dělá referenční zdroj napětí pro tento zdroj proudu, jednak může být využita i jako kontrolka nabíjení (při činnosti zdroje proudu svítí). Tranzistor T3 spíná proud pro LED a tím i zapíná nebo vypíná proudový zdroj, rezistor R16 zajistí, aby se ve vypnutém stavu T2 zcela zavřel. Po získání určité praxe z blikání LED při formování kondenzátoru jasně poznáme, jak na tom daný kondenzátor je a jak jeho formování pokračuje.
K ovládání se používají tři tlačítka označená jako menu, potvrzení a posun. Pokud nejsme v menu a stiskneme první z nich, vyvolá se přerušení, činnost programu se zastaví, vypne se nabíjecí i vybíjecí proud a okamžitě se přejde do nabídky funkcí. Měřený kondenzátor zůstane na napětí, které měl v okamžiku přerušení. Tlačítko pro cyklické posunutí v nabídce a potvrzení výběru se obsluhují programově a v průběhu práce s kondenzátorem jsou nefunkční.
Nabídka obsahuje čtyři funkce. Nabití kondenzátoru zapne nabíjecí proudový zdroj a vypne jej, když napětí na kondenzátoru dosáhne napětí 2,5 V. Ve skutečnosti je napětí o něco menší, jednak referenční napětí není 2557,5 mV, jednak napětí se měří pod proudem a tedy i včetně chyby, kterou způsobí reálný vnitřní odpor kondenzátoru. Toto má význam především u malých kapacit (do 5 F) a jejich napětí po skončení nabíjení může být až o několik desetin voltu nižší.
Druhou možností je vybití kondenzátoru. Sepne se vybíjecí proudový zdroj a odpojí se až když napětí klesne přibližně na 0,2 V. Opět je zde rozdíl vzhledem k odchylce reference (snižuje mezní napětí) a také proto, že napětí se měří při odběru (zvyšuje mezní napětí). Vybíjení probíhá konstantním proudem jen asi do napětí 0,5 V, pak už se tranzistor T4 naplno otevře a v podstatě se vybíjí rezistorem 1 Ω postupně klesajícím proudem. Proto také vybíjení trvá podstatně déle, než by odpovídalo výpočtu podle konstantního proudu zdroje. Vybíjení není do nuly a u kondenzátorů větších kapacit (nad 1 kF ) může i napětí 0,2 V způsobit při nechtěném zkratu velké problémy, nicméně tento přístroj je značně zjednodušený a budeme-li uvažovat dnes standardní jmenovité napětí superkondenzátorů 2,7 V, pak po vybití v daném režimu zbude v kondenzátoru jen 0,5% energie (proti maximu).
Třetím režimem je formování. Tento režim nemá automatické ukončení, musí se ukončit ručně tlačítkem „menu“, zobrazuje se doba v podobě hhhh:mm:ss. Zapne se nabíjení a kondenzátor se nabije na 2,5 V (přibližně). Když napětí samovybíjením poklesne, přístroj jej proudovým pulzem opět zvýši, takže napětí mírně kolísá (asi o 10 mV) a na LED je vidět, jak často se energie doplňuje. Formování má význam u nových kondenzátorů.
Nejdůležitější je režim měření kapacity. Nejprve se kondenzátor nabije na 2,5 V, pak se nechá 3 minuty na konstantním napětí (udržuje se stejně jako při formování) a následně se vybíjí a měří doba mezi průchodem napětí 2,00 a 1,00 V. Prodleva je důležitá zejména u malých kapacit do 10 F, u nich má citelný vliv na výsledek, bez prodlevy při bezprostředně opakovaných měřeních vychází kapacita o 2 až 3% menší. Výsledná kapacita ve faradech se zobrazuje na dvě desetinná místa bez ohledu na to, zda jde o desetiny faradu nebo tisíce faradů. S ohledem na reálnou přesnost měření je vhodné výsledek zaokrouhlit na dvě až tři platná místa.
Při měření malých kapacit (pod 5 F) a zejména pokud se pokusíme změřit kondenzátor, který není standardní ani pohonný, ale původem zálohovací (se záměrně velkým vnitřním odporem), se může stát, že okamžitě po zatížení měřicím proudem klesne napětí pod mez 2,0 V. V takovém případě se ohlásí chyba. Kapacitu těchto kondenzátorů by bylo možné měřit, ale mnohem nižším proudem (typicky 1 nebo 10 mA).
Při měření velkých kapacit (nad 100 F) se doba měření úměrně prodlouží, například pro pohonné kondenzátory Maxwell 3 kF by jen fáze vybíjení a měření trvala 2,5 hodiny, před tím by se kondenzátor nabíjel zhruba 7 hodin. Přístroj může jít i do těchto extrémů, ale musíme si uvědomit, že se už značně odchyluje od předepsaného režimu měření, který třeba pro zmíněné kondenzátory Maxwell 3 kF předpokládá měricí proud 100 A, ne zde použitých 0,5 A. Orientačně měřicí cyklus pro kondenzátor 10 F trvá necelých 5 minut, kondenzátor 100 F až 22 minut.
// Arduino Uno - metr superC #include <LiquidCrystal.h> int stav = 1; // stav vyberu z menu int napeti; // pomocna pro mereni napeti volatile int pryc = LOW; // pro obslouzeni interruptu unsigned long pocatek, doba; // pomocne mereni casu unsigned long form = 3600000; // doba formovani v ms LiquidCrystal lcd(9, 8, 7, 6, 5, 4); //LiquidCrystal(rs, enable, d4, d5, d6, d7) // uzivatelske znaky pro grafiku byte g0[8] = {B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111}; //0 byte g1[8] = {B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111}; //1 byte g2[8] = {B11111, B11000, B11000, B11000, B11000, B11000, B11000, B11111}; //2 byte g3[8] = {B11111, B11100, B11100, B11100, B11100, B11100, B11100, B11111}; //3 byte g4[8] = {B11111, B11110, B11110, B11110, B11110, B11110, B11110, B11111}; //4 byte g5[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}; //5 byte h0[8] = {B11111, B00001, B00001, B00001, B00001, B00001, B00001, B11111}; //6 byte h1[8] = {B11111, B10001, B10001, B10001, B10001, B10001, B10001, B11111}; byte h2[8] = {B11111, B11001, B11001, B11001, B11001, B11001, B11001, B11111}; byte h3[8] = {B11111, B11101, B11101, B11101, B11101, B11101, B11101, B11111}; byte h4[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}; //7 void setup() { pinMode(A1, OUTPUT); // nabijeni digitalWrite(A1, LOW); // nabijeni vypnout pinMode(A2, OUTPUT); // vybijeni digitalWrite(A2, HIGH); // vypnout vybijeni pinMode(A3, INPUT_PULLUP); // TL enter pinMode(A5, INPUT_PULLUP); // TL dalsi pinMode(2, INPUT_PULLUP); // TL menu pres interrupt pinMode(10, OUTPUT); // zvuk lcd.begin(16, 2); // zavedeni grafiky do RAM displeje lcd.createChar(0, g0); lcd.createChar(1, g1); lcd.createChar(2, g2); lcd.createChar(3, g3); lcd.createChar(4, g4); lcd.createChar(5, g5); lcd.createChar(6, h0); lcd.createChar(7, h4); analogReference(EXTERNAL); // reference 2,5 V z TL431 lcd.clear(); lcd.print("Meric superC"); // vypis hlavicky lcd.setCursor(0, 1); lcd.print(" verze 1.1"); attachInterrupt(0, ven, LOW);// interrupt delay(2000); } // bargraf v druhém řádku displeje s rozsahem 0 - 80 resp. 1 - 79 (16x5 bodů) void zobraz(int cislo) { constrain (cislo, 1, 80); lcd.setCursor(0, 1); if (cislo < 5) { lcd.write(cislo); } else { lcd.write(byte(5)); } for (int j = 5; j <= 70; j = j + 5) { if (cislo >= j + 1 && cislo < j + 5) { lcd.write(cislo % 5); } else { if (cislo < j + 1) { lcd.write(byte(0)); } if (cislo >= j + 5) { lcd.write(byte(5)); } } } switch (cislo) { // vymena znaku v pameti disleje case 76: lcd.createChar(7, h1); break; case 77: lcd.createChar(7, h2); break; case 78: lcd.createChar(7, h3); break; case 79: lcd.createChar(7, h4); break; case 80: lcd.createChar(7, h4); break; default: lcd.createChar(7, h0); } lcd.setCursor(15, 1); lcd.write(byte(7)); } boolean ctiTL() { // cteni tlacitek a posuny v menu int TL = 0; delay(300); do { if (digitalRead(A5) == LOW) TL += 1; // dalsi if (digitalRead(A3) == LOW) TL += 2; // enter } while (TL == 0); if (TL == 1) { stav ++; if (stav > 4) stav = 1; pip(10); } if (TL == 2) { return true; // byl enter na zvoleny stav } else { return false; // nekorektni kombinace ignoruj } } void loop() { // hlavni menu funkci lcd.clear(); lcd.print("Vyber funkce:"); lcd.setCursor(0, 1); switch (stav) { case 1: // Zmerit kapacitu lcd.print("Zmerit kapacitu"); if (ctiTL()) merkap(); break; case 2: // Nabit lcd.print("Nabit na 2.5 V"); if (ctiTL()) nabit(); break; case 3: // Vybit lcd.print("Vybit na 0.20 V"); if (ctiTL()) vybit(); break; case 4: // Formovat lcd.print("Formovat (2,5 V)"); if (ctiTL()) formovat(); break; } if (pryc) { digitalWrite(A1, LOW); // nabijeni vypnout digitalWrite(A2, HIGH); // vypnout vybijeni for (int i = 1; i < 5; i++) { pip(50); delay(100); } pryc = LOW; } } void merkap() { float kapacita; lcd.clear(); if (analogRead(0) < 960) { // je nabito? - kdyz neni lcd.print("Mereni: nabijeni"); digitalWrite(A1, HIGH); // nabijeni do { napeti = analogRead(0); zobraz(map(napeti, 0, 1000, 0, 80)); if (pryc)return; } while (napeti < 1000); lcd.setCursor(0, 0); lcd.print("Mereni: prodleva"); // prodleva s dobitim pocatek = millis(); do { napeti = analogRead(0); if (napeti > 1002) digitalWrite(A1, LOW); if (napeti < 998) digitalWrite(A1, HIGH); doba = millis() - pocatek; zobraz(map(doba, 0, 180000, 0, 80)); delay(50); if (pryc)return; } while (doba < 180000); // 3 minuty form digitalWrite(A1, LOW); } // sem prechod kdyz uz bylo nabito lcd.setCursor(0, 0); lcd.print("Mereni: vybijeni"); digitalWrite(A2, LOW); // vybijeni delay(250); if (analogRead(0) > 800) { // nekleslo napeti prilis po zatizeni? do { napeti = analogRead(0); // vybijeni zobraz(map(napeti, 0, 1000, 0, 80)); if (pryc)return; if (napeti >= 800) pocatek = millis(); } while (napeti > 400); doba = millis() - pocatek; digitalWrite(A2, HIGH); kapacita = 0.5 * doba / 1000; // C = I * t / U } else { // velky vnitrni odpor lcd.clear(); lcd.print("Nelze merit - "); lcd.setCursor(0, 1); lcd.print("prilis velky ESR"); do {} while (!ctiTL()); return; } lcd.clear(); // vypis kapacity lcd.print("Mereni: kapacita"); lcd.setCursor(0, 1); lcd.print("C = "); lcd.setCursor(4, 1); lcd.print(kapacita); lcd.print(" [F]"); pip(1000); do {} while (!ctiTL()); } void nabit() { // nabijeni na 2,5 V lcd.clear(); lcd.print("Nabijeni do 2,5V"); digitalWrite(A1, HIGH); do { // cyklus nabijeni napeti = analogRead(0); zobraz(map(napeti, 0, 1000, 0, 80)); if (pryc)return; } while (napeti < 1000); digitalWrite(A1, LOW); lcd.setCursor(0, 1); lcd.print(" - hotovo - "); pip(1000); do {} while (!ctiTL()); } void vybit() { // vybijeni do 0,2 V lcd.clear(); lcd.print("Vybijeni do 0,2V"); digitalWrite(A2, LOW); do { napeti = analogRead(0); zobraz(map(napeti, 0, 1000, 0, 80)); if (pryc)return; } while (napeti > 80); digitalWrite(A2, HIGH); lcd.setCursor(0, 1); lcd.print(" - hotovo - "); pip(1000); do {} while (!ctiTL()); } void formovat() { // formovani bez omezeni lcd.clear(); lcd.print("Formovani (2,5V)"); pocatek = millis(); digitalWrite(A1, HIGH); do { napeti = analogRead(0); if (napeti > 1002) digitalWrite(A1, LOW); // vypnuti dobijeni do { // synchro casu doba = millis() - pocatek; if (napeti < 998) digitalWrite(A1, HIGH); // zapnuti dobijeni } while ((doba % 1000) != 0); long pom; // vypis casu lcd.setCursor(0, 1); lcd.print(long(doba / 3600000)); lcd.print(":"); pom = long(doba / 60000) % 60; if (pom < 10) { lcd.print("0"); } lcd.print(pom); lcd.print(":"); pom = long(doba / 1000) % 60; if (pom < 10) { lcd.print("0"); } lcd.print(pom); if (pryc)return; } while (true); // nekonecny cyklus } // vyskok pres interrupt void pip(int cas) { // signalizave stisku a chyb tone(10, 800); delay(cas); noTone(10); } void ven() { // vse vypnout a skocit do menu pryc = HIGH; digitalWrite(A1, LOW); // nabijeni vypnout digitalWrite(A2, HIGH); // vypnout vybijeni }
Kat. 8