Skocz do zawartości

Sterownik silnika 1 przycisk pamieć po utracie zasilania


nebraska

Pomocna odpowiedź

5 godzin temu, ethanak napisał:

No to jeszcze ciekawostka: kolega o którym wspomniałem stwierdził, że ani eeprom, ani fram, on by zastosował SRAM z podtrzymaniem zasilania z dodatkowej baterii (a najlepiej akumulatorka) - eliminuje to możliwość, że przy odcięciu zasilania kostka czegoś tam nie zrobi. Ale obaj uznaliśmy to już za overkill w tym przypadku 🙂

W poprzednim projekcie używałem EERAM (47L04 bodajże) - takie wygodne połączenie SRAM z automatycznym backupem/restorem do wbudowanego EEPROM przy zaniku zasilania. Ma chyba zalety wszystkich wymienionych rozwiązań.

Nawet nóżkami pasuje zamiast np 24C04.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

15 minut temu, kostuch napisał:

EERAM (47L04

O, to ciekawe. Muszę poszukać, przydałoby mi się do nowej wersji czytaka , (potrzebuję 16 bajtów),  mógłbym zapisywać pozycję po każdym przeczytanym zdaniu... Dzięki!

Link do komentarza
Share on other sites

(edytowany)

Potestowałem swój kod i jedna sprawa mnie nie pokoi. Raczej kod tu nie ma nic do rzeczy. Program działa prawidłowo ale jeśli trzymam przycisk wciśnięty z 5s to następuje reset esp🙄. Co to może być?

EDIT 

Znalazłem przyczyne ale nie wiem jak ją zlikwidować winowajcą jest ta linia while (digitalRead(PRZYCISK) == LOW);  kurdę ten while jest mi potrzebny. While wprowadza jakiś konfilkt w pętli. 

 

Podaje rozwiązanie jakby ktoś miał z tym problem. Dodanie yield rozwiązało problem.


#include <EEPROM.h>

#define PRZYCISK  0
#define RELAY  12
#define RELAY2 13
bool flaga = false;
uint8_t ile = 0;
unsigned long czas;
unsigned long czas_Pracy_Silnika = 40000;
uint8_t saveToEprom = 0;


void StoreEprom() {

  if (saveToEprom == 1) {
    Serial.println("<< Zapis do eprom <<");
    saveToEprom = 0;
    EEPROM.write(0, ile);
    EEPROM.commit();
  }
}
void setup() {
  Serial.begin(9600);
  EEPROM.begin(1024);
  pinMode(PRZYCISK, INPUT_PULLUP);
  pinMode(RELAY, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  digitalWrite(RELAY, HIGH);
  digitalWrite(RELAY2, HIGH);

  ile = EEPROM.read(0);
}

void loop() {
  StoreEprom();
  
  if (digitalRead(PRZYCISK) == LOW) {          //  Jesli wcisnieto przycisk.
    delay(50);                                   //   Odczekaj na drgania stykow.
    if (digitalRead(PRZYCISK) == LOW) {      //    Jesli przycisk ciagle jest wcisniety.
      while (digitalRead(PRZYCISK) == LOW); //     Czekaj na puszczenie.
      ile++;
      delay(10);

      if (ile == 1) {
        Serial.println("Przycisk Zamknij");
        digitalWrite(RELAY, LOW);
        czas = millis();
        flaga = true;
        saveToEprom = 1;
      }
      else if (ile == 2 ) {
        Serial.println("Stop Zamknij");
        digitalWrite(RELAY, HIGH);
        flaga = false;
        saveToEprom = 1;
      }
      else if (ile == 3) {
        Serial.println("Przycisk Otwórz");
        digitalWrite(RELAY2, LOW);
        flaga = true;
        czas = millis();
        saveToEprom = 1;
      }
      else if (ile == 4) {
        Serial.println("Stop Otwórz");
        digitalWrite(RELAY2, HIGH);
        flaga = false;
        ile = 0;
        saveToEprom = 1;
      }
    }
  }
  if (flaga) {
    if (millis() - czas >= czas_Pracy_Silnika) {
      if (ile == 1) {
        ile = 2;
      }
      if (ile == 3) {
        ile = 4;
      }
    }
    if (ile == 2) {
      Serial.println("Stop Po okresolym Czasie");
      digitalWrite(RELAY, HIGH);
      flaga = false;
      saveToEprom = 1;
    }
    if (ile == 4) {
      Serial.println("Stop Po Okreslonym Czasie");
      digitalWrite(RELAY2, HIGH);
      flaga = false;
      ile = 0;
      saveToEprom = 1;
    }
  }
}

 

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffdf0 end: 3fffffc0 offset: 01a0
3fffff90:  3fffdad0 00000000 00000000 4020112a  
3fffffa0:  3fffdad0 00000000 3ffee6a4 40201e08  
3fffffb0:  feefeffe feefeffe 3ffe85dc 40100c9d  
<<<stack<<<

 

Edytowano przez nebraska
Link do komentarza
Share on other sites

40 minut temu, nebraska napisał:
while (digitalRead(PRZYCISK) == LOW); //     Czekaj na puszczenie.
      ile++;
      delay(10);

Przeanalizuj tę część kodu, robisz pętlę w pętli nie dając możliwości zmiany kontekstu przez harmonogram zadań, task yield pomogło ale nie jest właściwym rozwiązaniem twojego problemu. 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

6 minut temu, _LM_ napisał:

Przeanalizuj tę część kodu, robisz pętlę w pętli nie dając możliwości zmiany kontekstu przez harmonogram zadań, task yield pomogło ale nie jest właściwym rozwiązaniem twojego problemu. 

Powinienem klamrami zamknąć?

Link do komentarza
Share on other sites

Nie, po prostu nie potrzebujesz tej pętli oczekującej na puszczenie przycisku. Z powodzeniem możesz to realizować w głównym wątku. Poszukaj tematów o maszynie stanów zdaje się że @ethanakpopełnił na ten temat artykuł. 

  • Lubię! 1
Link do komentarza
Share on other sites

while (digitalRead(PRZYCISK) == LOW)

{

delay(10);

}

Blokujesz program to WDT go restartuje.

Nie wiem skąd wpadła tu informacja, że flash ESP można zapisać 10k x, ESP nie ma wbudowanego flash, korzysta z zewnętrznych kostek, te w modułach jak ESP12F są we wspólnej puszce, mogą być np. Windbond i mają   100k zapisów, w ESP można wziąć 512B na EEPROM, zapis bajtu co 1s daje klikania na rok, można zapisywać 2 bajty, 01FF i 00FF, przesunięcie na kolejny adres jak się uruchamia ESP odczyt leci aż znajdzie FF, poprzedni bajt zawiera ostatni zapis kierunku, kolejny bajt FF, przy zapisie już normalnie, ostatni adres +1 if adres<511.  Ale generalnie kostki flash mogą być różne.

Korzystanie z EEPROM ESP bardziej mi przypomina jednak zapis do pliku, funkcje write czy put nic nie zapisują, jak się program zakończy w tym miejscu to po resecie stan pamięci jest bez zmian, trzeba na koniec zapisu dodać eeprom.end lub eeprom.commit. 

Znalazłem w pudle mój pierwszy ESP-01, flash 512kB, jakby był powód to mogę go podmienić na 4MB, więc postanowiłem go zajeździć  zapisując ciąg 8 bajtów z FFFF na końcu, potem przesuwam się na kolejny, przed efkami jeszcze dodałem CRC8 by sprawdzać czy zapis się powiódł i nie są to jakieś losowe głupoty, inkrementuję zmienną, wrzucam nowy CRC, zapisuję, odczytuję, sprawdzam CRC, leci wolno, po około 300 tysiącach zapisów zauważyłem że leci wolniej, na początku to było z 10x/sekundę teraz tak ze 2. Byłoby może szybciej gdybym nie wyrzucał kontrolnie na serial co robi. 

Parę razy obszar EEPROM mi się wywalił zamieniając wszystko na efki. Mam ESP na donglu i by mu wrzucić nowszą wersję wyszarpywałem go, zmieniałem na tryb flashowania i podłączałem na nowo. Najwyraźniej takich rzeczy nie lubi, jak z zapisywaniem plików. Jak dodałem mu zatrzymanie pracy po zwarciu GPIO0 do GND i dopiero wtedy wyciągałem z USB, to nawet wgranie nowego programu zachowuje zawartość "EEPROM" i leci mi dalej z miejsca gdzie skończył.

Także moje wnioski są takie, że do zapisania stanu inicjowanego z palca to by mnie przeżyłoby parę razy, czyli jak ktoś jest przy urządzeniu  i widzi, że się zapisało, ale do zapisania stanu na wypadek awarii zasilania to się nie nadaje, bo może się stać to samo co ja zrobiłem dwa razy wyszarpując dongla z USB.  

Może wyjaśnicie mi zagadkę, bo ja nie elektronik czy informatyk, jak zapisuję w strukturę elementy uint8_t+uint16_t+uint8_t+uint32_t to robi mi z tego 8 bajtów, no przeżyję, że bajty mi zapisuje w dwóch, może jakieś minimum, ale jak zamieniam ten uint16_t na uint32_t to już struktura miała 12 bajtów, po adresach pamięci zmiennych widzę, że pierwszy bajt zaczął zajmować 4 bajty w pamięci tak jak drugi element struktury, kolejne dalej po 2 bajty. I nie wiem po co?

 

Link do komentarza
Share on other sites

4 godziny temu, kaczakat napisał:

Nie wiem skąd wpadła tu informacja, że flash ESP można zapisać 10k x, ESP nie ma wbudowanego flash, korzysta z zewnętrznych kostek, te w modułach jak ESP12F są we wspólnej puszce, mogą być np. Windbond i mają   100k zapisów

 

Nie wiem skąd wziąłeś informacje że ESP nie ma wbudowanego flash 🙂

ESP8285 to ESP8266 z wbudowanym w strukturę flashem

Moduł ESP32 też ma wersje z wewnętrznym flash (np C3-12F-FN4)

 

No i mam wrażenie, że operowałem rzędem 100k a nie 10k zapisów...

Link do komentarza
Share on other sites

2 minuty temu, ethanak napisał:

Ja znalazłem i tak i tak - wolę przyjąć w tym przypadku mniejszą wartość.

Czyli jednak lepiej dmuchać na zimne zew EPROM i tak jak wcześniej pisałeś śpi się spokojnie.

Kurde sprzedawca dał ciała nie wysłał i jeszcze kości nie doszły.

Link do komentarza
Share on other sites

@nebraska przepraszam jeśli burzę całą dotychczasową dyskusję w tym wątku, przeczytałem jeszcze raz pierwszy post i tu moje skromne pytanie: czy na pewno potrzebujesz do takiego zastosowania aż takiej armaty? Urządzenie o którym mowa można przecież zbudować na attiny13 lub jeszcze mniejszym mikrokontrolerze. Już o przekaźnikach z pamięcią nie mówiąc. ESP zostawić sobie do bardziej ambitnych celów i zadań 

Edytowano przez _LM_
Link do komentarza
Share on other sites

2 minuty temu, _LM_ napisał:

@nebraska przepraszam jeśli burzę całą dotychczasową dyskusję w tym wątku, przeczytałem jeszcze raz pierwszy post i moje skromne pytanie: czy na pewno potrzebujesz do takiego zastosowania aż takiej armaty? Urządzenie o którym mowa można przecież zbudować na attiny13 lub jeszcze mniejszym mikrokontrolerze. Już o przekaźnikach z pamięcią nie mówiąc. Znów ESP zostawić sobie do bardziej ambitnych celów i zadań 

LM potrzebuje ponieważ urządzenie bedzie sterowane przez Suple. Piszę program do obsługi sterownika z możliwościa sterowania z przycisku i z apki tel. Będzie to połączone ze sobą włączam z przycisku wyłączam z Supli itd.  Ta część kodu będzie wdrozona do zródeł Supli. Poza tym Supla też zajmuj część epromu bo odbywają się tam zapisy strony cfg ustawień wifi całego tego mechanizu Supli do epromu w ESP, więc eprom zew jaknajabrdziej wskazany, żeby nie zawalić tego w esp.

Wiem, że powieniem o tym napisać na początku watku tak czułem że w końcu takie pytanie ktoś wywali😃

Link do komentarza
Share on other sites

5 minut temu, nebraska napisał:

LM potrzebuje ponieważ urządzenie bedzie sterowane przez Suple.

A no to zmienia postać rzeczy, na supli się aż tak nie znam, ale kojarzę coś że w konfiguratorze jest możliwość ustawienia aby moduł pamiętał ostatnie stany, tu myślę że więcej miałby do powiedzenia kolega @SOYER bo lubi się tym bawić.
 

 

5 minut temu, nebraska napisał:

Wiem, że powieniem o tym napisać na początku watku tak czułem że w końcu takie pytanie ktoś wywali😃

No i masz babo placek 😄

Edytowano przez _LM_
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.