Rtc és eltelt idő számítása.

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 18. vasárnap, 9:35

Sziasztok!

Építek egy tojáskeltetőt, amiben igen fontos lenne az eltelt idő pontos mérése.
Amit meg szeretnék valósítani, hogy az rtc-ből kiolvasom az elinduláskor az időt és tárolom egy változóban, amihez hasonlítom a jelenlegi időt. Ebből szeretném kiszámolni, hogy hány nap telt el az indítás óta.

Az alapokkal tisztában vagyok, de ez meghaladja a képességeimet...

Próbáltam, hogy a ciklusokoat számoltam. Egy ciklus 6mp volt. Így egy nap 14400 ciklus lett. 5 percig számoltam és 1mp késés jött ki, ami egy keltetés alatt elenyésző. Azonban futtattam egy napig a rendszert probaképp, és 12 óra alatt már 3 napnyi ciklus futott le!?!? Ergo egyáltalán nem megbízható.

Az arduino egy uno, az rtc pedig egy ds3231.
_______________________________________________________

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 18. vasárnap, 12:56

Ez a timing dolog nekem nem teljesen tiszta, mert nem tudom, hogy a kiolvasott idő/dátum értéket hogy tudom vizsgáltatni, úgy, hogy nem egy adott dátummal hasonlítom össze, hanem az indulási időponthoz képest pl 2 nappal...
Remélem érti valaki, hogy mire gondolok :D
_______________________________________________________

vargham
Pákabűvész
Hozzászólások: 227
Csatlakozott: 2014. január 8. szerda, 8:32
Kapcsolat:

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: vargham » 2018. március 18. vasárnap, 14:05

Nem, nem értem.
Induláskor kiolvasod az időt az órából, elteszed egy változóba.
Rendszeres időközönként újra kiolvasod az időt, és összehasonlítod az eltárolttal.
Semmilyen ciklusidőt nem kell méregetni.
De van ebben az óra IC-ben lehetőség 2 riasztás beállítására is. Amikor eléri a beállított időt, megszakítást küld az MCU-nak. Az MCU pedig akár aludhat is, majd felébreszti a megszakítás. Elvégzi a teendőket, beállítja az újabb riasztást, majd vissza alszik.

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 18. vasárnap, 14:25

Az megvan, hogy kiolvasom, de milyen típusú változóba teszem? Illetve hogy tudok hozzáadni, hogy utána az összehasonlításhoz elő tudjam kapni?

A 2 riasztás kevés sajnos. Több változás van egy keltetési ciklus alatt. Páratartalom egy 17 napos ciklus alatt 1x, hűmérséklet 3x változik.
Illetve a riasztáshoz is a kiolvasott és elmentett időhöz kellene hozzáadnom, amit még mindig nem tudok, hogy álljak neki.

Illetve az se tiszta, hogy az indulás után eltelt órákat hogy tudom számolni?
_______________________________________________________

vargham
Pákabűvész
Hozzászólások: 227
Csatlakozott: 2014. január 8. szerda, 8:32
Kapcsolat:

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: vargham » 2018. március 18. vasárnap, 14:36

> hogy tudok hozzáadni, hogy utána az összehasonlításhoz elő tudjam kapni?
Google "arduino rtc elapsed time"
Első két találat:
https://playground.arduino.cc/Code/Time
http://forum.arduino.cc/index.php?topic=227313.0

> A 2 riasztás kevés sajnos.
Annyi riasztást kezelsz szoftveresen, amennyit akarsz. Megnézed, hogy mikor esedékes a következő esemény, beállítod a riasztást az RTC-ben, és altatod az MCU-t. Az RTC-nek mindig csak a KÖVETKEZŐ riasztást kell tudnia, nem az összeset.

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 18. vasárnap, 17:34

Ha jól értem, akkor így lesz jó nekem:

Kód: Egész kijelölése

t = rtc.getTime();
const int heat1 = t+24;
int maxTemp = 37.5;

loop{
now = rtc.getTime();
if(now = heat1){
   maxTemp = 37.8;}
   if (temp < maxTemp) {digitalWrite(heating, HIGH)};
      else {digitalWrite(heating, LOW);}
}


HA jól értem! :D Bár még mindig nem tudom, hogy tudom hozzáadni pontosan óraszámot...
_______________________________________________________

