Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ESP8266 Arduino IDE EEPROM lub inna nie ulotna pamięć

16 Paź 2016 18:49 2412 8
  • Poziom 12  
    Witam, potrzebuje przechować 4 zmienne typu String w pamięci która utrzyma dane mimo wyłączenia prądu.
    Zmienne te mają maksymalnie do 16 znaków.

    Do tej pory korzystałem z EEPROMAnything.h dzięki któremu zapisywałem całą strukturę. Niestety, wszystko działało dopóki nie przyszedł czas na test wyłaczenia i włączenia prądu.
    W EEPROMie nic nie było, znaczy po odczytaniu struktury dostawałem puste pole.

    Dlatego mam do was pytanie, jak Wy zrealizowaliście przechowywanie danych (zmiennych w postaci String) na czas odłączania zasilania?
  • Moderator na urlopie...
    Zapisując strukturę za pomocą domyślnego drivera EEPROM dla ESP.
    Ot strukturę wystarczy umieścić w unii z tablicą bajtów i zapisywać/odczytywać te bajty z EEPROM.
    Warto przechowywać 2 kopie danych (lub więcej) wraz z sumą kontrolną.

    No i warto sprawdzać zawsze czy działa zanim się uwierzy ;)
  • Poziom 12  
    Dziękuję za zainteresowanie tematem.
    Strukturę zapisałem i odczytałem z wykorzystaniem EEPROMAnything z tego samego adresu a następnie wysyłałem za pomocą serial print pojedyncze Stringi i wszystkie zawierały poprawne dane, dopóki nie wyłączyłem i nie włączyłem ponownie ESP. Po tym uzyskałem tylko cztery puste pola.
  • Moderator na urlopie...
  • Poziom 12  
    Racja, zapomnialem zamieścić chociaż sprawka kodu.
    Więc tak, zapisywanie znajduje się w funkcji która wywoływania jest jeżeli która kolwiek z wartości ulegnie zmianie.
    Wygląda to w ten sposob
    EEPROM.begin(512) sprawdzałem też z wartością 64 chociaż nie wiem co to oznacza czy jest to maksymalna porcja danych jaka wyślę czy maksymalna pojemność eepromu w bajkach, nie wiem.
    EEPROMAnything_write(0, str_dane)
    EEPROM. commit w pewnym poradniku znalazłem by zmodyfikować anything.h i dodać tam EEPROM.commit ale to nic nie dało.

    Tak wygląda u mnie zapis, dokładnie tak bo pominę wszystkie printy debugujace które informują mnie o każdym kroku programu bo już brakuje mi pomysłów gdzie szukać błędów...
    Funkcji odczytujacej nie poprzedzam EEPROM. Begging, czy to może być to?

    zamieszczam cały kod, jeżeli ktoś ma cierpliwość niech zerknie
    Kod: c
    Zaloguj się, aby zobaczyć kod
    [/code]

    Natomiast tutaj są kłopotliwe EEPROMy
    Kod: c
    Zaloguj się, aby zobaczyć kod


    A tutaj pierwsze próby "oszczędzania EEPROMu" i zapisywania tylko wartości któe uległy zmanie

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Czy mógłbyś mi wyjaśnić o co chodzi z tym EEPROM.begin(value)?
    czy wartość ta ma być równa sumie tego co znajduje się miedzy EEPROM.begin a EEPROM.commit?
    to znaczy że jeżeli zapisuje strukture w której mam 4*16 bajtów to EEPROM.begin powinienem wpisać 64?
    A jeżeli zapisuje pojedyńczo stringi to dla każdego powinienem dać 16?

    Niepotrzebnie cały czas komplikuje ten temat. Właśnie wyczytałem w linku który wysłałeś że zanim odczytam wartość powinienem dać EEPROM.begin... Zaraz sprawdze i dam znać

    Niestety, dodanie EEPROM.begin(64) przed readAnything nic nie dało. EEPROM.begin(512) też.
    Chyba przyjdzie mi napisać funkcje która sama rozbije Stringa na pojedyńcze bajty i zapisze je albo zrobie sprzętowe wykrywanie braku zasilania które spowoduje odłączenie CH_PD i podtrzymanie wszystkich zmiennych w RAMie akumulatorkiem.
    Dlaczego tylko mnie to nie działa? Nigdzie w internecie nie moge znaleźć żeby kto kolwiek miał jaki kolwiek problem z EEPROMem w ESP...
  • Pomocny post
    Moderator na urlopie...
    1. Spróbuj pozbyć się tej bibioteki - zapisz ręcznie kilkanaście bajtów, potem je odczytaj i np. przy każdym starcie programu zwiększ.
    2. Jeśli kiedykolwiek zapisywałeś coś w pętli z dużą szybkością to mogłeś uszkodzić pamięć.
    3. jako rozmiar podaje się maksymalny rozmiar danych, które chcesz zapisać, w Twoim przypadku powinno być to co najmniej sizeof(str_dane). Tu tylko parę uwag: nie wiem jak zachowa się obiekt string, ESP trochę dziwnie układa pola w strukturach.

    Na początku spróbowałbym zapisu pojedynczych bajtów - u nie to działa.
    Dalej samemu napisał funkcje do zapisu czego trzeba do pamięci.
    Dalej nie korzystał z obiektu string podczas zapisu, ale z tablicy znaków.
  • Poziom 12  
    Witam, popracowałem trochę nad moim programem i jest postęp.

    Tak jak pisałeś, przerzuciłem się z String na tablice znaków i zapisuje do EEPROM znak po znaku (bajt po bajcie).
    Zadziałało, znaczy EEPROM jeszcze działa bo zapisuje i zwraca nawet po odłączeniu zasilania co jest naprawdę niezwykłe :), ale pojawił się nowy problem i nie wiem gdzie jest błąd.

    Opisze najpierw jak wygląda u mnie procedura zapisu.

    Chce przechować 4 nazwy każda max po 32 znaki.

    Wszystko zaczyna sie od EEPROM.begin(512) jeszcze w sekcji setup()
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Następnie w pętli for wykonuje 32 operacje zapisu tablicy znak po znaku zmienając adres w EEPROM i numer kolejny tablicy z każdym obiegiem pętli.
    Zmiennna "a" wykorzystywana jest gdy chce zapisywać kolejną nazwę z offsetem 32 bajtów ale narazie rozwiązuje problem z jedną nazwą dla uproszczenia.
    Wszystko jest dobrze dopóki nie odczytam nazwy.
    Dla przykładu, gdy nazwa którą wpisałem to "mandaryna" po restarcie urządzenia i odczycie z EEPROM na stronie Web otrzymuję
    "mandaryna������������������������������������������������"
    Pierw myślałem że jest to dopełnienie do tych 32 znaków które "rezerwuję" w EEPROM, ale nie, tych znaczków jest więcej. Nie wiem skąd się biorą i jak się ich pozbyć.
    Czy ktoś ma jakiś pomysł jak sobie z tym poradzić?

    Dodam że odczyt z EEPROM wygląda tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    Użytkownik usunął konto  
  • Poziom 12  
    To było dokładnie to czego brakowało, wykrywanie końca ciągu znaku. Bardzo wam dziękuje. Teraz już wszystko działa tak jak powinno. Wprawdzie nie wiem skąd te losowe znaki na końcu się wzięły, ale teraz to nie ma znaczenia bo wiem kiedy kończy się tablica bez znajomości jej długości.