Skocz do zawartości

Zapis do eeprom


Grzeg

Pomocna odpowiedź

Witam, potrzebuję przerobić poniższy kod tak aby czas który ustawi się z przycisków ( ustawiony jest czas 90 sek a przyciskami zwiększa się bądź zmniejsza ten czas) po naciśnięciu przycisku start był zapisywany do pamięci nieulotnej. Próbowałem sam to zrobić używając poradników i opisów funkcji ale niestety nie udało mi się tego zrobić .

Mókłby ktoś pomóc ?

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int kompresor = 8;    
#define pinUP 13       
#define pinDOWN 7      
#define pinOK 0      
int pin2 = 10;
long start;            
int czas;              
int minuty;
int sekundy;
int pin_dioda = A5;
int pin_przycisk = A3;

void pokazCzas(int c)  // c - aktualny czas procesu
{
 char buf[20]; memset(buf, 0, sizeof(buf)); 
 minuty = c / 60; sekundy = c % 60;      
 if (minuty > 59) {
   minuty = 0;  // po przekroczeniu 60 minut liczymy od nowa
   sekundy = 0;
 }
 snprintf(buf, sizeof(buf), "%02d:%02d", minuty, sekundy);
 lcd.setCursor(6, 1); lcd.print(buf); // kosmetyka LCD
}
// --- funkcja do ustawiania czasu trwania procesu -----------------
int ustaw(int c)     // c - defaultowy czas (na poczÄ…tek do ustawiania)
{
 lcd.clear();
 lcd.setCursor(0, 0); lcd.print("<  Ustaw Czas  >");
 pokazCzas(c);                     // pokazujemy czas procesu do ustawienia
 while (digitalRead(pinOK != LOW)) // trwa tak długo aż naciśniemy przycisk OK
 {
   if (digitalRead(pinUP) == LOW) {
     delay(30);  // klawisz +
     if (digitalRead(pinUP) == LOW) {
       c += 10;
       if (c > 1800)c = 1800;
       pokazCzas(c);
     }
   }
   if (digitalRead(pinDOWN) == LOW) {
     delay(30);  // klawisz -
     if (digitalRead(pinDOWN) == LOW) {
       c -= 10;
       if (c < 0)c = 0;
       pokazCzas(c);
     }
   }
   delay(100);                      
 }
 lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Czas Ustawiony "); delay(2000); //
 return c;  // funkcja zwraca ustawiony czas
}
// --- funkcja do odliczania czasu (zapalnik zegarowy do bomby :-)---
void odliczanie(int ile)
{
 start = millis();                   // startujemy funkcjÄ… millis()
 int akt_czas = ile;                 // zmienna pomocnicza do ĹĽonglerki czasem
 while (akt_czas > 0)                // tak długo, aż odliczanie się nie skończy
 {
   akt_czas = czas - (millis() - start) / 1000; // ĹĽonglerka czasem
   pokazCzas(akt_czas);                 // pokaz czasu jaki pozostał
   if (digitalRead(pinOK) == LOW)       // jeśli wciśniesz OK to natychmiastowe przerwanie procesu
   {
     akt_czas = 0; pokazCzas(akt_czas); // zerowanie czasu
     lcd.setCursor(0, 1); lcd.print("Proces Przerwany"); delay(2000); // kosmetyka
   }
 }
}

// --------------------------------------------------------------
void setup ()
{
 pinMode(pinUP, INPUT_PULLUP);   // klawisz +
 pinMode(pinDOWN, INPUT_PULLUP); // klawisz -
 pinMode(pinOK, INPUT_PULLUP);   // klawisz OK
 pinMode(kompresor, OUTPUT);
 pinMode(led, OUTPUT);
 pinMode(reczne, INPUT_PULLUP);
 pinMode(pin_przycisk, INPUT_PULLUP);
 pinMode(pin_dioda, OUTPUT);
 lcd.begin(16, 2);
 digitalWrite(led, HIGH);          
 digitalWrite(kompresor, HIGH);       
 lcd.clear(); lcd.setCursor(3, 0); lcd.print("Gotowy za : ");
 czas = 2;       // czas nagrzewania w sekundach 60 = 1 min.
 odliczanie(czas); ‚
 lcd.clear();
}