Avatar
csegebiga
Chipgyilok
Hozzászólások: 283
Csatlakozott: 2015. március 27. péntek, 21:27

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: csegebiga » 2018. március 18. vasárnap, 19:18

Én a helyedben beírnám a keresőbe itt a fórumon, hogy ds3231 és megnézném, mit diskuráltak erről a chipről mások.
Akkor nem kellene mindent egymagad kitalálnod.
Pl: viewtopic.php?f=23&t=1918&hilit=ds3231
https://learn.adafruit.com/adafruit-ds3 ... uino-usage

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9904
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: Robert » 2018. március 18. vasárnap, 19:57

Még 1 ötlet:
A startidőtől kezdve mindent másodperc alapon kezelsz.
Linux time: 1970.01.01 00:00 óta eltelt idő mp-ben. (2041-ben lesz tólcsordulása csak).
http://www.tavir.hu - a gazda :)

Avatar
csegebiga
Chipgyilok
Hozzászólások: 283
Csatlakozott: 2015. március 27. péntek, 21:27

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: csegebiga » 2018. március 18. vasárnap, 21:53

mégegyszerűbb:
mivel a tojásnak tökmindegy , hogy milyen dátumot írunk, ezért az rtc-t nem is kell az aktuális dátumra beállítani.
induljon a keltetési szekvencia 01.01.0100:00:00 kor, tartson az első szakasz pl 01.01.07 12:00.00ig
kétféleképpen +sütheted el az áramkört a cél időpontban:
1. beállítod az rtc alarm regisztereit, és a chip által generált int jelet lekezeled, majd beállítod a következő alarm idöpontot
2. figyeled, hogy a rtcDay egyenlő-e a célDay értékkel? ha igen, a rtcHour=a célJour-ral, ha igen, a rtcMin= a célMin-nel? ha igen, idő van! elvégzed a teendőket, és beállítod a következő cél időpontot

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 19. hétfő, 7:22

csegebiga írta:mégegyszerűbb:
mivel a tojásnak tökmindegy , hogy milyen dátumot írunk, ezért az rtc-t nem is kell az aktuális dátumra beállítani.
induljon a keltetési szekvencia 01.01.0100:00:00 kor, tartson az első szakasz pl 01.01.07 12:00.00ig
kétféleképpen +sütheted el az áramkört a cél időpontban:
1. beállítod az rtc alarm regisztereit, és a chip által generált int jelet lekezeled, majd beállítod a következő alarm idöpontot
2. figyeled, hogy a rtcDay egyenlő-e a célDay értékkel? ha igen, a rtcHour=a célJour-ral, ha igen, a rtcMin= a célMin-nel? ha igen, idő van! elvégzed a teendőket, és beállítod a következő cél időpontot


A kettes megoldás ami nekem szimpatikus. Józan ésszel átgondolva, úgy látom hogy így ki lehet hagyni egy lépést, az alarm beállítást.
Még egy hülye kérdés: nekem nem kell másodperc pontosan, továbbgondoltam és szerintem elég lesz napos ciklusban is. Az az 1-2% rossz kikelési arány mindenképp megmarad sajnos.

Akkor ez így lenne jó? Illetve rednesen lereagálja a véltozóm, hogy pl 29-én hozzáadok 6-ot? Értem úgy, hogy nem lesz belőle 35 és nem teljesül soha a ciklus?

Kód: Egész kijelölése

startDay = x;
célDay = startDay;
loop{

if (célDay = startDay){
tedd amit kell;
célDay = célDay +2;}

if (célDay = rtcDay){
tedd amit kell;
célDay = célDay + 4;}

if (célDay = rtcDay){
tedd amit kell;
célDay = célDay + 2;}

_______________________________________________________

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3231
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: kapu48 » 2018. március 19. hétfő, 10:12

Itt sok mindent megtanulhatsz:
[PDF]talk22: A DS1307 és DS3231 valósidejű órák használata (Arduino)
http://megtestesules.info/hobbielektron ... talk22.pdf



Kód: Egész kijelölése

void setup() {
  // put your setup code here, to run once:
startDay = x;
célDay = startDay + kovetkezo;
}

void loop() {
  // put your main code here, to run repeatedly:
if (célDay == startDay){ // Helyesen. A feltétel vizsgálat jele == egyenlő e?
tedd amit kell;
célDay = célDay +2;}

if (célDay == rtcDay){
tedd amit kell;
célDay = célDay + 4;}

if (célDay == rtcDay){
tedd amit kell;
célDay = célDay + 2;}
}

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 19. hétfő, 10:31

Köszönöm nagyon hasznos a motyó és a javításod is :)
_______________________________________________________

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9904
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: Robert » 2018. március 19. hétfő, 10:54

