2020-10-25 20:48:57 +01:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * Program : OTGW - firmware . ino
2021-03-25 21:16:04 +01:00
* * Version : v0 .8 .2
2020-10-25 20:48:57 +01:00
* *
2021-01-11 00:37:30 +01:00
* * Copyright ( c ) 2021 Robert van den Breemen
2020-10-25 20:48:57 +01:00
* *
* * TERMS OF USE : MIT License . See bottom of file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2020-12-10 13:24:40 +01:00
/*
2021-01-31 23:43:52 +01:00
* How to install the OTGW on your nodeMCU :
* Read this : https : //github.com/rvdbreemen/OTGW-firmware/wiki/How-to-compile-OTGW-firmware-yourself
2020-12-10 13:24:40 +01:00
*
2021-01-31 23:43:52 +01:00
* How to upload to your LittleFS ?
* Read this : https : //github.com/rvdbreemen/OTGW-firmware/wiki/Upload-files-to-LittleFS-(filesystem)
*
2020-12-10 13:24:40 +01:00
* How to compile this firmware ?
* - NodeMCU v1 .0
* - Flashsize ( 4 MB - FS : 2 MB - OTA ~ 1019 KB )
* - CPU frequentcy : 160 MHz
* - Normal defaults should work fine .
* First time : Make sure to flash sketch + wifi or flash ALL contents .
*
*/
2020-10-25 20:48:57 +01:00
# include "version.h"
# define _FW_VERSION _VERSION
2020-10-25 20:35:34 +01:00
2020-10-25 20:48:57 +01:00
# include "OTGW-firmware.h"
2020-10-25 20:35:34 +01:00
2021-02-08 00:13:52 +01:00
# define ON LOW
# define OFF HIGH
2021-03-14 21:58:35 +01:00
DECLARE_TIMER_SEC ( timerpollsensor , settingGPIOSENSORSinterval , CATCH_UP_MISSED_TICKS ) ;
2020-10-25 20:35:34 +01:00
//=====================================================================
2021-02-14 19:26:37 +01:00
void setup ( ) {
2021-02-08 00:13:52 +01:00
// Serial is initialized by OTGWSerial. It resets the pic and opens serialdevice.
// OTGWSerial.begin();//OTGW Serial device that knows about OTGW PIC
// while (!Serial) {} //Wait for OK
OTGWSerial . println ( F ( " \r \n [OTGW firmware - Nodoshop version] \r \n " ) ) ;
OTGWSerial . printf ( " Booting....[%s] \r \n \r \n " , String ( _FW_VERSION ) . c_str ( ) ) ;
2021-02-02 00:36:36 +01:00
rebootCount = updateRebootCount ( ) ;
2020-10-25 20:35:34 +01:00
//setup randomseed the right way
randomSeed ( RANDOM_REG32 ) ; //This is 8266 HWRNG used to seed the Random PRNG: Read more: https://config9.com/arduino/getting-a-truly-random-number-in-arduino/
2021-03-06 10:52:51 +01:00
lastReset = ESP . getResetReason ( ) ;
2021-02-08 00:13:52 +01:00
OTGWSerial . printf ( " Last reset reason: [%s] \r \n " , CSTR ( ESP . getResetReason ( ) ) ) ;
2020-10-25 20:35:34 +01:00
//setup the status LED
2021-02-08 00:13:52 +01:00
setLed ( LED1 , ON ) ;
setLed ( LED2 , ON ) ;
2020-10-25 20:35:34 +01:00
2021-02-14 19:26:37 +01:00
LittleFS . begin ( ) ;
2020-10-25 20:35:34 +01:00
readSettings ( true ) ;
// Connect to and initialise WiFi network
2021-02-08 00:13:52 +01:00
OTGWSerial . println ( F ( " Attempting to connect to WiFi network \r " ) ) ;
setLed ( LED1 , ON ) ;
2021-03-25 21:08:09 +01:00
startWiFi ( CSTR ( settingHostname ) , 240 ) ; // timeout 240 seconds
2021-03-06 10:52:51 +01:00
blinkLED ( LED1 , 3 , 100 ) ;
2021-02-08 00:13:52 +01:00
setLed ( LED1 , OFF ) ;
2021-03-07 10:55:52 +01:00
startTelnet ( ) ; // start the debug port 23
2020-12-31 02:20:47 +01:00
startMDNS ( CSTR ( settingHostname ) ) ;
2021-03-06 19:14:08 +01:00
startLLMNR ( CSTR ( settingHostname ) ) ;
2020-10-31 18:46:04 +01:00
startMQTT ( ) ;
2021-02-14 19:26:37 +01:00
startNTP ( ) ;
2020-10-25 20:35:34 +01:00
setupFSexplorer ( ) ;
2021-02-19 01:48:31 +01:00
startWebserver ( ) ;
2021-02-08 00:13:52 +01:00
OTGWSerial . println ( F ( " Setup finished! \r \n " ) ) ;
2021-02-02 19:24:31 +01:00
// After resetting the OTGW PIC never send anything to Serial for debug
// and switch to telnet port 23 for debug purposed.
2021-01-31 23:43:52 +01:00
// Setup the OTGW PIC
2021-01-18 21:53:53 +01:00
resetOTGW ( ) ; // reset the OTGW pic
2021-02-02 00:56:38 +01:00
startOTGWstream ( ) ; // start port 25238
2021-03-06 10:52:51 +01:00
checkOTWGpicforupdate ( ) ;
2021-03-12 09:07:17 +01:00
initSensors ( ) ; // init DS18B20
2021-03-06 10:52:51 +01:00
initWatchDog ( ) ; // setup the WatchDog
2021-03-14 23:05:56 +01:00
sendOTGWbootcmd ( ) ;
2021-02-08 00:13:52 +01:00
//Blink LED2 to signal setup done
2021-03-06 10:36:07 +01:00
setLed ( LED1 , OFF ) ;
2021-03-06 10:52:51 +01:00
blinkLED ( LED2 , 3 , 100 ) ;
2021-02-08 00:13:52 +01:00
setLed ( LED2 , OFF ) ;
2021-03-15 22:18:30 +01:00
}
2020-10-25 20:35:34 +01:00
//=====================================================================
//===[ blink status led ]===
2021-02-08 00:13:52 +01:00
void setLed ( uint8_t led , uint8_t status ) {
pinMode ( led , OUTPUT ) ;
digitalWrite ( led , status ) ;
}
void blinkLEDms ( uint32_t delay ) {
2020-10-25 20:35:34 +01:00
//blink the statusled, when time passed
2021-02-08 00:13:52 +01:00
DECLARE_TIMER_MS ( timerBlink , delay ) ;
2020-10-25 20:35:34 +01:00
if ( DUE ( timerBlink ) ) {
blinkLEDnow ( ) ;
}
}
2021-03-06 10:54:53 +01:00
void blinkLED ( uint8_t led , int nr , uint32_t waittime_ms ) {
2021-03-06 10:52:51 +01:00
for ( int i = nr ; i > 0 ; i - - ) {
blinkLEDnow ( led ) ;
delayms ( waittime_ms ) ;
blinkLEDnow ( led ) ;
delayms ( waittime_ms ) ;
}
2021-02-08 00:13:52 +01:00
}
void blinkLEDnow ( uint8_t led = LED1 ) {
pinMode ( led , OUTPUT ) ;
digitalWrite ( led , ! digitalRead ( led ) ) ;
2020-10-25 20:35:34 +01:00
}
//===[ no-blocking delay with running background tasks in ms ]===
void delayms ( unsigned long delay_ms )
{
DECLARE_TIMER_MS ( timerDelayms , delay_ms ) ;
while ( DUE ( timerDelayms ) )
doBackgroundTasks ( ) ;
}
//=====================================================================
//===[ Do task every 1s ]===
void doTaskEvery1s ( ) {
//== do tasks ==
2021-03-18 00:53:30 +01:00
handleOTGWqueue ( ) ; //just check if there are commands to retry
2020-10-25 20:35:34 +01:00
upTimeSeconds + + ;
}
//===[ Do task every 5s ]===
void doTaskEvery5s ( ) {
//== do tasks ==
2021-03-14 21:58:35 +01:00
2020-10-25 20:35:34 +01:00
}
//===[ Do task every 30s ]===
void doTaskEvery30s ( ) {
//== do tasks ==
}
//===[ Do task every 60s ]===
void doTaskEvery60s ( ) {
2020-11-19 16:47:10 +01:00
//== do tasks ==
2020-12-13 02:06:05 +01:00
//if no wifi, try reconnecting (once a minute)
if ( WiFi . status ( ) ! = WL_CONNECTED )
{
//disconnected, try to reconnect then...
2021-03-25 21:08:09 +01:00
startWiFi ( CSTR ( settingHostname ) , 240 ) ;
2020-12-13 02:06:05 +01:00
//check OTGW and telnet
startTelnet ( ) ;
startOTGWstream ( ) ;
}
2020-10-25 20:35:34 +01:00
}
2021-03-08 02:15:28 +01:00
//===[ Do task every 5min ]===
void do5minevent ( ) {
2021-03-23 23:17:53 +01:00
DebugTf ( " Uptime seconds: %d \r \n " , upTimeSeconds ) ;
2021-03-08 02:38:24 +01:00
String sUptime = String ( upTimeSeconds ) ;
sendMQTTData ( " otgw-firmware/uptime " , sUptime , false ) ;
2021-03-08 02:15:28 +01:00
}
2021-02-20 17:49:56 +01:00
//===[ check for new pic version ]===
void docheckforpic ( ) {
String latest = checkforupdatepic ( " gateway.hex " ) ;
if ( ! bOTGWonline ) {
sMessage = sPICfwversion ;
} else if ( latest ! = sPICfwversion ) {
sMessage = " New PIC version " + latest + " available! " ;
}
}
2020-10-25 20:35:34 +01:00
//===[ Do the background tasks ]===
void doBackgroundTasks ( )
{
2020-11-02 08:09:26 +01:00
feedWatchDog ( ) ; // Feed the dog before it bites!
2020-10-25 23:25:49 +01:00
handleMQTT ( ) ; // MQTT transmissions
2020-11-20 00:43:22 +01:00
handleOTGW ( ) ; // OTGW handling
2020-10-25 20:35:34 +01:00
httpServer . handleClient ( ) ;
MDNS . update ( ) ;
2021-03-14 21:58:35 +01:00
events ( ) ; // trigger ezTime update etc
2020-11-20 00:43:22 +01:00
delay ( 1 ) ;
2021-02-28 15:44:53 +01:00
handleDebug ( ) ;
2020-10-25 20:35:34 +01:00
}
void loop ( )
{
DECLARE_TIMER_SEC ( timer1s , 1 , CATCH_UP_MISSED_TICKS ) ;
DECLARE_TIMER_SEC ( timer5s , 5 , CATCH_UP_MISSED_TICKS ) ;
DECLARE_TIMER_SEC ( timer30s , 30 , CATCH_UP_MISSED_TICKS ) ;
DECLARE_TIMER_SEC ( timer60s , 60 , CATCH_UP_MISSED_TICKS ) ;
2021-02-20 17:49:56 +01:00
DECLARE_TIMER_MIN ( tmrcheckpic , 1440 , CATCH_UP_MISSED_TICKS ) ;
2021-03-08 02:15:28 +01:00
DECLARE_TIMER_MIN ( timer5min , 5 , CATCH_UP_MISSED_TICKS ) ;
2021-03-14 21:58:35 +01:00
if ( DUE ( timer1s ) ) doTaskEvery1s ( ) ;
if ( DUE ( timer5s ) ) doTaskEvery5s ( ) ;
if ( DUE ( timer30s ) ) doTaskEvery30s ( ) ;
if ( DUE ( timer60s ) ) doTaskEvery60s ( ) ;
if ( DUE ( tmrcheckpic ) ) docheckforpic ( ) ;
if ( DUE ( timer5min ) ) do5minevent ( ) ;
if ( DUE ( timerpollsensor ) ) pollSensors ( ) ;
2020-10-25 20:35:34 +01:00
doBackgroundTasks ( ) ;
}
2021-01-30 18:35:11 +01:00
/***************************************************************************
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the
* " Software " ) , to deal in the Software without restriction , including
* without limitation the rights to use , copy , modify , merge , publish ,
* distribute , sublicense , and / or sell copies of the Software , and to permit
* persons to whom the Software is furnished to do so , subject to the
* following conditions :
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS
* OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT .
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT
* OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/