Záznam do EEPROM při vypnutí napájení
Moderátor: Moderátoři
Záznam do EEPROM při vypnutí napájení
Potřebuju těsně před vypnutím napájení ATtiny85 uložit jednu hodnotu v rozsahu 0-64 do EEPROM aby byla k dispozici pro následný zapnutí. EEPROM nesnese moc cyklů, takže přepisovat ji při změně hodnoty v cyklu Loop by dlouho nezvládala.
Napadlo mě řešení ale nevím, jestli to bude makat. Zařízení je napájený v autě z batarie 12V a vypíná se vyškubnutím konektoru z autozásuvky. Z napájení 12V se dělá stabilem 5V pro napájení ATtiny. Co vzít těch 12V a přes dělič ho snížit na cca 3V a poslat do vstupu INT0, kterej bude reagovat na sestupnou hranu a v obsluze přerušení zapsat požadovanou hodnotu do EEPROM? Pokud bude za stabilem větší elyt, tak snad napájení 5V podrží na těch pár instrukcí, než se EEPROM zapíše. Nebo to je celý blbost?
Napadlo mě řešení ale nevím, jestli to bude makat. Zařízení je napájený v autě z batarie 12V a vypíná se vyškubnutím konektoru z autozásuvky. Z napájení 12V se dělá stabilem 5V pro napájení ATtiny. Co vzít těch 12V a přes dělič ho snížit na cca 3V a poslat do vstupu INT0, kterej bude reagovat na sestupnou hranu a v obsluze přerušení zapsat požadovanou hodnotu do EEPROM? Pokud bude za stabilem větší elyt, tak snad napájení 5V podrží na těch pár instrukcí, než se EEPROM zapíše. Nebo to je celý blbost?
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
No jo, ale proč mi to teda na UNO nejde?
V setup mám:
pinMode(2, INPUT);
attachInterrupt(0, button, FALLING); // INT0, PB2, sestupná hrana
A za koncem loop mám:
// obsluha přerušení na sestupnou hranu
void button() {
EEPROM.write(adr,hodnota); // zápis do EEPROM
Serial.println("Zapis"); // kontrolní výpis
while (1); //zažvejknutí před ztrátou napájení
}
Zkouším to že mám poťák mezi +5V a 0 a běžec na PB2. Když jedu od 5V k nule, tak by to mělo někde pod 1V vyvolat přerušení, zapsat do EEPROM a napsat na sériovým monitoru "Zápis" a program by se měl zakousnout (prostě aby už nic nedělal do ztráty napájení). Bohužel nic a netuším proč. Něco blbě nadefinovanýho kolem toho vstupu pro přerušení PB2?
V setup mám:
pinMode(2, INPUT);
attachInterrupt(0, button, FALLING); // INT0, PB2, sestupná hrana
A za koncem loop mám:
// obsluha přerušení na sestupnou hranu
void button() {
EEPROM.write(adr,hodnota); // zápis do EEPROM
Serial.println("Zapis"); // kontrolní výpis
while (1); //zažvejknutí před ztrátou napájení
}
Zkouším to že mám poťák mezi +5V a 0 a běžec na PB2. Když jedu od 5V k nule, tak by to mělo někde pod 1V vyvolat přerušení, zapsat do EEPROM a napsat na sériovým monitoru "Zápis" a program by se měl zakousnout (prostě aby už nic nedělal do ztráty napájení). Bohužel nic a netuším proč. Něco blbě nadefinovanýho kolem toho vstupu pro přerušení PB2?
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
PB2 na Une nemôžeš použiť na hardwarové prerušenie, iba PD2 a PD3. Ten attachInterrupt s nulou na vstupnom argumente ti ho namapuje na PD2, takže pripoj poťák tam a malo by to fungovat. Vôbec, miesto tej nuly radšej použi digitalPinToInterrupt(pin_na_doske); potom si nemusíš dávať pozor na číslovanie vývodov MCU vs. vývodov označených na doske.
Nezabudni potom v setupe na Serial.begin() s rovnakou prenosovou rýchlosťou i na termináli. Vôbec, obsluhu prerušenia chceš vyriešiť v najkratšom čase, takže potom miesto Serial.println tam skús prebliknúť ledkou na doske, pripojenú na pine 13 (PB5) hned na začiatku, aby si videl, či sa to tam dostane.
BTW zápis do EEPROM trvá 3,3ms na bajt. Až to rozbeháš, použi update miesto write - to najskôr zavolá read a porovná, či nie je cieľový bajt ten istý, ušetrí to potom zápisný cyklus.
Nezabudni potom v setupe na Serial.begin() s rovnakou prenosovou rýchlosťou i na termináli. Vôbec, obsluhu prerušenia chceš vyriešiť v najkratšom čase, takže potom miesto Serial.println tam skús prebliknúť ledkou na doske, pripojenú na pine 13 (PB5) hned na začiatku, aby si videl, či sa to tam dostane.
BTW zápis do EEPROM trvá 3,3ms na bajt. Až to rozbeháš, použi update miesto write - to najskôr zavolá read a porovná, či nie je cieľový bajt ten istý, ušetrí to potom zápisný cyklus.
Chtěl jsem to mít nakonec co nejmenší, dát tam po odladění pouze SMD ATtiny85, FETa na výstup PWM, SMD stabil 0,8A ty dva odpory děliče, SMD tantal na +5V a dvě tlačítka nahoru a dolů. Je to náhradní PWM "regl" do rukojeti pájky Ersa kde před lety odešel nějakej asi zákaznickej šváb. Takže přidávání dalších součástek je nežádoucí aby se to vůbec rozumně vešlo na destičku původní velikosti.ondraN píše:Dej ten potenciometr přes SKO nebo komparátor a uvidíš že to bude chodit.
to Cowley: Máš pravdu, překlep, je to PD2. Ke klopáku jsem se už vyjádřil. Analogový vstup prý trvá na 8 MHz 130 ms. A musel by být ve smyčce Loop a ta je už tak zaměstnaná testem tlačítek pro nastavení. To je proti obsluze přerušení a zápisu do EEPROM strašně dlouhá doba. Nevím, co myslíš tím "Anebo nahraď Interrupt hodnotou LOW." Jako čtením v Loop?
to Nixdorf: Jak jsem již psal, překlep. DigitalPinToInterrupt sice můžu zkusit ale ATtiny ho stejně nemá. Ten Serial.printnl je tam jen na test provozovanej na UNO, pak tam už nebude. U toho testu zatím napájecí napětí nevypínám, jen poťákem simuluju pokles z 5V na nulu, takže Serial.print má dost času a nakonec se to zažvejkne na While (1).
Write jsem použil záměrně, určitě je kratší než update, kterej nejdřív čte, rozhodne jestli zapsat a případně zapíše. Pokud by se zápis do EEPROM dělal jen při tom vypnutí pájky třeba 10 x za den, 365 x za rok tak je to na věky i při zápisu do stále stejný adresy.
Jdu zkoušet dál. V nejhorším si napíšu jen krátkej test na vyhodnocení přerušení aby se to třeba nemotalo s něčím jiným.
Zatím díky všem za pomoc.
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
AVR101: High Endurance EEPROM Storage
Je trik se zvýšením životnosti zápisu do EEPROM.
Jde o to, že namísto zápisu do fixní adresy v EEPROM se pokaždé zapíše do další pam. buňky (kruhový buffer).
Kruhové buffery jsou celkem dva, jeden obsahuje data, druhý obsahuje "ukazatel", kde je poslední hodnota.
http://ww1.microchip.com/downloads/en/a ... oc2526.pdf
edit1: jestli máš 2 kanál. osciloskop, tak si zobraz kanál 1-signál do INT, a kanál 2-napájení MCU. Samozřejmě paralelně k MCU vhodný kondenzátor, který udrží V po dobu zápisu. Případně ještě oddělit shottky diodou od zbytku větve napájení..
Je trik se zvýšením životnosti zápisu do EEPROM.
Jde o to, že namísto zápisu do fixní adresy v EEPROM se pokaždé zapíše do další pam. buňky (kruhový buffer).
Kruhové buffery jsou celkem dva, jeden obsahuje data, druhý obsahuje "ukazatel", kde je poslední hodnota.
http://ww1.microchip.com/downloads/en/a ... oc2526.pdf
edit1: jestli máš 2 kanál. osciloskop, tak si zobraz kanál 1-signál do INT, a kanál 2-napájení MCU. Samozřejmě paralelně k MCU vhodný kondenzátor, který udrží V po dobu zápisu. Případně ještě oddělit shottky diodou od zbytku větve napájení..
O těch kruháčích vím, ale moc tomu po zběžným přečtení nerozumím. Ale tady to vzhledem k počtu zápisů určitě nebude potřeba.bdn píše:AVR101: High Endurance EEPROM Storage
Už mi to chodí. Dělič jsem nastavil z 12 na 3V. Pokud odpojím 12V, tak se mi EEPROM bez problému zapíše. Ale zatím to je na nepájivým poli s napájecí destičkou podobnou týhle. Za 5V stabilizátorem je elyt 100M/25V. Musím to nabastlit ze samotný 7805 a vyzkoušet jakej elyt je potřeba na spolehlivej zápis. Jde o to, aby se vešel. Tantal v obdélníkovým SMD pouzdře 4 x 7 mm 47M/16V co tu mám, je tak maximum, co se vejde.
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
Zakomentuj riadok
EEPROM.write(adr,hodnota); // zápis do EEPROM
A skús, či ti pôjde aspoň
Serial.println("Zapis"); // kontrolní výpis
V inej časti kódu ti Serial.println funguje?
Premenné adr a hodnota musia byť volatile, inak ich prerušenie neuvidí.
Ďalšia vec je, že hardverové prerušenie má najvyššiu prioritu, takže ak EEPROM.write a Seril.println využívajú prerušenia, tak s nemôžu vykonať, kým sa hardverové prerušenie neukončí. A tomu bráni while(1).
Lepšie, ak v prerušení nastaviš pomocnú premennu a na základe nej vykonáš všetko ostatné v loop v nejakej podmienke aj s tým while(1).
EDIT: neskoro, tak potom nič, keď už to chodí
EEPROM.write(adr,hodnota); // zápis do EEPROM
A skús, či ti pôjde aspoň
Serial.println("Zapis"); // kontrolní výpis
V inej časti kódu ti Serial.println funguje?
Premenné adr a hodnota musia byť volatile, inak ich prerušenie neuvidí.
Ďalšia vec je, že hardverové prerušenie má najvyššiu prioritu, takže ak EEPROM.write a Seril.println využívajú prerušenia, tak s nemôžu vykonať, kým sa hardverové prerušenie neukončí. A tomu bráni while(1).
Lepšie, ak v prerušení nastaviš pomocnú premennu a na základe nej vykonáš všetko ostatné v loop v nejakej podmienke aj s tým while(1).
EDIT: neskoro, tak potom nič, keď už to chodí
Zkusil jsem napájení ProMini z 12V stáhnout 7805-kou, dělič pro přerušení před ní a zkoušel jakej elyt to potřebuje mezi zemí a VCC aby bylo dost energie pro zápis do EEPROM. A zjistil jsem, že externí žádnej. Tedy že stačí interní 10M, co je na VCC 5V za stabilem MIC5205 přímo na desce.
Dokonce to chodí i když pošlu 12V na RAW a beru dělič na přerušení od něho. Ale protože to nakonec bude na ATtiny85, tak nad tím RAW nemá cenu dál bádat.
Tak to jdu zkusit přenýst na ATtiny85. U něj za stabec budu muset něco dát, počítám 22-47M.
Přerušení by mělo makat na PB2, PWM na PB1 a tlačítka nahoru a dolů musím dát na PB3 a PB4. No uvidíme...
edit: tak to šlo přenýst na první šlápnutí. Akorát jsem musel dát za stabec elyt 47M jinak to do EEPROM nestíhalo zapisovat. ATTiny na 8MHz žere 15mA, ProMini na 16MHz s tím samým programem 22mA. Takže spotřebou to není. Divný, ještě zkusím ATtiny zapnout předděličku na hodinách, jestli se spotřeba výrazně nezmenší. Nojo, ale zase se srát s předěláním časování v celým programu...
Dokonce to chodí i když pošlu 12V na RAW a beru dělič na přerušení od něho. Ale protože to nakonec bude na ATtiny85, tak nad tím RAW nemá cenu dál bádat.
Tak to jdu zkusit přenýst na ATtiny85. U něj za stabec budu muset něco dát, počítám 22-47M.
Přerušení by mělo makat na PB2, PWM na PB1 a tlačítka nahoru a dolů musím dát na PB3 a PB4. No uvidíme...
edit: tak to šlo přenýst na první šlápnutí. Akorát jsem musel dát za stabec elyt 47M jinak to do EEPROM nestíhalo zapisovat. ATTiny na 8MHz žere 15mA, ProMini na 16MHz s tím samým programem 22mA. Takže spotřebou to není. Divný, ještě zkusím ATtiny zapnout předděličku na hodinách, jestli se spotřeba výrazně nezmenší. Nojo, ale zase se srát s předěláním časování v celým programu...
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
Krok od tlačítek v rozsahu 0-64 ze kterýho se přepočítává PWM.Crifodo píše:Jaký parametr pájky je potřeba uložit do paměti před vypnutím? nastavenou teplotu?
Kód: Vybrat vše
// (krok min, krok max, PWM min, PWM max)
pwm = map(krok, 0, 64, 160, 255);
Jirka
Proč mi nemůže všechno chodit hned ?!!
Proč mi nemůže všechno chodit hned ?!!
Když jsem kdysi dělal s attiny přijímač DO a přepínač vstupů nf zesilovače, ukládal jsem nastavenou hlasitost a zvolený zdroj signálu do eeprom ne v okamžiku vypnutí, ale po pár sec po poslední změně tlačítkama nebo enkodérem, jedna buňka paměti jako ukazatel do začátku dat. Po určitým počtu zápisů se inkrementovala hodnota v ukazateli a jelo se dál. Takže se eeprom "opotřebovala" cyklicky.