// -----------------------------------------------------------
void loop ()
{

 czas = ustaw(110);
 lcd.clear(); lcd.print("Start odliczania"); 
 digitalWrite(kompresor, LOW); digitalWrite(led, LOW); //
 delay(250); digitalWrite(kompresor,LOW );
 odliczanie(czas);                          // start odliczania
 digitalWrite(led, HIGH); delay(250); digitalWrite(kompresor, HIGH); 
 lcd.clear(); lcd.print("  Koniec Cyklu"); delay(3000); lcd.clear();   
}

Link do komentarza
Share on other sites

korzystałem z biblioteki EEPROM.h. i z funkcji EEPROM.read oraz EEPROM.write

Mam problem żeby zapisać w pamięci czas w postaci minuty:sekundy. Za każdym razem program liczy od 0 do 255.

Nie chodzi mi o to żeby ktoś tu dął gotowca ... chodzi mi o przykład na podstawie którego mógłbym sam to pojąc albo o wytłumaczenie mi jak mam zrobić top

Link do komentarza
Share on other sites

Zastanów się na początek nad dwoma rzeczami:

1. Zakładając, że w pamięci EEPROM masz już zapisany czas to gdzie w powyższym kodzie powinieneś wstawić odczyt tego zapisu i jak go wykorzystasz?

2. Zakładając, że zapisy do pamięci EEPROM powinny być ograniczone do minimum, gdzie w kodzie powinieneś wstawić zapis/zapamiętanie czasu?

Na razie nie myśl o szczegółach wykonania. Odpowiedz sobie tylko na te dwa pytania i pokaż nowy program w którym zaznaczyłeś odpowiednie miejsca np. komentarzami typu "Tu będzie zapis czasu ze zmiennej blabla", "Tu będzie odczyt do zmiennej takiejśmakiej".

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

// -------------------------------------------------------------- 
void setup () 
{ 
   Tutaj powinien być zapis do pamięci 

 pinMode(pinUP, INPUT_PULLUP);   // klawisz + 
 pinMode(pinDOWN, INPUT_PULLUP); // klawisz - 
 pinMode(pinOK, INPUT_PULLUP);   // klawisz OK 
 pinMode(kompresor, OUTPUT); 
 pinMode(led, OUTPUT); 
 pinMode(reczne, INPUT_PULLUP); 
 pinMode(pin_przycisk, INPUT_PULLUP); 
 pinMode(pin_dioda, OUTPUT); 
 lcd.begin(16, 2); 
 digitalWrite(led, HIGH);          
 digitalWrite(kompresor, HIGH);        
 lcd.clear(); lcd.setCursor(3, 0); lcd.print("Gotowy za : "); 
 czas = 2;       // czas nagrzewania w sekundach 60 = 1 min. 
 odliczanie(czas); ‚ 
 lcd.clear(); 
} 

void loop () 
{ 
// tu powinien być odczyt czasu zapisany w pamięci 
 czas = ustaw(110);   
 lcd.clear(); lcd.print("Start odliczania"); 
 digitalWrite(kompresor, LOW); digitalWrite(led, LOW); // 
 delay(250); digitalWrite(kompresor,LOW ); 
 odliczanie(czas);                          // start odliczania 
 digitalWrite(led, HIGH); delay(250); digitalWrite(kompresor, HIGH); 
 lcd.clear(); lcd.print("  Koniec Cyklu"); delay(3000); lcd.clear();    
} 
Link do komentarza
Share on other sites

Moim zdaniem zupełnie nie.