A program az utasításaid szerint működik.

29+4 = 33. Azaz _soha_ nem teljesül, mert az ÓraIC tudja belül, ha átcsordulás van, akkor bizony a nap léptet....
És így soha nem teljesül a nap eltelése...

Miért nem maradsz másodperc v. perc alapon az _indítás óta_ eltelt idővel?


Amivel számolj még:
- áramszünet/reset és az Arduino újraindul (hol tartottál? Mi a köv. lépés?),
- távoli debug/hozzáférés - eseménykövetés,
- hiányzik a folyamatlogolás (hőfok és páratartalom).
http://www.tavir.hu - a gazda :)

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3231
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: kapu48 » 2018. március 19. hétfő, 12:59

Példa, Egyszerű keltető:
DHT22 hő és páratartalom mérő
DS3231 RTC
I2C_LCD 16*2 kijelző.
ventilátor relé
izzó1 relé
izzó2 relé
párásító relé

Kód: Egész kijelölése

// keltetogep.ino
#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include "math.h"
 
int maxHum = 80;
int maxTemp = 37.3;
long cnt = 0;
int osztott = 0;

LiquidCrystal_I2C lcd(0x27,16,2);
#define BUFF_MAX 128
#define DHTPIN 2     // szenzorpin
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define fan 8 // ventilátor relé
#define heat1 9 // izzó1 relé
#define heat2 10  //izzó2 relé
#define hum 11  // párásító relé

uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;

DHT dht(DHTPIN, DHTTYPE);

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    dht.begin();
    pinMode(fan, OUTPUT);
    pinMode(heat1, OUTPUT);
    pinMode(heat2, OUTPUT);
    pinMode(hum, OUTPUT);
    DS3231_init(DS3231_INTCN);
    memset(recv, 0, BUFF_MAX);
    lcd.init();
    lcd.backlight();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" TYUKANYO  v1.1");
}

void loop()
{
    delay (1800);
    char in;
    char tempF[6];
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;
    float hu = dht.readHumidity();
    float tm = dht.readTemperature();

    if (isnan(hu) || isnan(tm)) {
    Serial.println("Szenzorhiba 02!");
    lcd.clear();
    lcd.print("Szenzorhiba 02!");
    return;
    }

//rendszerszámláló, forgatásjelző   
osztott = (cnt/2400)+1;
round(osztott);
   lcd.clear();
   lcd.setCursor(5,0);
   lcd.print(osztott);
   lcd.print(". nap");
   lcd.setCursor(0,1);
   lcd.print (cnt);
   lcd.print (" ciklus");
if (osztott >= 2 && osztott <= 16) {lcd.setCursor(0,1);
                         lcd.print("Ma forgatni kell!");}
           
delay(1800);

//időarányos hűmérséklet és párabeállítás

if (osztott <= 16) {maxHum = 60;}
if (osztott > 16) {maxHum = 80;}
if (osztott <= 8) {maxTemp = 37.8;}
if (osztott <= 15) {maxTemp = 37.5;}
if (osztott > 15) {maxTemp = 37.2;}

//fűtés és páratartalom vezérlés
    if(tm > maxTemp) {digitalWrite(fan, HIGH);
                      digitalWrite(heat1, HIGH);
                      digitalWrite(heat2, HIGH);
                      Serial.print (" FŰTÉS KIKAPCSOLVA!");
                      lcd.clear();
                      lcd.setCursor(0,0);
                      lcd.print(tm);
                      lcd.print((char)223);
                      lcd.print("C ");
                      lcd.print("Futes ki");}

                      else {digitalWrite(fan, LOW);
                            digitalWrite(heat1, LOW);
                            digitalWrite(heat2, LOW);
                            Serial.print (" FŰTÉS BEKAPCSOLVA!");
                            lcd.clear();
                            lcd.setCursor(0,0);
                            lcd.print(tm);
                            lcd.print((char)223);
                            lcd.print("C ");
                            lcd.print("Futes be");}
                                                 
    if (hu < maxHum) {digitalWrite(hum,LOW);
                      lcd.setCursor(0,1);
                      lcd.print(hu);
                      lcd.print((char)37);
                      lcd.print(" Para be");
                      Serial.print (" PÁRA BEKAPCSOLVA!");}
                       
                      else {digitalWrite(hum,HIGH);
                            lcd.setCursor(0,1);
                            lcd.print(hu);
                            lcd.print((char)37);
                            lcd.print(" Para ki");
                            Serial.print (" PÁRA KIKAPCSOLVA!");}
                         
delay (1900);

// idő és rendszerhőmérséklet kiírása
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t); //Get time
        parse_cmd("C",1);
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
       
        lcd.setCursor(2,0);
       
        lcd.print(t.year);
        printMonth(t.mon);
        lcd.print(t.mday);
                 
        lcd.setCursor(0,1);
        lcd.print(t.hour);
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        if(t.sec<10)
        {
          lcd.print("0");
        }
        lcd.print(t.sec);
       
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }
Serial.print("Beállított hőmérséklet: ");
Serial.print(maxTemp);
Serial.print(" Beállított páratartalom: ");
Serial.println(maxHum);
Serial.print("Jelenlegi hőmérséklet: ");
Serial.print(tm);
Serial.print(" Jelenlegi páratartalom: ");
Serial.println(hu);
Serial.print("Üzemciklus: ");
Serial.print(cnt);
Serial.print(" Üzemnap: ");
Serial.println(osztott);
Serial.print(t.hour);
Serial.print(":");
        if(t.min<10)
        {
          Serial.print("0");
        }
        Serial.print(t.min);
        Serial.print(":");
        if(t.sec<10)
        {
          Serial.print("0");
        }
