diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml index f86f656..6f8c869 100644 --- a/.github/workflows/build_check.yml +++ b/.github/workflows/build_check.yml @@ -3,7 +3,6 @@ name: Integration Tests on: merge_group: pull_request: - types: [opened, reopened] jobs: build: @@ -45,10 +44,10 @@ jobs: - 'lib/BoardFinder' - 'lib/ConfigurationManagement' #- 'lib/Display' - #- 'lib/NTPClient' + - 'lib/NTPClient' - 'lib/PowerManagement' - 'lib/System' - #- 'lib/TimeLib' + - 'lib/TimeLib' steps: - name: Checkout code uses: actions/checkout@v3 @@ -61,38 +60,14 @@ jobs: cppcheck: name: Run cppcheck runs-on: ubuntu-latest - env: - CPPCHECK_ARGS: --enable=all --std=c++14 --inline-suppr -I lib/BoardFinder -I lib/ConfigurationManagement -I lib/Display -I lib/LoRa -I lib/LoRa_APRS -I lib/NTPClient -I lib/PowerManagement -I lib/System -I lib/TimeLib -i lib/Display -i lib/LoRa -i lib/NTPClient -i lib/TimeLib src lib steps: - - name: checkout code - uses: actions/checkout@v3 - - run: docker pull facthunder/cppcheck:latest - - name: Run cppcheck and print result - run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck $CPPCHECK_ARGS" - - name: Run cppcheck and create html - run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck --xml $CPPCHECK_ARGS 2> report.xml && cppcheck-htmlreport --file=report.xml --report-dir=output" - - name: Upload report - uses: actions/upload-artifact@v3 - with: - name: Cppcheck Report - path: output - - - remote_testing: - name: Remote Testing - runs-on: ubuntu-20.04 - env: - PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }} - steps: - - name: Setup Cache - uses: actions/cache@v3 + - uses: actions/cache@v3 with: path: | ~/.cache/pip - ~/.platformio - key: remote-cache - - name: Setup Python - uses: actions/setup-python@v4 + ~/.platformio/.cache + key: check-cache + - uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install PlatformIO @@ -101,9 +76,37 @@ jobs: python -m pip install --upgrade pip pip install --upgrade platformio + - name: Checkout code + uses: actions/checkout@v3 + - name: Run PlatformIO Check + run: pio check --fail-on-defect high -e lora_board + + hw_testing: + name: Hardware Testing + strategy: + matrix: + usb_port: [ttyUSB0] + runs-on: [self-hosted, "${{ matrix.usb_port }}"] + steps: + - uses: actions/cache@v3 + with: + path: | + ~/.cache/pip + ~/.platformio/.cache + key: hw-cache + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install PlatformIO + shell: bash + run: | + python -m pip install --upgrade pip + pip install --upgrade platformio - name: Checkout code uses: actions/checkout@v3 - name: List Devices - run: pio remote device list + run: pio device list - name: PlatformIO Test - run: pio remote test -v -r --upload-port /dev/ttyUSB4 --test-port /dev/ttyUSB4 + if: always() + run: flock -w 600 --verbose /locks/pio-${{ matrix.usb_port }} -c "pio test -vvv --upload-port /dev/${{ matrix.usb_port }} --test-port /dev/${{ matrix.usb_port }}" + diff --git a/lib/NTPClient/NTPClient.cpp b/lib/NTPClient/NTPClient.cpp index 13447f7..cdd53be 100644 --- a/lib/NTPClient/NTPClient.cpp +++ b/lib/NTPClient/NTPClient.cpp @@ -25,10 +25,10 @@ NTPClient::NTPClient() { } NTPClient::NTPClient(long timeOffset) { - this->_timeOffset = timeOffset; + this->_timeOffset = timeOffset; } -NTPClient::NTPClient(const char* poolServerName) { +NTPClient::NTPClient(const char *poolServerName) { this->_poolServerName = poolServerName; } @@ -37,18 +37,18 @@ NTPClient::NTPClient(IPAddress poolServerIP) { this->_poolServerName = NULL; } -NTPClient::NTPClient(const char* poolServerName, long timeOffset) { +NTPClient::NTPClient(const char *poolServerName, long timeOffset) { this->_timeOffset = timeOffset; this->_poolServerName = poolServerName; } -NTPClient::NTPClient(IPAddress poolServerIP, long timeOffset){ +NTPClient::NTPClient(IPAddress poolServerIP, long timeOffset) { this->_timeOffset = timeOffset; this->_poolServerIP = poolServerIP; this->_poolServerName = NULL; } -NTPClient::NTPClient(const char* poolServerName, long timeOffset, unsigned long updateInterval) { +NTPClient::NTPClient(const char *poolServerName, long timeOffset, unsigned long updateInterval) { this->_timeOffset = timeOffset; this->_poolServerName = poolServerName; this->_updateInterval = updateInterval; @@ -74,23 +74,24 @@ void NTPClient::begin(unsigned int port) { } bool NTPClient::forceUpdate() { - #ifdef DEBUG_NTPClient - Serial.println("Update from NTP Server"); - #endif +#ifdef DEBUG_NTPClient + Serial.println("Update from NTP Server"); +#endif // flush any existing packets - while(this->_udp.parsePacket() != 0) + while (this->_udp.parsePacket() != 0) this->_udp.flush(); this->sendNTPPacket(); // Wait till data is there or timeout... byte timeout = 0; - int cb = 0; + int cb = 0; do { - delay ( 10 ); + delay(10); cb = this->_udp.parsePacket(); - if (timeout > 100) return false; // timeout after 1000 ms + if (timeout > 100) + return false; // timeout after 1000 ms timeout++; } while (cb == 0); @@ -99,36 +100,37 @@ bool NTPClient::forceUpdate() { this->_udp.read(this->_packetBuffer, NTP_PACKET_SIZE); unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); - unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); + unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); // combine the four bytes (two words) into a long integer // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; this->_currentEpoc = secsSince1900 - SEVENZYYEARS; - return true; // return true after successful update + return true; // return true after successful update } bool NTPClient::update() { - if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval - || this->_lastUpdate == 0) { // Update if there was no update yet. - if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed + if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval + || this->_lastUpdate == 0) { // Update if there was no update yet. + if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) + this->begin(this->_port); // setup the UDP client if needed return this->forceUpdate(); } - return false; // return false if update does not occur + return false; // return false if update does not occur } unsigned long NTPClient::getEpochTime() const { - return this->_timeOffset + // User offset - this->_currentEpoc + // Epoc returned by the NTP server + return this->_timeOffset + // User offset + this->_currentEpoc + // Epoc returned by the NTP server ((millis() - this->_lastUpdate) / 1000); // Time since last update } int NTPClient::getDay() const { - return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday + return (((this->getEpochTime() / 86400L) + 4) % 7); // 0 is Sunday } int NTPClient::getHours() const { - return ((this->getEpochTime() % 86400L) / 3600); + return ((this->getEpochTime() % 86400L) / 3600); } int NTPClient::getMinutes() const { return ((this->getEpochTime() % 3600) / 60); @@ -138,15 +140,15 @@ int NTPClient::getSeconds() const { } String NTPClient::getFormattedTime() const { - unsigned long rawTime = this->getEpochTime(); - unsigned long hours = (rawTime % 86400L) / 3600; - String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + unsigned long rawTime = this->getEpochTime(); + unsigned long hours = (rawTime % 86400L) / 3600; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); - unsigned long minutes = (rawTime % 3600) / 60; - String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + unsigned long minutes = (rawTime % 3600) / 60; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); - unsigned long seconds = rawTime % 60; - String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + unsigned long seconds = rawTime % 60; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); return hoursStr + ":" + minuteStr + ":" + secondStr; } @@ -158,15 +160,15 @@ void NTPClient::end() { } void NTPClient::setTimeOffset(int timeOffset) { - this->_timeOffset = timeOffset; + this->_timeOffset = timeOffset; } void NTPClient::setUpdateInterval(unsigned long updateInterval) { this->_updateInterval = updateInterval; } -void NTPClient::setPoolServerName(const char* poolServerName) { - this->_poolServerName = poolServerName; +void NTPClient::setPoolServerName(const char *poolServerName) { + this->_poolServerName = poolServerName; } void NTPClient::sendNTPPacket() { @@ -175,19 +177,19 @@ void NTPClient::sendNTPPacket() { // Initialize values needed to form NTP request // (see URL above for details on the packets) - this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode - this->_packetBuffer[1] = 0; // Stratum, or type of clock - this->_packetBuffer[2] = 6; // Polling Interval - this->_packetBuffer[3] = 0xEC; // Peer Clock Precision + this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode + this->_packetBuffer[1] = 0; // Stratum, or type of clock + this->_packetBuffer[2] = 6; // Polling Interval + this->_packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion - this->_packetBuffer[12] = 49; - this->_packetBuffer[13] = 0x4E; - this->_packetBuffer[14] = 49; - this->_packetBuffer[15] = 52; + this->_packetBuffer[12] = 49; + this->_packetBuffer[13] = 0x4E; + this->_packetBuffer[14] = 49; + this->_packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: - if (this->_poolServerName) { + if (this->_poolServerName) { this->_udp.beginPacket(this->_poolServerName, 123); } else { this->_udp.beginPacket(this->_poolServerIP, 123); @@ -199,4 +201,4 @@ void NTPClient::sendNTPPacket() { void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) { randomSeed(analogRead(0)); this->_port = random(minValue, maxValue); -} \ No newline at end of file +} diff --git a/lib/NTPClient/NTPClient.h b/lib/NTPClient/NTPClient.h index 1c6c9c2..90b5595 100644 --- a/lib/NTPClient/NTPClient.h +++ b/lib/NTPClient/NTPClient.h @@ -3,104 +3,104 @@ #include #include -#define SEVENZYYEARS 2208988800UL -#define NTP_PACKET_SIZE 48 +#define SEVENZYYEARS 2208988800UL +#define NTP_PACKET_SIZE 48 #define NTP_DEFAULT_LOCAL_PORT 1337 class NTPClient { - private: - WiFiUDP _udp; - bool _udpSetup = false; +private: + WiFiUDP _udp; + bool _udpSetup = false; - const char* _poolServerName = "pool.ntp.org"; // Default time server - IPAddress _poolServerIP; - unsigned int _port = NTP_DEFAULT_LOCAL_PORT; - long _timeOffset = 0; + const char *_poolServerName = "pool.ntp.org"; // Default time server + IPAddress _poolServerIP; + unsigned int _port = NTP_DEFAULT_LOCAL_PORT; + long _timeOffset = 0; - unsigned long _updateInterval = 3600000; // In ms + unsigned long _updateInterval = 3600000; // In ms - unsigned long _currentEpoc = 0; // In s - unsigned long _lastUpdate = 0; // In ms + unsigned long _currentEpoc = 0; // In s + unsigned long _lastUpdate = 0; // In ms - byte _packetBuffer[NTP_PACKET_SIZE]; + byte _packetBuffer[NTP_PACKET_SIZE]; - void sendNTPPacket(); + void sendNTPPacket(); - public: - NTPClient(); - explicit NTPClient(long timeOffset); - explicit NTPClient(const char* poolServerName); - NTPClient(const char* poolServerName, long timeOffset); - NTPClient(const char* poolServerName, long timeOffset, unsigned long updateInterval); - explicit NTPClient(IPAddress poolServerIP); - NTPClient(IPAddress poolServerIP, long timeOffset); - NTPClient(IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); +public: + NTPClient(); + explicit NTPClient(long timeOffset); + explicit NTPClient(const char *poolServerName); + NTPClient(const char *poolServerName, long timeOffset); + NTPClient(const char *poolServerName, long timeOffset, unsigned long updateInterval); + explicit NTPClient(IPAddress poolServerIP); + NTPClient(IPAddress poolServerIP, long timeOffset); + NTPClient(IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); - /** - * Set time server name - * - * @param poolServerName - */ - void setPoolServerName(const char* poolServerName); + /** + * Set time server name + * + * @param poolServerName + */ + void setPoolServerName(const char *poolServerName); - /** - * Set random local port - */ - void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535); + /** + * Set random local port + */ + void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535); - /** - * Starts the underlying UDP client with the default local port - */ - void begin(); + /** + * Starts the underlying UDP client with the default local port + */ + void begin(); - /** - * Starts the underlying UDP client with the specified local port - */ - void begin(unsigned int port); + /** + * Starts the underlying UDP client with the specified local port + */ + void begin(unsigned int port); - /** - * This should be called in the main loop of your application. By default an update from the NTP Server is only - * made every 60 seconds. This can be configured in the NTPClient constructor. - * - * @return true on success, false on failure - */ - bool update(); + /** + * This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPClient constructor. + * + * @return true on success, false on failure + */ + bool update(); - /** - * This will force the update from the NTP Server. - * - * @return true on success, false on failure - */ - bool forceUpdate(); + /** + * This will force the update from the NTP Server. + * + * @return true on success, false on failure + */ + bool forceUpdate(); - int getDay() const; - int getHours() const; - int getMinutes() const; - int getSeconds() const; + int getDay() const; + int getHours() const; + int getMinutes() const; + int getSeconds() const; - /** - * Changes the time offset. Useful for changing timezones dynamically - */ - void setTimeOffset(int timeOffset); + /** + * Changes the time offset. Useful for changing timezones dynamically + */ + void setTimeOffset(int timeOffset); - /** - * Set the update interval to another frequency. E.g. useful when the - * timeOffset should not be set in the constructor - */ - void setUpdateInterval(unsigned long updateInterval); + /** + * Set the update interval to another frequency. E.g. useful when the + * timeOffset should not be set in the constructor + */ + void setUpdateInterval(unsigned long updateInterval); - /** - * @return time formatted like `hh:mm:ss` - */ - String getFormattedTime() const; + /** + * @return time formatted like `hh:mm:ss` + */ + String getFormattedTime() const; - /** - * @return time in seconds since Jan. 1, 1970 - */ - unsigned long getEpochTime() const; + /** + * @return time in seconds since Jan. 1, 1970 + */ + unsigned long getEpochTime() const; - /** - * Stops the underlying UDP client - */ - void end(); + /** + * Stops the underlying UDP client + */ + void end(); }; diff --git a/lib/TimeLib/TimeLib.cpp b/lib/TimeLib/TimeLib.cpp index 9394574..38676af 100644 --- a/lib/TimeLib/TimeLib.cpp +++ b/lib/TimeLib/TimeLib.cpp @@ -1,329 +1,326 @@ /* - time.c - low level time and date functions - Copyright (c) Michael Margolis 2009-2014 + time.c - low level time and date functions + Copyright (c) Michael Margolis 2009-2014 - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - 1.0 6 Jan 2010 - initial release - 1.1 12 Feb 2010 - fixed leap year calculation error - 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this) - 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update - status, updated examples for Arduino 1.0, fixed ARM - compatibility issues, added TimeArduinoDue and TimeTeensy3 - examples, add error checking and messages to RTC examples, - add examples to DS1307RTC library. - 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7 + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + 1.0 6 Jan 2010 - initial release + 1.1 12 Feb 2010 - fixed leap year calculation error + 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this) + 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update + status, updated examples for Arduino 1.0, fixed ARM + compatibility issues, added TimeArduinoDue and TimeTeensy3 + examples, add error checking and messages to RTC examples, + add examples to DS1307RTC library. + 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7 */ #include #include "TimeLib.h" -static tmElements_t tm; // a cache of time elements -static time_t cacheTime; // the time the cache was updated -static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds +static tmElements_t tm; // a cache of time elements +static time_t cacheTime; // the time the cache was updated +static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds void refreshCache(time_t t) { - if (t != cacheTime) { - breakTime(t, tm); - cacheTime = t; - } + if (t != cacheTime) { + breakTime(t, tm); + cacheTime = t; + } } -int hour() { // the hour now - return hour(now()); +int hour() { // the hour now + return hour(now()); } int hour(time_t t) { // the hour for the given time - refreshCache(t); - return tm.Hour; + refreshCache(t); + return tm.Hour; } int hourFormat12() { // the hour now in 12 hour format - return hourFormat12(now()); + return hourFormat12(now()); } int hourFormat12(time_t t) { // the hour for the given time in 12 hour format - refreshCache(t); - if( tm.Hour == 0 ) - return 12; // 12 midnight - else if( tm.Hour > 12) - return tm.Hour - 12 ; - else - return tm.Hour ; + refreshCache(t); + if (tm.Hour == 0) + return 12; // 12 midnight + else if (tm.Hour > 12) + return tm.Hour - 12; + else + return tm.Hour; } uint8_t isAM() { // returns true if time now is AM - return !isPM(now()); + return !isPM(now()); } uint8_t isAM(time_t t) { // returns true if given time is AM - return !isPM(t); + return !isPM(t); } uint8_t isPM() { // returns true if PM - return isPM(now()); + return isPM(now()); } uint8_t isPM(time_t t) { // returns true if PM - return (hour(t) >= 12); + return (hour(t) >= 12); } int minute() { - return minute(now()); + return minute(now()); } int minute(time_t t) { // the minute for the given time - refreshCache(t); - return tm.Minute; + refreshCache(t); + return tm.Minute; } int second() { - return second(now()); + return second(now()); } -int second(time_t t) { // the second for the given time - refreshCache(t); - return tm.Second; +int second(time_t t) { // the second for the given time + refreshCache(t); + return tm.Second; } -int day(){ - return(day(now())); +int day() { + return (day(now())); } int day(time_t t) { // the day for the given time (0-6) - refreshCache(t); - return tm.Day; + refreshCache(t); + return tm.Day; } -int weekday() { // Sunday is day 1 - return weekday(now()); +int weekday() { // Sunday is day 1 + return weekday(now()); } int weekday(time_t t) { - refreshCache(t); - return tm.Wday; -} - -int month(){ - return month(now()); + refreshCache(t); + return tm.Wday; } -int month(time_t t) { // the month for the given time - refreshCache(t); - return tm.Month; +int month() { + return month(now()); } -int year() { // as in Processing, the full four digit year: (2009, 2010 etc) - return year(now()); +int month(time_t t) { // the month for the given time + refreshCache(t); + return tm.Month; +} + +int year() { // as in Processing, the full four digit year: (2009, 2010 etc) + return year(now()); } int year(time_t t) { // the year for the given time - refreshCache(t); - return tmYearToCalendar(tm.Year); + refreshCache(t); + return tmYearToCalendar(tm.Year); } -const String timeString() -{ - return timeString(now()); +const String timeString() { + return timeString(now()); } -const String timeString(time_t t) -{ - char line[30]; - sprintf(line, "%02d:%02d:%02d", hour(t), minute(t), second(t)); - return String(line); +const String timeString(time_t t) { + char line[30]; + sprintf(line, "%02d:%02d:%02d", hour(t), minute(t), second(t)); + return String(line); } -/*============================================================================*/ +/*============================================================================*/ /* functions to convert to and from system time */ /* These are for interfacing with time services and are not normally needed in a sketch */ // leap year calculator expects year argument as years offset from 1970 -#define LEAP_YEAR(Y) ( ((1970+(Y))>0) && !((1970+(Y))%4) && ( ((1970+(Y))%100) || !((1970+(Y))%400) ) ) +#define LEAP_YEAR(Y) (((1970 + (Y)) > 0) && !((1970 + (Y)) % 4) && (((1970 + (Y)) % 100) || !((1970 + (Y)) % 400))) -static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 - -void breakTime(time_t timeInput, tmElements_t &tm){ -// break the given time_t into time components -// this is a more compact version of the C library localtime function -// note that year is offset from 1970 !!! +static const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // API starts months from 1, this array starts from 0 - uint8_t year; - uint8_t month, monthLength; - uint32_t time; - unsigned long days; +void breakTime(time_t timeInput, tmElements_t &tm) { + // break the given time_t into time components + // this is a more compact version of the C library localtime function + // note that year is offset from 1970 !!! - time = (uint32_t)timeInput; - tm.Second = time % 60; - time /= 60; // now it is minutes - tm.Minute = time % 60; - time /= 60; // now it is hours - tm.Hour = time % 24; - time /= 24; // now it is days - tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 - - year = 0; - days = 0; - while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { - year++; - } - tm.Year = year; // year is offset from 1970 - - days -= LEAP_YEAR(year) ? 366 : 365; - time -= days; // now it is days in this year, starting at 0 - - days=0; - month=0; - monthLength=0; - for (month=0; month<12; month++) { - if (month==1) { // february - if (LEAP_YEAR(year)) { - monthLength=29; - } else { - monthLength=28; - } - } else { - monthLength = monthDays[month]; - } - - if (time >= monthLength) { - time -= monthLength; - } else { - break; - } - } - tm.Month = month + 1; // jan is month 1 - tm.Day = time + 1; // day of month + uint8_t year; + uint8_t month, monthLength; + uint32_t time; + unsigned long days; + + time = (uint32_t)timeInput; + tm.Second = time % 60; + time /= 60; // now it is minutes + tm.Minute = time % 60; + time /= 60; // now it is hours + tm.Hour = time % 24; + time /= 24; // now it is days + tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 + + year = 0; + days = 0; + while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { + year++; + } + tm.Year = year; // year is offset from 1970 + + days -= LEAP_YEAR(year) ? 366 : 365; + time -= days; // now it is days in this year, starting at 0 + + days = 0; + month = 0; + monthLength = 0; + for (month = 0; month < 12; month++) { + if (month == 1) { // february + if (LEAP_YEAR(year)) { + monthLength = 29; + } else { + monthLength = 28; + } + } else { + monthLength = monthDays[month]; + } + + if (time >= monthLength) { + time -= monthLength; + } else { + break; + } + } + tm.Month = month + 1; // jan is month 1 + tm.Day = time + 1; // day of month } -time_t makeTime(const tmElements_t &tm){ -// assemble time elements into time_t -// note year argument is offset from 1970 (see macros in time.h to convert to other formats) -// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 - - int i; - uint32_t seconds; +time_t makeTime(const tmElements_t &tm) { + // assemble time elements into time_t + // note year argument is offset from 1970 (see macros in time.h to convert to other formats) + // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 - // seconds from 1970 till 1 jan 00:00:00 of the given year - seconds= tm.Year*(SECS_PER_DAY * 365); - for (i = 0; i < tm.Year; i++) { - if (LEAP_YEAR(i)) { - seconds += SECS_PER_DAY; // add extra days for leap years - } - } - - // add days for this year, months start from 1 - for (i = 1; i < tm.Month; i++) { - if ( (i == 2) && LEAP_YEAR(tm.Year)) { - seconds += SECS_PER_DAY * 29; - } else { - seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 - } - } - seconds+= (tm.Day-1) * SECS_PER_DAY; - seconds+= tm.Hour * SECS_PER_HOUR; - seconds+= tm.Minute * SECS_PER_MIN; - seconds+= tm.Second; - return (time_t)seconds; + int i; + uint32_t seconds; + + // seconds from 1970 till 1 jan 00:00:00 of the given year + seconds = tm.Year * (SECS_PER_DAY * 365); + for (i = 0; i < tm.Year; i++) { + if (LEAP_YEAR(i)) { + seconds += SECS_PER_DAY; // add extra days for leap years + } + } + + // add days for this year, months start from 1 + for (i = 1; i < tm.Month; i++) { + if ((i == 2) && LEAP_YEAR(tm.Year)) { + seconds += SECS_PER_DAY * 29; + } else { + seconds += SECS_PER_DAY * monthDays[i - 1]; // monthDay array starts from 0 + } + } + seconds += (tm.Day - 1) * SECS_PER_DAY; + seconds += tm.Hour * SECS_PER_HOUR; + seconds += tm.Minute * SECS_PER_MIN; + seconds += tm.Second; + return (time_t)seconds; } -/*=====================================================*/ +/*=====================================================*/ /* Low level system time functions */ -static uint32_t sysTime = 0; -static uint32_t prevMillis = 0; -static uint32_t nextSyncTime = 0; -static timeStatus_t Status = timeNotSet; +static uint32_t sysTime = 0; +static uint32_t prevMillis = 0; +static uint32_t nextSyncTime = 0; +static timeStatus_t Status = timeNotSet; -getExternalTime getTimePtr; // pointer to external sync function -//setExternalTime setTimePtr; // not used in this version +getExternalTime getTimePtr; // pointer to external sync function +// setExternalTime setTimePtr; // not used in this version -#ifdef TIME_DRIFT_INFO // define this to get drift data -time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync +#ifdef TIME_DRIFT_INFO // define this to get drift data +time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync #endif - time_t now() { - // calculate number of seconds passed since last call to now() - while (millis() - prevMillis >= 1000) { - // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference - sysTime++; - prevMillis += 1000; + // calculate number of seconds passed since last call to now() + while (millis() - prevMillis >= 1000) { + // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference + sysTime++; + prevMillis += 1000; #ifdef TIME_DRIFT_INFO - sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift + sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift #endif - } - if (nextSyncTime <= sysTime) { - if (getTimePtr != 0) { - time_t t = getTimePtr(); - if (t != 0) { - setTime(t); - } else { - nextSyncTime = sysTime + syncInterval; - Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; - } - } - } - return (time_t)sysTime; + } + if (nextSyncTime <= sysTime) { + if (getTimePtr != 0) { + time_t t = getTimePtr(); + if (t != 0) { + setTime(t); + } else { + nextSyncTime = sysTime + syncInterval; + Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; + } + } + } + return (time_t)sysTime; } -void setTime(time_t t) { +void setTime(time_t t) { #ifdef TIME_DRIFT_INFO - if(sysUnsyncedTime == 0) - sysUnsyncedTime = t; // store the time of the first call to set a valid Time + if (sysUnsyncedTime == 0) + sysUnsyncedTime = t; // store the time of the first call to set a valid Time #endif - sysTime = (uint32_t)t; - nextSyncTime = (uint32_t)t + syncInterval; - Status = timeSet; - prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) -} + sysTime = (uint32_t)t; + nextSyncTime = (uint32_t)t + syncInterval; + Status = timeSet; + prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) +} -void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ - // year can be given as full four digit year or two digts (2010 or 10 for 2010); - //it is converted to years since 1970 - if( yr > 99) - yr = yr - 1970; - else - yr += 30; - tm.Year = yr; - tm.Month = mnth; - tm.Day = dy; - tm.Hour = hr; - tm.Minute = min; - tm.Second = sec; - setTime(makeTime(tm)); +void setTime(int hr, int min, int sec, int dy, int mnth, int yr) { + // year can be given as full four digit year or two digts (2010 or 10 for 2010); + // it is converted to years since 1970 + if (yr > 99) + yr = yr - 1970; + else + yr += 30; + tm.Year = yr; + tm.Month = mnth; + tm.Day = dy; + tm.Hour = hr; + tm.Minute = min; + tm.Second = sec; + setTime(makeTime(tm)); } void adjustTime(long adjustment) { - sysTime += adjustment; + sysTime += adjustment; } // indicates if time has been set and recently synchronized timeStatus_t timeStatus() { - now(); // required to actually update the status - return Status; + now(); // required to actually update the status + return Status; } -void setSyncProvider( getExternalTime getTimeFunction){ - getTimePtr = getTimeFunction; - nextSyncTime = sysTime; - now(); // this will sync the clock +void setSyncProvider(getExternalTime getTimeFunction) { + getTimePtr = getTimeFunction; + nextSyncTime = sysTime; + now(); // this will sync the clock } -void setSyncInterval(time_t interval){ // set the number of seconds between re-sync - syncInterval = (uint32_t)interval; - nextSyncTime = sysTime + syncInterval; +void setSyncInterval(time_t interval) { // set the number of seconds between re-sync + syncInterval = (uint32_t)interval; + nextSyncTime = sysTime + syncInterval; } diff --git a/lib/TimeLib/TimeLib.h b/lib/TimeLib/TimeLib.h index a5ffb24..15ecd35 100644 --- a/lib/TimeLib/TimeLib.h +++ b/lib/TimeLib/TimeLib.h @@ -5,44 +5,60 @@ /* July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this) - fixed daysToTime_t macro (thanks maniacbug) -*/ +*/ #ifndef _Time_h #define _Time_h -#include #include - -typedef enum {timeNotSet, timeNeedsSync, timeSet -} timeStatus_t ; +#include typedef enum { - dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday + timeNotSet, + timeNeedsSync, + timeSet +} timeStatus_t; + +typedef enum { + dowInvalid, + dowSunday, + dowMonday, + dowTuesday, + dowWednesday, + dowThursday, + dowFriday, + dowSaturday } timeDayOfWeek_t; typedef enum { - tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields -} tmByteFields; + tmSecond, + tmMinute, + tmHour, + tmWday, + tmDay, + tmMonth, + tmYear, + tmNbrFields +} tmByteFields; -typedef struct { - uint8_t Second; - uint8_t Minute; - uint8_t Hour; - uint8_t Wday; // day of week, sunday is day 1 +typedef struct { + uint8_t Second; + uint8_t Minute; + uint8_t Hour; + uint8_t Wday; // day of week, sunday is day 1 uint8_t Day; - uint8_t Month; - uint8_t Year; // offset from 1970; -} tmElements_t, TimeElements, *tmElementsPtr_t; + uint8_t Month; + uint8_t Year; // offset from 1970; +} tmElements_t, TimeElements, *tmElementsPtr_t; -//convenience macros to convert to and from tm years -#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year -#define CalendarYrToTm(Y) ((Y) - 1970) -#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 -#define y2kYearToTm(Y) ((Y) + 30) - -typedef time_t(*getExternalTime)(); -//typedef void (*setExternalTime)(const time_t); // not used in this version +// convenience macros to convert to and from tm years +#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year +#define CalendarYrToTm(Y) ((Y)-1970) +#define tmYearToY2k(Y) ((Y)-30) // offset is from 2000 +#define y2kYearToTm(Y) ((Y) + 30) +typedef time_t (*getExternalTime)(); +// typedef void (*setExternalTime)(const time_t); // not used in this version /*==============================================================================*/ /* Useful Constants */ @@ -52,76 +68,74 @@ typedef time_t(*getExternalTime)(); #define DAYS_PER_WEEK ((time_t)(7UL)) #define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK)) #define SECS_PER_YEAR ((time_t)(SECS_PER_DAY * 365UL)) // TODO: ought to handle leap years -#define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the start of y2k - +#define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the start of y2k + /* Useful Macros for getting elapsed time */ -#define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN) -#define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN) -#define numberOfHours(_time_) (((_time_) % SECS_PER_DAY) / SECS_PER_HOUR) -#define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday -#define elapsedDays(_time_) ((_time_) / SECS_PER_DAY) // this is number of days since Jan 1 1970 -#define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY) // the number of seconds since last midnight +#define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN) +#define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN) +#define numberOfHours(_time_) (((_time_) % SECS_PER_DAY) / SECS_PER_HOUR) +#define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4) % DAYS_PER_WEEK) + 1) // 1 = Sunday +#define elapsedDays(_time_) ((_time_) / SECS_PER_DAY) // this is number of days since Jan 1 1970 +#define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY) // the number of seconds since last midnight // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 // Always set the correct time before setting alarms -#define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day -#define nextMidnight(_time_) (previousMidnight(_time_) + SECS_PER_DAY) // time at the end of the given day -#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY)) // note that week starts on day 1 -#define previousSunday(_time_) ((_time_) - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time -#define nextSunday(_time_) (previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time - +#define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day +#define nextMidnight(_time_) (previousMidnight(_time_) + SECS_PER_DAY) // time at the end of the given day +#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_) - 1) * SECS_PER_DAY)) // note that week starts on day 1 +#define previousSunday(_time_) ((_time_)-elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time +#define nextSunday(_time_) (previousSunday(_time_) + SECS_PER_WEEK) // time at the end of the week for the given time /* Useful Macros for converting elapsed time to a time_t */ -#define minutesToTime_t(M) ((M) * SECS_PER_MIN) -#define hoursToTime_t(H) ((H) * SECS_PER_HOUR) -#define daysToTime_t(D) ((D) * SECS_PER_DAY) // fixed on Jul 22 2011 -#define weeksToTime_t(W) ((W) * SECS_PER_WEEK) +#define minutesToTime_t(M) ((M)*SECS_PER_MIN) +#define hoursToTime_t(H) ((H)*SECS_PER_HOUR) +#define daysToTime_t(D) ((D)*SECS_PER_DAY) // fixed on Jul 22 2011 +#define weeksToTime_t(W) ((W)*SECS_PER_WEEK) /*============================================================================*/ /* time and date functions */ -int hour(); // the hour now -int hour(time_t t); // the hour for the given time -int hourFormat12(); // the hour now in 12 hour format +int hour(); // the hour now +int hour(time_t t); // the hour for the given time +int hourFormat12(); // the hour now in 12 hour format int hourFormat12(time_t t); // the hour for the given time in 12 hour format -uint8_t isAM(); // returns true if time now is AM -uint8_t isAM(time_t t); // returns true the given time is AM -uint8_t isPM(); // returns true if time now is PM -uint8_t isPM(time_t t); // returns true the given time is PM -int minute(); // the minute now -int minute(time_t t); // the minute for the given time -int second(); // the second now -int second(time_t t); // the second for the given time -int day(); // the day now -int day(time_t t); // the day for the given time -int weekday(); // the weekday now (Sunday is day 1) -int weekday(time_t t); // the weekday for the given time -int month(); // the month now (Jan is month 1) -int month(time_t t); // the month for the given time -int year(); // the full four digit year: (2009, 2010 etc) -int year(time_t t); // the year for the given time +uint8_t isAM(); // returns true if time now is AM +uint8_t isAM(time_t t); // returns true the given time is AM +uint8_t isPM(); // returns true if time now is PM +uint8_t isPM(time_t t); // returns true the given time is PM +int minute(); // the minute now +int minute(time_t t); // the minute for the given time +int second(); // the second now +int second(time_t t); // the second for the given time +int day(); // the day now +int day(time_t t); // the day for the given time +int weekday(); // the weekday now (Sunday is day 1) +int weekday(time_t t); // the weekday for the given time +int month(); // the month now (Jan is month 1) +int month(time_t t); // the month for the given time +int year(); // the full four digit year: (2009, 2010 etc) +int year(time_t t); // the year for the given time const String timeString(); const String timeString(time_t t); -time_t now(); // return the current time as seconds since Jan 1 1970 -void setTime(time_t t); -void setTime(int hr,int min,int sec,int day, int month, int yr); -void adjustTime(long adjustment); +time_t now(); // return the current time as seconds since Jan 1 1970 +void setTime(time_t t); +void setTime(int hr, int min, int sec, int day, int month, int yr); +void adjustTime(long adjustment); -/* date strings */ +/* date strings */ #define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null) const String monthStr(uint8_t month); const String dayStr(uint8_t day); const String monthShortStr(uint8_t month); const String dayShortStr(uint8_t day); - + /* time sync functions */ -timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized -void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider -void setSyncInterval(time_t interval); // set the number of seconds between re-sync +timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized +void setSyncProvider(getExternalTime getTimeFunction); // identify the external time provider +void setSyncInterval(time_t interval); // set the number of seconds between re-sync /* low level functions to convert to and from system time */ -void breakTime(time_t time, tmElements_t &tm); // break time_t into elements -time_t makeTime(const tmElements_t &tm); // convert time elements into time_t +void breakTime(time_t time, tmElements_t &tm); // break time_t into elements +time_t makeTime(const tmElements_t &tm); // convert time elements into time_t #endif /* _Time_h */ - diff --git a/lib/TimeLib/TimeLibString.cpp b/lib/TimeLib/TimeLibString.cpp index 49bb0e8..36970f1 100644 --- a/lib/TimeLib/TimeLibString.cpp +++ b/lib/TimeLib/TimeLibString.cpp @@ -4,53 +4,34 @@ * Updated for Arduino 1.5.7 18 July 2014 * * No memory is consumed in the sketch if your code does not call any of the string methods - * You can change the text of the strings, make sure the short strings are each exactly 3 characters + * You can change the text of the strings, make sure the short strings are each exactly 3 characters * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in TimeLib.h - * + * */ -#include #include "TimeLib.h" +#include -const String monthNames[] = -{ - "Error", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" -}; +const String monthNames[] = {"Error", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; -const String monthStr(uint8_t month) -{ - return monthNames[month]; +const String monthStr(uint8_t month) { + return monthNames[month]; } +const String monthShortNames[] = {"Err", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -const String monthShortNames[] = -{ - "Err", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -const String monthShortStr(uint8_t month) -{ - return monthShortNames[month]; +const String monthShortStr(uint8_t month) { + return monthShortNames[month]; } +const String dayNames[] = {"Err", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; -const String dayNames[] = -{ - "Err", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" -}; - -const String dayStr(uint8_t day) -{ - return dayNames[day]; +const String dayStr(uint8_t day) { + return dayNames[day]; } +const String dayShortNames[] = {"Err", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -const String dayShortNames[] = -{ - "Err", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -const String dayShortStr(uint8_t day) -{ - return dayShortNames[day]; +const String dayShortStr(uint8_t day) { + return dayShortNames[day]; } diff --git a/platformio.ini b/platformio.ini index 401fc3b..bee7c42 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,10 +19,9 @@ lib_deps = jgromes/RadioLib @ 5.7.0 check_tool = cppcheck check_flags = - cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK --force lib -ilib/TimeLib -ilib/LoRa -ilib/NTPClient + cppcheck: --std=c++14 --suppress=*:*.pio\* --inline-suppr --suppress=unusedFunction -DCPPCHECK --force lib -ilib/TimeLib check_skip_packages = yes test_build_src = yes -#monitor_flags = --raw # activate for OTA Update, use the CALLSIGN from is-cfg.json as upload_port: #upload_protocol = espota #upload_port = .local @@ -35,4 +34,4 @@ build_flags = -Werror -Wall -DUNITY_INCLUDE_PRINT_FORMATTED board = esp32doit-devkit-v1 build_flags = -Werror -Wall -DCORE_DEBUG_LEVEL=5 -DUNITY_INCLUDE_PRINT_FORMATTED build_type = debug -monitor_filters = esp32_exception_decoder +#monitor_filters = esp32_exception_decoder diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 5f3f863..e568b9a 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -37,7 +37,7 @@ System LoRaSystem; Configuration userConfig; DisplayTask displayTask; -// ModemTask modemTask(fromModem, toModem); +// ModemTask modemTask(fromModem, toModem); RadiolibTask modemTask(fromModem, toModem); EthTask ethTask; WifiTask wifiTask;