Pomoc s EEPROM

milda
Příspěvky: 8
Registrován: 16 kvě 2018, 20:17
Reputation: 0

Pomoc s EEPROM

Příspěvek od milda » 16 srp 2018, 17:15

Zdravím lidi, chtěl bych pomoct s projektem... Potřebuju aby se mě do EEPROM ukládala teplota naměřená pomocí DHT22 každých 5 minut (Funkce EEPROM.put zajišťuje lepší využitelnost) poté potřebuji aby se mě objevila max/min teplota za 24 hodin. pomůže mě někdo s touto podmínkou? Vím, že se bude využívat toho LONG, ale nejsem schopný tu podmínku udělat. Vkládám screen mého kódu. Díky za případnou pomoc.
Přílohy
EEPROMOBR.jpg

rejze69
Příspěvky: 174
Registrován: 02 dub 2018, 18:56
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od rejze69 » 16 srp 2018, 19:07

Ahoj. Na co tam máš tu proměnnou cas? Co ten kód dělal původně a do čeho patřil?
Btw: kód vkládej copy/paste do code tohle tlacitko </>
Koukal jsem na reference a budeš muset porovnávat aktuálně čtenou teplotu s EEPROM. get() poslední uloženou hodnotou. Když bude vyšší, tak eeprom. update()
Asi tak. Jestli ti správně rozumim.

milda
Příspěvky: 8
Registrován: 16 kvě 2018, 20:17
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od milda » 17 srp 2018, 10:01

Tenhle projekt maji byt hodiny + teplomer s ukazatelem aktualnich hodnot + "pameti" ze pri stisku jednoho ze tri tlacitek se objevi max/min teplota za 24 hodin/ 1 tyden/ 1 mesic a k tomu bude cas kdy se ta dana teplota namerila...

AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od AstroMiK » 17 srp 2018, 17:59

V první řadě se asi nevyhneš použití nějakého RTC obvodu, který ti pomůže s prací s datumem a časem.
Přes funkci millis() bych se do toho asi nepouštěl.


A pak, jak píšeš o té nejvyšší a nejnižší teplotě za měsíc, tak to má znamenat co?

verze 1)
Rekordy platí pro kalendářní měsíc (červenec, srpen, září ...) - O půlnoci prvního dne v následujícím měsíci se starý rekord maže a zaznamenává se nový rekord.

verze 2)
Rekordy platí od aktuálního času 30 dní zpátky. Takže jestli je dneska 17.8. tak se hledá rekordní teplota mezi 18.7. až 17.8.



Podle odpovědi na předchozí otázku se bude výrazně lišit způsob záznamu hodnot.

Pokud bude odpověď 1), bude stačit aktuální teplotu porovnávat s rekordem měsíce (týdne / dne) a když rekord bude překročen, tak se přepíše aktuální hodnotou a někam se poznamená i aktuální čas.
Na konci měsíce (týdne / dne) se příslušné rekordy smažou a začne se od znova.
V tomhle případě se bude zaznamenávat v podstatě jen 6 rekordních teplot a k nim příslušející časy. (minimum dne, maximum dne, minimum týdne, maximum týdne a minimum kalendářního měsíce, maximum kalendářního měsíce).



Pokud ale bude odpověď 2), bude to znamenat trvalé ukládání velkého množství hodnot do nějakého pole, kde se nejstarší záznamy budou postupně přepisovat novými. Pak se před požadavkem na zobrazení rekordu bude muset projít zvolený úsek pole (30 dní zpátky / týden zpátky / 24 hodin zpátky) a vyhledat v tom úseku minima a maxima.

Problém v tomto případě bude to obrovské pole, které bude muset ukládat do nějaké externí RAM (nebo FRAM / EEPROM - v tomhle případě bych se nebál ani trvalého přepisovaní, protože jedna buňka se nepřepíše dřív, než za měsíc).
Pokud bude teplota nějak upravená, aby se jedna hodnota vešla do dvou bajtů a bude se provádět měření každých 5 minut, vychází z toho velikost pole pro měsíc staré záznamy skoro 20kB dat.
(12 záznamů za hodinu * 24 hodin za den * 30 dní * 2 bajty)

milda
Příspěvky: 8
Registrován: 16 kvě 2018, 20:17
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od milda » 18 srp 2018, 13:33

