Arduino RTC

Domm__
Příspěvky: 7
Registrován: 26 čer 2022, 14:44
Reputation: 0

Arduino RTC

Příspěvek od Domm__ » 26 čer 2022, 14:51

Zdravím!
Mám hotový program pro RTC, ale nevím, jak z něj každý den ve stejnou hodinu vytáhnout pět minut OUTPUT - HIGH z pinu 7. Pomůžete? Díky, Dom.

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Arduino RTC

Příspěvek od gilhad » 26 čer 2022, 17:16

Nešlo by tam někam vtěsnat něco jako:

Kód: Vybrat vše

unsigned long milsState;
unsigned long currentMillis;

const unsigned long milsDay = 24*60*60*1000UL;
const unsigned long mils5minutes = 5*60*1000UL;

bool Zapnuto = false;
int Pin7=7;

// v setupu
  pinMode(Pin7,OUTPUT);
  digitalWrite(Pin7, LOW);
  
// v loop
  currentMillis=millis();
  if (Zapnuto and ((currentMillis-milsState) >= mils5minutes)) {
     Zapnuto = false;
     digitalWrite(Pin7, LOW);
     milsState=currentMillis;
  };
  if (! Zapnuto and ((currentMillis-milsState) >= (milsDay-mils5minutes))) {
     Zapnuto = true;
     digitalWrite(Pin7, HIGH);
     milsState=currentMillis;
  };


martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino RTC

Příspěvek od martinius96 » 26 čer 2022, 18:36

Kód: Vybrat vše

//globálne premenné
boolean active = false;
unsigned long time = 0;

//v loope() obe podmienky
//NACITAME SI HOUR MINUTE Z RTC, uložíme do premenných hour a minute
// pouzijeme v podmienke
if ((hour = 11 && minute == 0) && (active == false)){ //v 11:00 sa zapne výstup
time = millis();
active = true;
digitalWrite(7, HIGH);
}

if((millis()-time >=300000) && (active == true)){ // po 5 minutach od štartu sa vystup vypne, znova sa spustí na 5 min následujúci deň v 11:00
active = false;
digitalWrite(7, LOW);
}

Domm__
Příspěvky: 7
Registrován: 26 čer 2022, 14:44
Reputation: 0

Re: Arduino RTC

Příspěvek od Domm__ » 26 čer 2022, 20:43

gilhad píše:
26 čer 2022, 17:16
Nešlo by tam někam vtěsnat něco jako:

Kód: Vybrat vše

unsigned long milsState;
unsigned long currentMillis;

const unsigned long milsDay = 24*60*60*1000UL;
const unsigned long mils5minutes = 5*60*1000UL;

bool Zapnuto = false;
int Pin7=7;

// v setupu
  pinMode(Pin7,OUTPUT);
  digitalWrite(Pin7, LOW);
  
// v loop
  currentMillis=millis();
  if (Zapnuto and ((currentMillis-milsState) >= mils5minutes)) {
     Zapnuto = false;
     digitalWrite(Pin7, LOW);
     milsState=currentMillis;
  };
  if (! Zapnuto and ((currentMillis-milsState) >= (milsDay-mils5minutes))) {
     Zapnuto = true;
     digitalWrite(Pin7, HIGH);
     milsState=currentMillis;
  };

Nějak mi není jasné naco se dívám... :?:

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Arduino RTC

Příspěvek od jankop » 26 čer 2022, 21:48

Jestli to nebude tvým nepřesným dotazem. Jeden předpokládá generování času Arduinem, druhý externím RTC.

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Arduino RTC

Příspěvek od gilhad » 26 čer 2022, 23:43

