Arduino-aikakirjasto ja RTC-kirjastot

Käytän RTClib.h- ja TimeLib.h-tiedostoja Unon kanssa.

Olen kamppailen päiviä ymmärtämällä käytettävissä olevia RTC-kirjastoja ja niiden käyttöä Arduino-aikakirjastossa.

Kysymys 1 .
Jos en halua luoda uutta nyt () -objektia joka kerta silmukan läpi, miten synkronoidaan aikakirjasto RTC: hen x sekunnin välein? Aina kun yritän käyttää RTClib-toimintoa now.hour now.minute jne., Se vaatii minua käyttämään DateTime now = RTC.now () luomalla now () -objektin.

Onko RTCLibissä vastaavaa toimintoa as setSyncProvider (RTC.get) DS1307RTC-kirjastossa?

Onko vastaavaa setSyncInterval (5000)

Kysymys 2 .
Mikä RTCLib minun pitäisi kutsua? Esimerkkejä on useita:

< RTClib.h >

” RTClib ” lainausmerkkien avulla

< RTCLib.h > isolla L

ja joskus myös kutsumalla yksi näistä:

RTC_DS1307 RTC

tai RTC_DS1307 rtc

tai RTC_DS3231 rtc

Kysymys 3
a. Ovatko tmElements_t tm osa DS1307RTC-kirjastoa?
b. Ovatko nämä tm.Hour tm.Minute RTC: ltä?
c. Onko RTClib.h: ssä vastaavaa?

Ja lopuksi olen lähettänyt koodin alle osoittamaan vain käyttötarkoitukseni:

#include "RTClib.h" #include <Wire.h> #include <TimeLib.h> RTC_DS1307 RTC; void setup() { Serial.begin(9600); Wire.begin(); //sets up the I2C RTC.begin(); //initializes the I2C to the RTC if (! RTC.begin()) { Serial.println("Couldn"t find RTC"); } // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30)); //Set Arduino Time Library different than RTC time to see which is which setTime(9, 27, 05, 14, 07, 2015); } void loop() { /* // How do I sync Time Library to RTC after x seconds? setSyncProvider(RTC.get); // This is in the DS1307RTC.h Library setSyncInterval(5000); // Are there such functions in RTClib ? */ DateTime now = RTC.now(); // Pulls RTC time into now(). Does not sync with Time Library // Do not want to do this every loop. //Print RTC Time Serial.println(); Serial.print("RTC now.hour "); Serial.println(now.hour()); Serial.print("RTC now.minute "); Serial.println(now.minute()); Serial.print("RTC now.second: "); Serial.println(now.second()); Serial.println(); Serial.println(); //Print Arduino TimeLib Time Serial.print("Time Lib Hour: "); Serial.print(hour()); Serial.println(); Serial.print("Time Lib Min: "); Serial.print(minute()); Serial.println(); Serial.print("Time Lib Sec: "); Serial.print(second()); Serial.println(); Serial.println(); delay(1000); } 

Päivitetty 5. marraskuuta 2020

Luulen melkein ymmärtävän. Kerro minulle, toimiiko tämä koodi mielestäni erityisesti:

Asennuksessa:
Aseta RTC arvoon 5:10:30.
Aseta aikakirjasto 9:27:05 setTime () -toiminnolla.
Aseta Time Library RTC-aikaan päivämäärän kanssa TimeTime nyt (kirjoitettaessa 9:27:05)?
Aseta Time Library -muuttujien arvoksi RTC käyttämällä tm.Hour = now. Tunti jne.

Silmukka:
Päivitä 5 sekunnin välein tunti (), minuutti () sekunti () RTC-ajan kanssa.
Jokainen silmukan päivitys tm. Tunti tunnilla () , jne.

Tiedän, että se ei ole vieläkään oikein, koska sarjajulkaisuissa näkyy tm.Hour, tm.Minute vuorotellen kutakin silmukkaa alareunassa esitetyllä tavalla.

 #include "RTClib.h" #include <Wire.h> #include <TimeLib.h> RTC_DS1307 RTC; time_t time_provider() { return RTC.now().unixtime(); } tmElements_t tm; //part of Time Library void setup() { //setSyncProvider(time_provider); Serial.begin(9600); Wire.begin(); //sets up the I2C RTC.begin(); //initializes the I2C to the RTC if (! RTC.begin()) { Serial.println("Couldn"t find RTC"); } // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30)); //Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015); //Setting Time Library to RTC time DateTime now = RTC.now(); tm.Hour = now.hour(); tm.Minute = now.minute(); tm.Second = now.second(); } void loop() { setSyncProvider(RTC.now); setSyncInterval(5000); //Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second(); Serial.print("tm.Hour: "); Serial.print(tm.Hour); Serial.println(); Serial.print("tm.Minute: "); Serial.print(tm.Minute); Serial.println(); Serial.print("tm.Seconds: "); Serial.print(tm.Second); Serial.println(); Serial.println(); delay(1000); }  