Jasně chápu, ta 1. možnost bude určitě stačit. momentálně jsem na tom s kódem takto. Fungují mi všechny tlačítka, jenom potřebuji nějak udělat tu podmínku s ukládáním do EEPROM už mě jede i to "odpočítavadlo" času. To u modrého vykřičníku bude patřit do toho posledního tlačítka okamzita, jenom se mě to neposouvá displej a nenačítají se teploty/čas budu tam muset nejspíš dát taky nějaké odpočítavadlo pro posun a načítání nových hodnot, nemůžu tam dát delay, kvůli tomu počítání funkce millis(). Červené kolečka znázorňují tlačítka.
Přílohy
forum.jpg

rejze69
Příspěvky: 174
Registrován: 02 dub 2018, 18:56
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od rejze69 » 18 srp 2018, 16:23

To vážně nemůžeš vkládat ty sketche jako kód a ne v obrázku? Zkus to a uvidíš, že to bude jednodušší i pro Tebe. A co teprv pro ty, kteří Ti budou chtít poradit.

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Pomoc s EEPROM

Příspěvek od petan » 18 srp 2018, 20:40

jj, obrázky jsou naprd. Vkládej kód!

Kód: Vybrat vše

//VKLÁDEJ KÓD :-P
//NE OBRÁZKY. TY TI NIKDO DEBUGOVAT NEBUDE.
Připoj si na to RTC modul a ve smyčce (třeba 1s) kontroluj čas. Min a max hodnotu za den vynuluj vždy v 00:00. Hodnotu za týden ve stejný čas, ale pokud je proměnná den 2 (pondělí) a hodnoty za měsíc vždy prvního o půlnoci.

Každou pátou sekundu (když sekundy končí 0, nebo 5) if(sec % 5 == 0) naměř teplotu a porovnej s jednotlivýma min a max (je to celkem 6 proměnných pro den, týden a měsíc). Pokud je hodnota menší, než MIN, tak ji přepiš. Pokud je hodnota větší, než MAX, tak ji přepiš.

Jednou za čas, třeba za hodinu (třeba nultou minutu a nultou sekundu) si ulož data do EEPROM. Ta není dělaná na moc časté zapisování. Program ti může běžet v RAMce, pokud ti vypadne elektrika, tak se ti vymaže maximálně jedna hodina dat.

Podmínky jsou v tomto případě jednoduchý, protože vše můžeš synchronizovat časem. Jenom si pomocí podmínek vytvoříš, kdy se co bude spouštět.

milda
Příspěvky: 8
Registrován: 16 kvě 2018, 20:17
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od milda » 18 srp 2018, 22:27

Tady je ten kod.

Kód: Vybrat vše

#include <DS3231.h>
DS3231  rtc(SDA, SCL);                // Inicializace portů

#include "DHT.h"
#define DHTPIN 2                               // PIN
#define DHTTYPE DHT22                          // DHTtyp
DHT dht(DHTPIN, DHTTYPE); 

#include <config.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int den = 5;   // choose the input pin (for a pushbutton)
int buttonDen =0;
const int tyden = 6;   // choose the input pin (for a pushbutton)
int buttonTyden =0;
const int okamzita = 7;   // choose the input pin (for a pushbutton)
int buttonOkamzita =0;

long cas=millis; 
int sec = 0L;
int mili = 0L;
int vter = 0L;
int minu = 0L;
int hod = 0L;

void setup() {
  
  Serial.begin(9600);
    
  pinMode(den, INPUT);
  pinMode(tyden, INPUT);

  dht.begin();
  
  lcd.begin(); 

  Serial.begin(9600);                 // Rychlost kominukace
  rtc.begin();                              // Nastavení  dnu, času, data
  rtc.setTime(17, 39, 00);     // Čas 12:00:00 (24h)
  rtc.setDate(14, 10,2018);   // Datum den/měsíc/rok
 
}

void loop() {
 
 static float sec;
 static float mili;
 static float vter;
 static float minu;
 static float hod;

 if (cas = 1000);{
   sec=sec + 1;
 cas = 0;
 }
 if(sec==60);{
    mili=mili+1;
    sec=0;
 }  
  if(mili==60) { 
    vter=vter+1;
    mili=0; 
 }
  if(vter==60) { 
    minu=minu+1;
    vter=0; 
 }
  if(minu==60) { 
    hod=hod+1;
    minu=0; 
 }

  float h = dht.readHumidity();               
  float t = dht.readTemperature();             

  buttonDen = digitalRead(den);
  if (buttonDen == HIGH) {         
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("den ");  // stisknuto
  } else {
    Serial.print(" ");
  }
  
  buttonTyden = digitalRead(tyden);
  if (buttonTyden == HIGH) {         
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("tyden");  // stisknuto
  } else {
    Serial.print(" ");
  }
  buttonOkamzita = digitalRead(okamzita);
  if (buttonOkamzita == HIGH) {        
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("okamzita");  // stisknuto
  } else {
    Serial.print(" ");
  }

}
Vůbec nechápu první dva odstavce co jsi napsal. Jojo, šlo by to nejspíš i v RAM, ale mám vysloveně za úkol to udělat do EEPROM vím, že je tam omezený počet zápisu a to bych vyřešil tím, že se to bude ukládat každých 5 minut. Podmínky moc jednoduché nejsou, aspoň ne pro mě :D . jediné věci co mě tam teda chybí jsou, aby se při stisku jednotlivých tlačítek objevily naměřené hodnoty s časem pořizení + jedno tlačítko by mělo ukazovat aktuální hodnoty.

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Pomoc s EEPROM

Příspěvek od petan » 19 srp 2018, 10:32

Rozmysli se, co nejdřív chceš dělat. Mícháš dvě věci. počítání min. a max. hodnoty a zobrazování. Nejdřív si odlaď jednu věc a pak se pusť do druhé. Nahoře v kódu importuješ knihovnu pro DS3231 (modul RTC), ale vzápětí počítáš sekundy "ručně". To je nějaká matlanina... Máš tam ten modul, nebo nemáš? Pokud stavíš hodiny, tak tam stejně ten modul budeš muset dát.

Koukni sem: https://www.mylms.cz/text-kusy-kodu-k-arduinu/#delay Pomocí tohoto kódu si vytvoříš smyčku, která se ti bude spouštět jednou za určitý čas (třeba přibližně jednou za sekundu).

V této smyčce budeš číst data z modulu reálného času tímto kódem: https://www.mylms.cz/text-kusy-kodu-k-arduinu/#ds3231. Odteď máš v programu reálný čas, na který se můžeš spolehnout. V této smyčce můžeš navíc vykreslovat na displej. Jednou za sekundu to stačí.

Stejně tak si můžeš vytvořit smyčku, která bude třeba jednou za těch 5 minut číst teplotu a ukládat minimální a maximální teplotu. Stejně je ten první příklad na dva časy, tak tam ani nebudeš muset nic upravovat.

Zobrazení času bych udělal tak, že bych si vytvořil proměnou byte mode; a podle jejího stavu vykresloval na displej určitá data. pokud je mode == 0 tak třeba aktuální čas a teplotu, pokud mode == 1 tak min a max ze dne atd...

Kód: Vybrat vše

//toto bude ve hlavní smyčce loop, aby to reagovalo rychle
if(digitalRead(okamzita)) mode = 0;
if(digitalRead(den)) mode = 1;
if(digitalRead(tyden)) mode = 2;

//toto bude ve smyčce vykreslování, stačí třeba jednou za sekundu
switch (mode ) {
  case 0:
    //vykreslování aktuální teploty
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("okamzita");  // stisknuto
    break;
  case 1:
    //vykreslení teplot za den
    break;
    case 2:
    //vykreslení teplot za tyden
    break;
}
To je ohledně měření a vykreslování. Samotnou kapitolou je počítání minimální a maximální teploty. Stále nevím, jakou výraznou výhodu má hrnout to do EEPROM, ale budiž. V podstatě to je stejné, jako běžná RAM, ale musí se s tím trošku jinak zacházet. Nicméně platí to, co jsem psal výše. V sekundové smyčce vytvořit podmínku, která se podle času z RTC modulu spustí jednou za těch 5 minut (koukám, že tam mám podmínku na sekundy). Jinak "výpočet" je stále stejný. Porovnávat uloženou teplotu a v případě rozdílu přepsat.
Ještě co se týče EEPROM a přesnosti, doporučuju ti ještě zamyslet se nad tím jakou potřebuješ přesnost. Teplota by se dala převést na jeden bajt, takže by ti to nežralo tolik paměti. Ale pokud na to používáš knihovnu, tak je to asi z pohledu ovládání jedno.

milda
Příspěvky: 8
Registrován: 16 kvě 2018, 20:17
Reputation: 0

Re: Pomoc s EEPROM

Příspěvek od milda » 21 srp 2018, 16:01

DS3231 tam mám. ručně se tam snažím dát jenom to ukládání každých 5 minut jinak normální čas mě počíta DS3231. díky za ty stránky nějak se to tam pokusím dát a dám sem výsledek co mě z toho vznikl. Jojo ohledně té přesnosti jsem taky uvažoval, ale podle mě to stačí tak jak to je na ty 2 desetinné místa.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 5 hostů