Jo, já si teď hrál s různýma realtimama, takže jsem se překouknul a místo RTC četl RTOS.
Jinak je to dost podoné tomu druhému příkladu, akorát řeším obě větve (aktivní i neaktivní) stejným čekáním bez blokování.
(A mám tam překlep, v ifu má samozřejmě být && místo and)
Jinak bool proměnné a výrazy mají přímo logickou hodnotu, takže je většinou není potřeba porovnávat s true/false a lze je použít rovnou.
A dávám přednost přehlednějšímu zápisu 5*60*1000UL kde je jasné, že beru 5 minut po 60 sekundách po 1000 milisekundách a chci to UnsignedLong a nejek oříznout na integer. Že je to 300000 spočítá už překladač a tak si tam to číslo dosadí sám, jemu to na přehlednosti nevadí.
(Explicitní přetypování na UnsignedLong tam mám, protože jinak to s oblibou všechno převádí na int a ne vždy se to tam vejde.)
No a protože vyhodnocení bool proměnné je výrazně rychlejší než rozdíl dvou UL a porovnání výsledku s třetím UL, tak výrazy začínám těma bool, protože když to selže, tak se nemusí vyhodnocovat dál (a tak zdržovat zbytečnýma operacema) - což u mě vyjde v 1/2 porovnání (když je na začátku jednou Zapnuto a jednou !Zapnuto) (A ano, šlo by z toho udělat samostatný if() {} else {} ale tím by se ztratila přehlednost a tolik času zase nezískalo)