Sarjakuvat:

tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0 tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0 tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0 

Vastaus

Sallikaa minun antaa ensin tausta näistä kirjastoista.

Aikakirjasto käyttää millis() ajankäyttö. Koska tähän voi kohdistua merkittävää ajautumista, se tarjoaa keinot synkronoida ajoittain ulkoisen ajan tarjoajan kanssa. Tästä syystä funktiot setSyncProvider() ja setSyncInterval().

RTClib on tarkoitettu liittämään RTC: tä. Se ei tarjoa kellonaikaa yksin: saat nykyisen ajan tiedustelemalla RTC: tä sen ”s now() -menetelmän avulla.

Nämä kaksi kirjastoa voivat täydentää kullakin muu, koska RTClibia voidaan käyttää aikakirjaston aikatoimittajana:

 // Provide the RTC time to the Time library. time_t time_provider() { return RTC.now().unixtime(); } void setup() { // ... setSyncProvider(time_provider); }  

Jos en halua luoda uutta nyt () -objektia […]

Sitä kutsutaan itse asiassa DateTime -objektiksi.

Onko vastaavaa [div

] RTClibissä

Kyllä, DateTime luokka . Huomaa, että toisin kuin tmElements_t -rakenteessa, DateTime -tietokentät eivät ole julkinen, ja sinun on käytettävä lisävarusteita niiden hankkimiseen: year(), month(), day()

Vaihtoehtoinen ajanottomenetelmä

Koska käytät Arduino Unoa, voit käyttää kolmatta ajanottomenetelmää haluavat harkita. Sen sijaan, että kysytään RTC: tä kaikilla silmukan iteraatioilla (RTClib) tai interpoloit RTC-lukemia millis() (aikakirjasto), voit reitittää RTC: n 1 Hz: n lähdön keskeytystappiin, ja laske sekunnit ISR: ssä. avr-libc-ajoituskoodi on suunniteltu tarjoamaan ajanotto tällä tavalla. Se kaikki muodostuu:

 // Initialize the system time from the RTC. set_system_time(RTC.now().secondstime()); // Keep the time in sync using the 1 Hz output of the RTC. pinMode(pin1Hz, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(pin1Hz), system_tick, FALLING);  

Lisätietoja on esimerkkiluonnoksessa keskeyttää1Hz.ino RTClibin mukana.


Muokkaa 1 : kommenttiin vastaaminen

mihin nastaan [Arduino-keskeytystappi] muodostaa yhteyden RTC: ssä?

Se riippuu käyttämästäsi RTC: stä. Oletan, että se on DS1307, kuten kysymyksesi koodi viittaa. Tutustu RTC: n tietolomakkeeseen .Sivulla 6 on taulukko, jonka otsikko on ”Pin-kuvaus”. Tästä taulukosta:

pin : 7
nimi : SQW / OUT
-toiminto : Neliöaalto / lähtöohjain. Kun SQWE-bitti on asetettu arvoon 1, SQW / OUT-nasta tuottaa yhden neljästä neliöaaltotaajuudesta (1Hz, 4kHz, 8kHz, 32kHz). SQW / OUT-tappi on tyhjä ja vaatii ulkoisen vetovastuksen. SQW / OUT toimii joko V CC tai V BAT kanssa. Vetojännite voi olla enintään 5,5 V riippumatta V CC -jännitteestä. Jos sitä ei käytetä, tämä tappi voidaan jättää kellumaan.

Jos käytät RTC -moduulia , sinun on selvitettävä missä tämä nasta on moduulin liittimessä.

Joka tapauksessa joudut ottamaan 1 Hz: n neliöaaltolähdön käyttöön

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);  

Muokkaa 2 : Kommentoi kysymyksen päivitystä:

 // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));  

Oikea.

 // Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);  

Oikein. Päivämäärä on 14.7.2015.

 // Setting Time Library to RTC time DateTime now = RTC.now(); tm.Hour = now.hour(); tm.Minute = now.minute(); tm.Second = now.second();  

Ei. Tämä alustaa vain tm muuttuja. Sillä ei ole vaikutusta ajatuskirjaston ajatukseen nykyisestä ajasta. Huomaa, että tm -kohdan päivämääräkenttiä ei ole alustettu tässä vaiheessa ja ne voivat hyvinkin olla virheellisiä (kuten 23. kuukausi, päivä 125).

 setSyncProvider(RTC.now);  