Serial.println(t.sec);
   
cnt = ++cnt;
}

void parse_cmd(char *cmd, int cmdsize)
{
    uint8_t i;
    uint8_t reg_val;
    char buff[BUFF_MAX];
    struct ts t;
}

void printMonth(int month)
{
  switch(month)
  {
    case 1: lcd.print(" Jan ");break;
    case 2: lcd.print(" Feb ");break;
    case 3: lcd.print(" Mar ");break;
    case 4: lcd.print(" Apr ");break;
    case 5: lcd.print(" Maj ");break;
    case 6: lcd.print(" Jun ");break;
    case 7: lcd.print(" Jul ");break;
    case 8: lcd.print(" Aug ");break;
    case 9: lcd.print(" Sept ");break;
    case 10: lcd.print(" Oct ");break;
    case 11: lcd.print(" Nov ");break;
    case 12: lcd.print(" Dec ");break;
    default: lcd.print(" Error ");break;
  }
}

karolyia
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2017. április 14. péntek, 7:47

Re: Rtc és eltelt idő számítása.

HozzászólásSzerző: karolyia » 2018. március 19. hétfő, 13:53

Van egy lanshield ami megoldja, hogy ne kelljen az lcd kijelzőt figyelni. Áramszünet elméletileg kizárva, egy bazi nagy teherautóaksiról megy az egész motyó, amin rajta van a töltő is. A relépanel 5V, de az is megoldva egy 12V - 5V stepdown elektronikával.
Ha esetleg újraindul a motyó, akkor a lanshield sd kártyára ment és az utolsó mentésből futtatom az utolsó állás szerinti változókat. Ha nullázni akarom, akkor azt majd a webfelületen megoldom.

Pára és a hőmérséklet alapon működik jelnleg a cucc. Pont ezt szeretném automatizálni, hogy idő függvényében automatikusan ő állítson magának mindent, ne csak statív legyen a dolog.

De kezdek agyf@xt kapni. Hogy tudok hozzáadni egy kiolvasott dátumhoz? Globál változót hogy tudok egy rtc.now() parancsból csinálni, ami nem DateTime, hogy kezelhető legyen? Lehet érthetetlen amit írok, de lassan végigolvasom a netet, de nem találok ilyet.

Ami a fórumról be lett másolva, konkrétan én csináltam....
_______________________________________________________


Vissza: “Arduino / C-nyelvű programozás (AVR-Duino, EthDuino, Arduino, Diecimila)”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 1 vendég