milsState uchovává, kdy se přešlo do daného stavu - odpovídá time z druhého příkladu.
currentMillis uchovávají millis() ze začátku současného průchodu, aby se nevolalo víckrát (častu se mi na to odkazuje i mnohem víc if-ů a nastavuje se to do více proměnných, takže je pro mě výhodné si vzít hodnotu na začátku smyčky a neřešit, co by se mohlo stát, kdyby mezi jednotlivými volání přeskočila na další hodnotu

milsDay a mils5minutes jsou konstanty, uchovávající počet milisekund v jednom dni, resp v 5 minutách. Když se od sebe odečítají, zase to vyřeši překladač a použije přímo výsledek. Pokud by se třeba měnila doba zapnutí, tak to změním na jednom místě a všude jinde se to přepočte samo (další výhoda 5*60*1000 oproti 300000 - jde dohledat těch 5)

Pin7 je ovládaný pin (líp by mu slušelo nějaké názornější jméno, třeba PinBzučák, pokud ovládá bzučák), ale zase ho mám na jednom místě na začátku a pokud bych někdy v budoucnu to zapojil jinak, tak to měním na jediném místě. (Například se rohodnul k něčemu použít AIN1 (analog comparator negative input), který sedí na stejném pinu.)

Zapnuto řiká zda má být výstup zapnut (HIGH), nebo vypnut (LOW) - zase by šlo psát univerzálně digitalWrite(Pin7, Zapnuto); ale zase by to tady přehlednosti nepřispělo, tak to píšu s HIGH/LOW

---

Základní myšlenka je jednoduchá - nechám to 5 minut zapnuté a zbytek dne vypnuté. Kdy přesně to má začít s tím zapínáním by se nastavilo někde jinde nějak jinak, podle toho jaké ovládání by bylo k dispozici.

Domm__
Příspěvky: 7
Registrován: 26 čer 2022, 14:44
Reputation: 0

Re: Arduino RTC

Příspěvek od Domm__ » 29 čer 2022, 16:58

Měl bych prosbičku... Potřeboval bych nějaku ochotnou chytrou hlavu, která mi pomůže napsat program na automatické zalévání.
Hardware obsahauje arduino UNO, RTC a relé kterým spouštím elektromagnetický ventil. Dolů přidám odkazy.
Představa programu je, že budu přes arduino a RTC modul spouštět přes relé elmg. ventil každý den v šest ráno a v šest večer.
Bohužel, mé dosavadní znalosti programování v jazyce wiring nejsou dostatečné, tak snad se někdo ochotný najde.
[Poté bych chtěl přidat ještě dešťový senzor, to je ale až další část]. Tak předem dík!











https://dratek.cz/docs/produkty/0/577/1517436347.pdf
https://dratek.cz/arduino/1261-rtc-hodi ... duino.html
https://www.easydiag.cz/Solenoid-3-4-12 ... C-d229.htm

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino RTC

Příspěvek od martinius96 » 29 čer 2022, 17:37

Je to úplne ten istý program, ktorý som ti poskytol minule vyššie...
Identickú podmienku som použil pre oba časy v ktorých chceš výstup spúšťať a doplnil som podľa tvojho zdroja kód s knižnicou DS3231 pre inicializáciu displeja a vyčítanie jednotlivých položiek (hodina, minúta...). Nakoľko má relé invertovanú logiku (active-LOW), otočil som preto hodnoty, t.j. pre aktívne relé LOW, pre vypnuté HIGH.

Verím, že teraz máš už v programe dosť info o komentárov, aby si dokázal pridať dažďový senzor aj sám a urobiť pre neho podmienku.
Využiješ tam len digitalRead(), respektíve analogRead() funkciu podľa toho či využiješ digitálny (threshold zvyčajne voliteľný potenciometrom), alebo analógový výstup senzora.

Nenapísal si dĺžku po akú má byť výstup aktívny. Dal som tam teda 60 sekúnd interval.
Výstup sa aktivuje v 6:00 a v 18:00. V oboch prípadoch bude aktívny minútu, teda do 6:01 resp. 18:01.

Edit:
Jo a inak to relé vyžaduje 12V napájanie i keď v .pdf ukazujú 5V, neveril by som tomu, že to bude fungovať s 5V napájaním z Arduina... Myslel som si, že je to štandardné 5V relé SRD-05VDC-SL-C s invertovanou logikou. Podľa signálov IN+, resp. IN-, ktoré sú tam vyznačené si zvolíš vlastne i logiku, teda buď ho budeš spínať log. 0 alebo log. 1 (+5V) z GPIO Arduina.

Kód: Vybrat vše

// připojení potřebných knihoven
#include <Wire.h>
#include <DS3231.h>
// inicializace RTC z knihovny
DS3231 rtc;
// vytvoření proměnné pro práci s časem
RTCDateTime datumCas;
boolean active = false; //príznak pre spúšťanie podmienok
unsigned long time = 0;
int hour;
int minute;
const int rele = 7;
void setup() {
  pinMode(rele, OUTPUT);
  digitalWrite(rele, HIGH);
  // zahájení komunikace po sériové lince
  // rychlostí 9600 baud
  Serial.begin(9600);
  // zahájení komunikace s RTC obvodem
  rtc.begin();
  //rtc.setDateTime(__DATE__, "12:34:56"); //MANUALNE NASTAVENIE CASU PRI SPUSTENI - PREPIS STAREHO CASU
}

//v loope() obe podmienky
//NACITAME SI HOUR MINUTE Z RTC, uložíme do premenných hour a minute
// pouzijeme v podmienke
void loop() {
  // načtení času z RTC do proměnné
  datumCas = rtc.getDateTime();
  hour = datumCas.hour; //do HOUR zapiseme hodinu z RTC modulu
  minute = datumCas.minute; //do MINUTE zapiseme minuty z RTC modulu
  if ((hour = 6 && minute == 0) && (active == false)) { //v 6:00 aktivujeme vystup
    time = millis();
    active = true;
    digitalWrite(rele, LOW);
  }

  if ((hour = 18 && minute == 0) && (active == false)) { //v 18:00 aktivujeme vystup
    time = millis();
    active = true;
    digitalWrite(rele, LOW);
  }

  if ((millis() - time >= 60000) && (active == true)) { // vystup bude aktivny minutu (od 6:00 do 6:01 a od 18:00 do 18:01)
    active = false;
    digitalWrite(rele, HIGH);
  }
}

Domm__
Příspěvky: 7
Registrován: 26 čer 2022, 14:44
Reputation: 0

Re: Arduino RTC

Příspěvek od Domm__ » 29 čer 2022, 17:56

Fajn, díky za zmínku.
Nevím, jestli je chyba ve mně, ale program vyhazuje spoustu chyb... Bohužel, nejsem je jaksi schopný odstranit..
Třeba vám to řekne víc, opakuji, jsem na začátku. Všechno jsem si pročetl, zkusil pochopit, ale vyřešit nedokážu.....

Arduino: 1.8.19 (Windows 10), Vývojová deska: "Arduino Uno"


sketch_jun29b:7:1: error: 'RTCDateTime' does not name a type; did you mean 'DateTime'?

RTCDateTime datumCas;

^~~~~~~~~~~

DateTime

sketch_jun29b:9:15: error: 'long unsigned int time' redeclared as different kind of symbol

unsigned long time = 0;

^~~~

In file included from C:\Users\kruzelovi\Documents\Arduino\libraries\DS3231/DS3231.h:22:0,

from C:\Users\KRUZEL~1\AppData\Local\Temp\arduino_modified_sketch_495834\sketch_jun29b.ino:3:

c:\users\kruzelovi\appdata\local\arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\time.h:122:21: note: previous declaration 'time_t time(time_t*)'

time_t time(time_t *timer);

^~~~

C:\Users\KRUZEL~1\AppData\Local\Temp\arduino_modified_sketch_495834\sketch_jun29b.ino: In function 'void setup()':

sketch_jun29b:20:7: error: 'class DS3231' has no member named 'begin'

rtc.begin();

^~~~~

C:\Users\KRUZEL~1\AppData\Local\Temp\arduino_modified_sketch_495834\sketch_jun29b.ino: In function 'void loop()':

sketch_jun29b:29:3: error: 'datumCas' was not declared in this scope

datumCas = rtc.getDateTime();

^~~~~~~~

sketch_jun29b:29:18: error: 'class DS3231' has no member named 'getDateTime'; did you mean 'getDate'?

datumCas = rtc.getDateTime();

^~~~~~~~~~~

getDate

sketch_jun29b:33:19: error: assignment of function 'time_t time(time_t*)'

time = millis();

^

sketch_jun29b:33:19: error: cannot convert 'long unsigned int' to 'time_t(time_t*) {aka long unsigned int(long unsigned int*)}' in assignment

sketch_jun29b:39:19: error: assignment of function 'time_t time(time_t*)'

time = millis();

^

sketch_jun29b:39:19: error: cannot convert 'long unsigned int' to 'time_t(time_t*) {aka long unsigned int(long unsigned int*)}' in assignment

sketch_jun29b:44:17: error: invalid operands of types 'long unsigned int' and 'time_t(time_t*) {aka long unsigned int(long unsigned int*)}' to binary 'operator-'

if ((millis() - time >= 60000) && (active == true)) { // vystup bude aktivny minutu (od 6:00 do 6:01 a od 18:00 do 18:01)

~~~~~~~~~^~~~~~

exit status 1

'RTCDateTime' does not name a type; did you mean 'DateTime'?



Táto zpráva by měla mít víc informacií v
"Zobrazení podrobného výstupu při kompilaci"
podle zapnuté volby v Soubor -> Nastavení.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino RTC

Příspěvek od martinius96 » 29 čer 2022, 19:55

No zdá sa, že máš inú knižnicu DS3231, nakoľko som vychádzal z príkladu tejto knižnice z linku, ktorý si dal na modul DS3231 u dratek.cz, kde je aj ukážkový návod k modulu a základný program pre výpis času. Takže buď zmeniť knižnicu na tú, ktorá je na stránkach dratek.cz pri návode k modulu, alebo prepísať program podľa tvojej knižnice (otvoríš si v Arduino IDE Príklady, vyberieš si DS3231 a akýkoľvek príklad. Podľa neho upravíš existujúci program). Tých DS3231 knižníc je fakt mnoho a majú rovnaký názov .cpp i .h súboru, ale každá knižnica má iné funkcie triedy... Niektorá má pre inicializáciu begin(), iná init(). Pre prevzatie aktuálnych hodnôt času a dátumu má niektorá knižnica getDate(), iná getDateTime()...

Mimo toho je jediná chyba premenná s názvom time, ktorá sa musí premenovať, keďže taká existuje vo Wiringu...
Môžeš to zmeniť napríklad na cas / mytime všade v programe...

Odpovědět

Kdo je online

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