Tämä on väärin, ja sen olisi pitänyt luoda kääntäjävaroitus. setSyncProvider() odottaa funktion, joka palauttaa nykyisen ajan Unix-aikaan (yksinkertainen kokonaisluku, tyyppi time_t). Annat funktion, joka palauttaa nykyisen ajan eriteltyinä (vuosi, kuukausi …), tyypillä DateTime. Time-kirjasto ei ymmärrä sitä ja saattaa tuottaa roskaa, kuten esimerkiksi klo 18:00:00.

RTC.now() palauttama aika voidaan muuntaa Unix-aikaan unixtime() -menetelmällä. Siksi annoin sinulle time_provider() -funktion.

Sinun ei myöskään tule kutsua setSyncProvider() ja setSyncInterval() kaikilla silmukka-iteraatioilla. Tee se lopullisesti kohdassa setup().

 // Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second();  

Jälleen päivittää vain muuttujan tm. Sillä ei ole vaikutusta siihen, mitä aikakirjasto uskoo olevan nykyinen aika.

Vastaa

Onko RTCLibissä vastaava toiminto setSyncProvider (RTC.get) DS1307RTC-kirjastossa?

Onko vastaa setSyncInterval (5000)

Nämä ovat TimeLib-toimintoja. Ei ” vastaa div id = ”6fd0f512c6”>

koska käytät TimeLibiä.

Ensimmäinen odottaa vain osoittimen funktiolle, joka r eturns a time_t. Funktion sisältö on sinun tehtäväsi.

Minkä RTCLibin pitäisi kutsua? Esimerkeissä käytetään useita:

Isojen kirjainten on vastattava otsikkotiedoston nimeä. Windows ei välitä, ja OS X ei yleensä välitä, mutta se voidaan määrittää. Linux huolehtii ja tarvitsee sitä vastaamaan. Jos haluat koodisi olevan kannettava, sinun on pidettävä isot ja pienet kirjaimet samalla tavalla kuin tiedostossa.

ja joskus myös kutsuttava yksi näistä:

Sinun on luotava objekti, joka vastaa fyysistä RTC: täsi.

a. Ovatko tmElements_t tm osa DS1307RTC-kirjastoa?

Ei. Ne ovat osa TimeLibiä.

b. Ovatko nämä tm.Hour tm.Minute RTC: ltä?

Ne ovat mitä tahansa, mikä heille osoitetaan kutsutulla toiminnolla. Ne ovat vain muuttujia. Ne voivat sisältää mitä tahansa.

c. Onko RTClib.h: ssä vastaavaa?

Ei. Mutta silloin sinun ei tarvitse olla, jos käytät TimeLibiä.

Joten: sinun täytyy

  • luoda toiminto, joka saa ajan RTC: ltä haluamasi kirjaston kautta (esimerkiksi RTCLib) ja laskee sekuntien määrän 00:00:00 01.01.1970 lähtien, jonka se sitten palauttaa nimellä time_t.
  • välitä se TimeLibille ”s setSyncProvider()
  • Aseta tahdistustiheys setSyncInterval() -toiminnolla.

Kommentit

  • now on aika RTC: stä hetkellä, kun määrität objektin now. .hour() on vain tunnin sisällä objektin sisällä. hour() on aika TimeLib-kirjastosta, kyllä. setSyncProvider () doesn ’ älä lähetä mitään RTC: lle, se saa ajan RTC: ltä säännöllisesti ja päivittää TimeLibin nykyisellä ajalla.
  • Se ’ sa vähän monimutkaisempi kuin se. TimeLib käyttää millis() seurata aikaa. Se päivittää säännöllisesti sisäistä ajatustaan ajankohdasta riippuen setSyncInterval(). kun pyydät hour(), jos on kulunut enemmän aikaa siitä, kun se viimeksi sai todellisen ajan, jonka määritit kohdassa setSyncInterval(), se menee ja saa aika RTC: ltä. Muuten se vain kertoo sinulle, mitä ajattelee aika on omien sisäisten laskelmiensa mukaan.
  • Päivitin viestini avustuksella. Melkein ymmärrät sen.
  • Koska ’ vaihdat jatkuvasti synkronointipalvelua ja -väliä. Asetat ne kerran ja kerran vain määrityksessä, enkä enää koskaan.
  • Se näyttää oikealta, kyllä. Vaikka et ’ tarvitse lainkaan tmElements_t -rakennetta, koska kaikki mitä ’ käsittelette kanssa on yksinkertaisia numeroita. tmElements_t on vain kätevä tapa niputtaa ne kaikki yhteen, jos haluat siirtää sen toiselle toiminnolle. Vain Serial.print(hour());
  • Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *