Skocz do zawartości
SOYER

Odzyskanie stanu zmiennej po resecie

Pomocna odpowiedź

Cześć, bawię się trochę w wolnej chwili tym moim kodem z alarmu, dzisiaj dołożyłem mu z ciekawości  bibliotekę <avr/wdt.h> i funkcje  wdt_disable();,  wdt_enable(WDTO_8S);,  wdt_reset();.

Fajna sprawa pewnie, ale widzę jeden problem w takim zastosowaniu. Po resecie arduino, oczywiście wszystkie zmienne są również resetowane co powoduje ew. dezaktywcję alarmu i konieczność jego ew. ponownego uzbrojenia.

Tu pytanie, czy jest możliwość przy używaniu ww. sposobu, zapisania stanu choćby jednej zmiennej sprzed resetu tak by go odzyskać po resecie.

else if(jeśli nie da się tego zrobić) {

to jak  pilnować ew. zwiechy programu za pomocą innych funkcji, tak by po resecie móc znać stan konkretnej zmiennej, odpowiadającej za to jak ma pracować program po resecie;

}

 

Udostępnij ten post


Link to post
Share on other sites

@marek1707 dzięki 🙂

1 godzinę temu, marek1707 napisał:

by nie zajechać tej pamięci w tydzień

nie rozumiem, co to znaczy? 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

To znaczy mniej więcej że pamięć EEPROM ma dość ograniczoną liczbę cykli zapisu i odczytu, w zależności od typu i producenta pamięci ilość cykli wynosi od

10 000 do 1 000 000 cykli. Co za tym idzie, jak zrobisz zły program (np. zapisujący dane co 1 s.) to pamięć rzeczywiście "zajedziesz w tydzień" 🙂

Edytowano przez macizet

Udostępnij ten post


Link to post
Share on other sites

Można też zapisywać do flash ale flash ma tę samą przypadłość więc najlepszym sposobem jest używanie pamięci zewnętrznej np. sram spi z podtrzymywaniem bateryjnym i wtedy masz na zawsze. Np. taka:

https://www.microchip.com/wwwproducts/en/23LCV512

sam używam i jestem zadowolony. Oczywiście występuje w różnych rozmiarach pamięci a do podtrzymywania wystarcza malutka bateryjka guzikowa.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Ok, na razie spróbuję z eeprom. 

Czyli

EEPROM. update(0, zmienna) ;

EEPROM. read(0);

Oczywiście tylko w ściśle określonych i koniecznych momentach, zresztą EEPROM. update() zapisuje tylko jeśli (nowa ! = poprzednia). 

Teraz pytanie, czy w tej pamięci eeprom są zapisywane jakieś krytyczne informacje, dane, z punktu widzenia działania Arduino, czy też śmiało mogę coś zapisywać np. pod adresem 0?.

Edytowano przez SOYER

Udostępnij ten post


Link to post
Share on other sites

Jeśli coś tam jest to jedynie bajty kalibracyjne do oscylatora ale arduino jeździ z kwarcem więc nieważne. Epromu używa się w specyficzny sposób aby zwiększyć jego żywotność tj. jeśli np. potrzebujesz zapisywać 1 bajt to zapisujesz go za każdym razem pod kolejnym a nie tym samym adresem i dopiero po dojechaniu do końca nadpisujesz od zera. EEPROM służy raczej do zapisywania wstępnej konfiguracji, która ma się nie zmieniać a jeśli już to rzadko dlatego jeśli chcesz często aktualizować takie dane lepiej użyć zewnętrznej pamięci.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Dzięki, czyli jest różnica czy nadpisujemy ten sam adres, czy po kolei do pełna i od nowa. Dlaczego tak jest? 

Ja planuję max kilka razy na dobę, co przy limicie 100000 nadpisań, wystarczy na ok 50 lat. Wystarczająco;). 

Udostępnij ten post


Link to post
Share on other sites

Skoro tak to spoko 😜 Tak jest bo tak jest i już, komórki pamięci się zużywają. Sam się kiedyś zastanawiałem dlaczego tak jest jakby były z przekaźników zrobione i się im styki upalały 😄

Udostępnij ten post


Link to post
Share on other sites

Działanie komórek tej pamięci polega na utrzymywaniu ładunku w bramkach tranzystorów MOSFET, które z punktu widzenia "elektryki" są kondensatorami. Jeżeli weźmiesz z szuflady dowolny tranzystor MOSFET-N i podłączysz mu multimetr/omomierz do obwodu dren (czerwony kabelek) źródło (czarny kabelek) to zobaczysz zwarcie albo rozwarcie w zależności od tego czy pojemność (wiszącej w powietrzu) bramki jest akurat naładowana lub rozładowana. Niektórym wydaje się, że taki pomiar i wynik "0Ω" pokazuje uszkodzenie tranzystora, co rzecz jasna nie jest prawdą. W normalnych warunkach powinno się to robić z bramką zwartą do źródła, ale wtedy eksperyment nie jest ciekawy 🙂 Teraz, gdy dotkniesz palcem do wyprowadzenia bramki (ale tylko do niego), doprowadzasz do niej napięcie zmienne 50Hz z wszędobylskiej sieci AC. W momencie oderwania palca zostaje na niej napięcie takie jakie akurat było "powietrzu". Czasem uda się z bramką naładowaną dodatnio i wtedy zostaje "zwarcie" w kanale a czasem z naładowaną ujemnie lub w okolicach 0V i wtedy tranzystor jest wyłączony a kanał nie przewodzi. Brawo, niniejszym zrobiłeś 1-bitową pamięć EEPROM. Oczywiście w prawdziwej komórce tego typu jest to zrobione trochę inaczej: bramka nie ma żadnego podłączenia elektrycznego i z każdej strony jest dobrze izolowana tlenkiem krzemu o tak wielkiej rezystancji, że utworzony kondensator o pojemności kilkunastu fF rozładowuje się latami. Problem ładowania/rozładowania (czyli zapisów zer i jedynek) rozwiązano przez.. przebijanie izolacji kondensatora. Tuż za warstwą dielektryka jest elektroda do której układy sterujące podają wysokie napięcie. Oczywiście wysokie w skali mikrochipu - wystarczy kilka V by przebić izolację i wprowadzić ładunek do bramki. To samo w drugą stronę (kasowanie do stanu 1), ale ta prostota procesu i struktury układowej jest też największą wadą tego pomysłu. Z powodu kolejnych przebić tlenek się degraduje i bramka ma coraz gorszy izolator a ładunki coraz szybciej z niej "wyciekają". To oznacza, że po pewnej liczbie zapisów/kasowań dany bit nie może już utrzymać stanu przez czas i w warunkach gwarantowanych przez producenta - czyli wciąż działa, ale ma coraz większą "sklerozę". Jest jasne, że prąd czyli proces upływu ładunku zależy od temepratury więc jest to jeden z podstawowych parametrów. Przykładowo producent EEPROMu może się zobowiązać, że pamięć będzie pamiętać 🙂 przez 10 lat w temperaturze 80°C po 100 tys zapisów. Wtedy wiesz mniej więcej czego oczekiwać. Jeżeli nie używasz jej jak RAMu i choc trochę przemyślałeś sprawę, to są to tak dobre wartości (a w temperaturze pokojowej czasy są lepsze o co najmniej rząd wielkości - pamiętajcie, że scalaki nie są robione dla amatorów do zabaw na biurku tylko do samochodów, samolotów, komórek itp, my się nie liczymy), że nie ma się czym przejmować. Pomysły na zapisywanie kolejnych komórek są rzeczywiście stosowane w profesjonalnych urządzeniach (i wzięły się z czasów gdy raczkująca technologia EEPROM "umiała" się przeprogramować 1000 razy), ale moim zdaniem w zabawkach tego typu nie ma to sensu. To już lepiej - jeśli rzeczywiście chcesz się bawić w jakąś kontrolę - zrób zapis do dwóch sąsiednich komórek informacji w postaci prostej i zanegowanej i sprawdzaj to przy odczycie. Zaraz za tym idzie reakcja programu na to wydarzenie - trzeba gdzieś mieć funkcję znającą poprawny wzorzec i pozwalającą funkcjonować urządzeniu na "factory presets" gdy kontrola zawartości EEPROMu wykaże problemy. Tak więc bardzo "poprawne" używanie EEPROMu to cały łańcuch nowych funkcjonalności w programie i trzeba dobrze rozważyć czy w ogóle warto, albo.. zrobić to tak, by te gwarantowane 100 tys. starczyło po prostu na zawsze 🙂 (czyli kilka lat(?) po których zabawka zwyczajnie się znudzi). Na koniec jeszcze jedno: technologia "zagrzebanych bramek" EEPROM (buried gates) wymaga dodatkowych masek dla chipu więc i kosztuje więcej w stosunku do zwykłego procesora czy pamięci RAM. Z tego powodu niektóre firmy nie decydują się na umieszczenie tego typu pamięci w swoich układach, skazując nas na emulację tego w głównej pamięci FLASH lub na zewnętrzne układy dospawane na I2C lub SPI. Jeżeli więc AVRy EEPROM mają, warto z tego korzystać. Acha i jeszcze w kwestii operacji zapis/odczyt: degradacja tlenku następuje w wyniku przebicia polem elektrycznym i wytworzenia (miejscowo) wysokiej temperatury - i zachodzi tylko w czasie zapisu. Odczyt jest bezbolesny: sprawdzamy jedynie czy odpowiedni tranzystor jest włączony czy nie. A zapis jest dwufazowy: najpierw następuje obowiązkowe kasowanie (ustawienie wszystkich bitów w stan 1) a potem te tranzystory które mają mieć zero dostają "strzał" w bramkę. Do tego są dwie elektrody: kasująca (rozładowująca) i zapisująca (ładująca). Pamięci FLASH mają elektrodę kasującą rozciągniętą na wielkie obszary i dlatego tam kasowanie odbywa się dużymi sektorami lub stronami (256 bajtów do 4 Kbajtów) na raz. W EEPROMie mamy granulację bajtową i to fajne, ale to także podraża układ, bo rozpycha powierzchnię struktury krzemowej.

Dla porównania jak daleko zaszliśmy (zapis nawet i całej strony EEPROMu przy 3V trwający 1ms i 10-letnia trwałość po 1 mln zapisów przy 85°C) może dla porównania zajrzeć do kart katalogowych pierwszych EEPROMów Intela np. 2816:

http://bitsavers.trailing-edge.com/components/intel/_dataBooks/210273-001_E2Prom_Family_Applications_Handbook_Book_2_1981.pdf

Jest tam trochę o technologii wykonania - rzecz zupełnie w dzisiajszych katalogach niespotykana, i o zasadach działania. Moim zdaniem warto.

 

  • Lubię! 1
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Jestem ciekaw czy te, dajmy na to, umowne 100000 operacji odczyt/zapis to jest dla całej pamięci, czy dla każdej komórki osobno. Czy jeśli będę zapisywał tylko pod adres "0" to padnie ta komórka pamięci, a reszta będzie ok, czy cała pamięć wyzionie ducha?

Udało mi się z powodzeniem zaimplementować obsługę zapisu i odczytu do EEPROM. Dzięki za pomoc:-).

Jedynie wyskoczył mi problem z pierwszym uruchomieniem bo w komórce "0", na start, mamy zapisane 255, ale ugryzłem to if-em:

#include <EEPROM.h>
int menu;
void setup() {
Serial.begin(9600);
	if(EEPROM.read(0)>2){
		menu=0;
	}
		else{
 			 menu=EEPROM.read(0);
		}
}

void loop() {
  
Serial.println(menu);
}

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Chyba wszystkie odpowiedzi masz powyżej 🙂 

EDIT: A dane początkowe, które mają znaleźć się w EREPROMie przed pierwszym startem programu (żeby nie być zaskoczonym "dziewiczymi FF-ami) możesz umieszczać w kodzie jako inicjalizacja zmiennych w sekcji EEMEM - to bardzo wygodne. Avrdude uzywany przez Arduino obsługuje wpisywanie danych początkowych do EEPROMu. I odradzam korzystanie z adresu 0, każdy tylko nie ten.

Edytowano przez marek1707

Udostępnij ten post


Link to post
Share on other sites

@marek1707 pisaliśmy razem:-)), 

9 minut temu, marek1707 napisał:

To już lepiej - jeśli rzeczywiście chcesz się bawić w jakąś kontrolę - zrób zapis do dwóch sąsiednich komórek informacji w postaci prostej i zanegowanej i sprawdzaj to przy odczycie.

ale po co? w jakim celu zapisywać rzeczywisty stan np. zmiennej i jej negację? Tym bardziej, że może to być np.: 2,3, lub 77.... czego tu nie rozumiem?

Udostępnij ten post


Link to post
Share on other sites

Dzięki temu możesz sprawdzić, czy coś w EEPROMie padło. Jeśli każda wartość jest równie prawdopodobna, to jak możesz stwierdzić, że to co odczytałeś jest tym co zapisałeś? Redundancja zwiększa szansę wykrycia błędu zapisu. Wartość prosta i zanegowana to tylko taki przykład. Równie dobrze możesz zapisywać dwa razy to samo, czy jeszcze jakoś inaczej, np. sumę kontrolna dla dłuższego bloku, CRC, kody korekcyjne itp itd..

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

To ma sens, dzięki 🙂

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...