Przecież setup() wykonuje się tylko raz, po włączeniu zasilania. Tam raczej powinien się znaleźć odczyt kiedyś tam zapamiętanego czasu i przyporządkowanie go do Twojej zmiennej, zamiast jej inicjalizacja na przykładowe 120.

To samo w loop(). To się wykonuje w kółko a nowy czas powinieneś zapamiętywać w EEPROM tuż PO jego ustawieniu przyciskami, czyż nie?

Myśl o EEPROMie jak o używaniu kamiennej tabliczki. Odczytanie z niej nie jest trudne i możesz to robić bezkarnie wielokrotnie, ale zapis jest bardzo bolesny i powolny - trzeba zetrzeć to co było wyskrobane wcześniej i potem jeszcze porobić nowe napisy dłutem i młotkiem. A tabliczka po każdym wymazaniu jest coraz cieńsza..

Czekamy na podejście nr 2.

Link do komentarza
Share on other sites

#include<EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int kompresor = 8;     
#define pinUP 13        // klawisz +   pin 2
#define pinDOWN 7      // klawisz -   pin 1
#define pinOK 0      // klawisz OK  pin 0
int pin2 = 10;
long start;            
int czas;              
int minuty;
int sekundy;



void pokazCzas(int c)  // c - aktualny czas procesu
{
 char buf[20]; memset(buf, 0, sizeof(buf)); 
 minuty = c / 60; sekundy = c % 60;       
 if (minuty > 59) {
   minuty = 0;  
   sekundy = 0;
 }
 snprintf(buf, sizeof(buf), "%02d:%02d", minuty, sekundy);
 lcd.setCursor(6, 1); lcd.print(buf); // kosmetyka LCD
}
// --- funkcja do ustawiania czasu trwania procesu -----------------
int ustaw(int c)     // c - defaultowy czas (na poczÄ…tek do ustawiania)
{
 lcd.clear();
 lcd.setCursor(0, 0); lcd.print("<  Ustaw Czas  >");
 pokazCzas(c);                     
 while (digitalRead(pinOK != LOW)) 
 {
   if (digitalRead(pinUP) == LOW) {
     delay(30);  // klawisz +
     if (digitalRead(pinUP) == LOW) {
       c += 10;
       if (c > 1800)c = 1800;
       pokazCzas(c);
     }
   }
   if (digitalRead(pinDOWN) == LOW) {
     delay(30);  // klawisz -
     if (digitalRead(pinDOWN) == LOW) {
       c -= 10;
       if (c < 0)c = 0;
       pokazCzas(c);


     }
   }
   delay(100);                      
 }
 lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Czas Ustawiony "); delay(2000); //
 return c;  // funkcja zwraca ustawiony czas

 [b] Tutaj powinien być zapis do EEPROM'u [/b]
}

void odliczanie(int ile)
{
 start = millis();                  
 int akt_czas = ile;                
 while (akt_czas > 0)               
 {
   akt_czas = czas - (millis() - start) 
   pokazCzas(akt_czas);                 
   if (digitalRead(pinOK) == LOW)       
   {
     akt_czas = 0; pokazCzas(akt_czas); // zerowanie czasu
     lcd.setCursor(0, 1); lcd.print("Proces Przerwany"); delay(2000); 
   }
 }
}


void setup ()
{

 pinMode(pinUP, INPUT_PULLUP);   // klawisz +
 pinMode(pinDOWN, INPUT_PULLUP); // klawisz -
 pinMode(pinOK, INPUT_PULLUP);   // klawisz OK
 pinMode(kompresor, OUTPUT);
 pinMode(led, OUTPUT);
 pinMode(reczne, INPUT_PULLUP);
 pinMode(pin_przycisk, INPUT_PULLUP);
 pinMode(pin_dioda, OUTPUT);
 lcd.begin(16, 2);
 digitalWrite(led, HIGH);          
 digitalWrite(kompresor, HIGH);       
 lcd.clear(); lcd.setCursor(3, 0); lcd.print("Gotowy za : "); // kosmetyka
 czas = 2;      .
 odliczanie(czas); 
 lcd.clear();
}

void loop ()
{

 czas = ustaw(110);  [b] Tutaj powinien być odczytany czas z EEPROM'u [/b]

 lcd.clear(); lcd.print("Start odliczania");// kosmetyka
 digitalWrite(kompresor, LOW); digitalWrite(led, LOW); 
 delay(250); digitalWrite(kompresor,LOW );
 odliczanie(czas);                        
 digitalWrite(led, HIGH); delay(250); digitalWrite(kompresor, HIGH);
 lcd.clear(); lcd.print("  Koniec Cyklu"); delay(3000); lcd.clear(); 
}


Czy teraz dobrze myślę ? i czy w takim wypadku trzeba użyć funkcji : EEPROM.update() ?

Link do komentarza
Share on other sites

Jeśli jesteś autorem tego programu, to z pewnością wiesz co, jak i kiedy on robi, prawda? To mamy kolejną iterację:

1. Jeśli chcesz, by po włączeniu zasilania procesor odczytał sobie z EEPROMu wcześniej zapisany czas, to musisz znaleźć w kodzie miejsce, które wykonywane jest tylko raz, właśnie po starcie. Gdzie to jest? Znajdź to miejsce (tę funkcję) i tam wstaw odczyt EEPROMu. W loop() tylko korzystaj z tej odczytanej (lub nowo ustawionej) wartości.

2. Zapis EEPROMu wstawiłeś po instrukcji return? Nie wykona się nigdy. Nie rób tego na chybcika, to nie wyścig. Jeśli już coś do kodu wstawiasz, przemyśl sobie jak on będzie z tą nową poprawką działał. Przebiegnij oczami (lub palcem) kolejne linie kodu, prześledź warunki if-ów, wywołania funkcji i zastanów się czy zmiana ma sens. Dobrze, że jesteś z zapisem w funkcji ustaw(), ale nie to miejsce. Znajdź takie, w którym właśnie skończyłeś ustawianie nowego czasu. To nie może być linia która wykonuje się za każdym wywołaniem funkcji, bo wtedy częste zapisy do EEPROMu zniszczą go szybko. W którym miejscu program uznaje, że ma już nowo obowiązujący czas?

I na marginesie:

Po co w loop() dwa razy w odstępie 250ms zerujesz wyjście kompresor? Dla pewności?

To chyba nie jest wygodne, gdy program zamiera na 2 czy 3 sekundy po to by wyświetlić jakiś napis? W każdym razie ja bym uznał, że coś zwisło i poszukał wyłącznika lub resetu. We współpracy z ludźmi unikaj delay'ów jak ognia. Urządzenie musi być zawsze responsywne, bo niedziałające klawisze robią wrażenie poważnej awarii lub zwiechy programu.

Link do komentarza
Share on other sites

Kod nie jest mojego autorstwa, aczkolwiek został zmodyfikowany pod moje potrzeby.

kombinuje już któryś dzień z funkcjami eeprom get i put

wiem ze tych funkcji używa się tylko przy zmiennych typu float ,

 lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Czas Ustawiony "); delay(2000); //
 t = (float) c+10;
 EEPROM.put (4,t);
 return c;  // funkcja zwraca ustawiony czas


to tez dodałem takie o to "równanie" żeby zamienić c na t w float.

dodałem w "setup'

 EEPROM.get(4,t);

a w loop

czas = t;                          
 lcd.clear(); lcd.print("Start Odliczania"); 
 delay(250); digitalWrite(kompresor, HIGH);
 odliczanie(czas);                         
 delay(250); digitalWrite(kompresor, LOW); 
 lcd.clear(); lcd.print("  Koniec Cyklu"); delay(3000); lcd.clear();

problem w tym ze program nie widzi w cale czasu :/ odrazu jest komunikat start odliczania i następnie konie :/

Proszę o pomoc

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.