diff --git a/lib/obp60task/OBP60ExtensionPort.cpp b/lib/obp60task/OBP60ExtensionPort.cpp index 757c939..b47f0bd 100644 --- a/lib/obp60task/OBP60ExtensionPort.cpp +++ b/lib/obp60task/OBP60ExtensionPort.cpp @@ -104,29 +104,37 @@ void setBuzzerPower(uint power){ buzzerpower = power; } +/* void underVoltageDetection(){ - noInterrupts(); - float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 + float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // V = 1/20 * Vin + long starttime; + static bool undervoltage = false; + if(actVoltage < MIN_VOLTAGE){ - uvDuration ++; + if(undervoltage == false){ + starttime = millis(); + undervoltage = true; + } + if(millis() > starttime + POWER_FAIL_TIME){ +// Timer1.detach(); // Stop Timer1 + setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off + setPortPin(OBP_FLASH_LED, false); // Flash LED Off + buzzer(TONE4, 20); // Buzzer tone 4kHz 20% 20ms + // Shutdown EInk display + display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen + display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); // Partial update + setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off + setPortPin(OBP_POWER_33, false); // Power rail 3.3V Off + // display._sleep(); // Display shut dow + // Stop system + while(true){ + esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart). + } + } } else{ - uvDuration = 0; + undervoltage = false; } - if(uvDuration > POWER_FAIL_TIME){ - setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off - setPortPin(OBP_FLASH_LED, false); // Flash LED Off - buzzer(TONE4, 20); // Buzzer tone 4kHz 20% 20ms - setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off - setPortPin(OBP_POWER_33, false); // Power rail 3.3V Off - // Shutdown EInk display - display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen - display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); // Partial update - // display._sleep(); // Display shut dow - // Stop system - while(true){ - esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart). - } - } - interrupts(); + } +*/ \ No newline at end of file diff --git a/lib/obp60task/OBP60ExtensionPort.h b/lib/obp60task/OBP60ExtensionPort.h index 52d6733..f104232 100644 --- a/lib/obp60task/OBP60ExtensionPort.h +++ b/lib/obp60task/OBP60ExtensionPort.h @@ -33,6 +33,6 @@ void setBlinkingLED(bool on); // Set blinking LED active void buzzer(uint frequency, uint duration); // Buzzer function void setBuzzerPower(uint power); // Set buzzer power -void underVoltageDetection(); // Function for 12V undervoltage detection +// void underVoltageDetection(); // Function for 12V undervoltage detection #endif \ No newline at end of file diff --git a/lib/obp60task/OBP60Formater.cpp b/lib/obp60task/OBP60Formater.cpp index 85e67b1..6a2a374 100644 --- a/lib/obp60task/OBP60Formater.cpp +++ b/lib/obp60task/OBP60Formater.cpp @@ -20,7 +20,6 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){ if (! value->valid){ result.svalue = "---"; - result.unit = ""; return result; } static const int bsize = 30; @@ -166,15 +165,15 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){ else if (value->getFormat() == "formatDop"){ double dop = value->value; result.unit = "m"; + if(dop > 99.9){ + dop = 99.9; + } if(dop < 10){ snprintf(buffer,bsize,"%2.1f",dop); } if(dop >= 10 && dop < 100){ snprintf(buffer,bsize,"%2.1f",dop); } - if(dop >= 100){ - snprintf(buffer,bsize,"%3.0f",dop); - } } else if (value->getFormat() == "formatLatitude"){ double lat = value->value; diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index d8bde37..05d3041 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -42,7 +42,7 @@ #define OBP_ANALOG1 36 // Analog In 1 #define OBP_ANALOG2 39 // Analog In 2 #define MIN_VOLTAGE 9.0 // Min voltage for under voltage detection (then goto deep sleep) - #define POWER_FAIL_TIME 2 // Accept min voltage until 2 x 1ms (for under voltage gaps by engine start) + #define POWER_FAIL_TIME 2 // in [ms] Accept min voltage until 2 x 1ms (for under voltage gaps by engine start) // Extension Port MCP23017 #define MCP23017_I2C_ADDR 0x20 // Addr. 0 is 0x20 // Extension Port PA diff --git a/lib/obp60task/PageOneValue.cpp b/lib/obp60task/PageOneValue.cpp index b60a506..c089da1 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -50,8 +50,7 @@ class PageOneValue : public Page{ pixelcolor = GxEPD_WHITE; bgcolor = GxEPD_BLACK; } - display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Draw white sreen - display.setTextColor(textcolor); + // Clear display in obp60task.cpp in main loop // Show name display.setFont(&Ubuntu_Bold32pt7b); diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index 5dcbcbc..4c4baec 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -30,6 +30,7 @@ public: String flashLED = config->getString(config->flashLED); int batVoltage = config->getInt(config->batteryVoltage); String batType = config->getString(config->batteryType); + String backlightMode = config->getString(config->backlight); // Get voltage value String name1 = "VBat"; @@ -39,10 +40,10 @@ public: // Optical warning by limit violation if(String(flashLED) == "Limit Violation"){ // Limits for Pb battery - if(String(batType) == "Pb" && (value1 < 10.0 || value1 > 14.5)){ + if(String(batType) == "Pb" && (value1 < 11.0 || value1 > 14.5)){ setBlinkingLED(true); } - if(String(batType) == "Pb" && (value1 >= 10.0 && value1 <= 14.5)){ + if(String(batType) == "Pb" && (value1 >= 11.0 && value1 <= 14.5)){ setBlinkingLED(false); setPortPin(OBP_FLASH_LED, false); } @@ -69,8 +70,7 @@ public: pixelcolor = GxEPD_WHITE; bgcolor = GxEPD_BLACK; } - display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Draw white sreen - display.setTextColor(textcolor); + //Clear display in obp60task.cpp in main loop // Show name display.setFont(&Ubuntu_Bold32pt7b); @@ -113,8 +113,10 @@ public: display.setFont(&Ubuntu_Bold8pt7b); display.setCursor(115, 290); display.print(" [ <<<<<< >>>>>> ]"); - display.setCursor(343, 290); - display.print("[ILUM]"); + if(String(backlightMode) == "Control by Key"){ + display.setCursor(343, 290); + display.print("[ILUM]"); + } // Update display display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Partial update (fast) diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 6d49633..e995610 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -289,7 +289,7 @@ "name": "underVoltage", "label": "Undervoltage", "type": "boolean", - "default": "false", + "default": "true", "description": "If undervoltage detection [on|off] lower than 9V then switch off the device", "category": "OBP60 Hardware", "capabilities": { diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 26d36dc..1b5b131 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -20,21 +20,57 @@ //#include GxEPD_BitmapExamples // Example picture #include "MFD_OBP60_400x300_sw.h" // MFD with logo #include "Logo_OBP_400x300_sw.h" // OBP Logo - #include "OBP60QRWiFi.h" // Functions lib for WiFi QR code - -tNMEA0183Msg NMEA0183Msg; -tNMEA0183 NMEA0183; - +/* // Timer Interrupts for hardware functions Ticker Timer1; // Under voltage detection Ticker Timer2; // Binking flash LED +*/ +tNMEA0183Msg NMEA0183Msg; +tNMEA0183 NMEA0183; // Global vars bool initComplete = false; // Initialization complete int taskRunCounter = 0; // Task couter for loop section bool gps_ready = false; // GPS initialized and ready to use +// Timer Interrupts for hardware functions +void underVoltageDetection(); +Ticker Timer1(underVoltageDetection, 1); // Start Timer1 with maximum speed with 1ms +Ticker Timer2(blinkingFlashLED, 500); + +void underVoltageDetection(){ + float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // V = 1/20 * Vin + long starttime; + static bool undervoltage = false; + + if(actVoltage < MIN_VOLTAGE){ + if(undervoltage == false){ + starttime = millis(); + undervoltage = true; + } + if(millis() > starttime + POWER_FAIL_TIME){ + Timer1.stop(); // Stop Timer1 + setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off + setPortPin(OBP_FLASH_LED, false); // Flash LED Off + buzzer(TONE4, 20); // Buzzer tone 4kHz 20% 20ms + setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off + setPortPin(OBP_POWER_33, false); // Power rail 3.3V Off + // Shutdown EInk display + display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen +// display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); // Partial update + display.update(); + // display._sleep(); // Display shut dow + // Stop system + while(true){ + esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart). + } + } + } + else{ + undervoltage = false; + } +} // Hardware initialization before start all services //################################################## @@ -42,12 +78,12 @@ void OBP60Init(GwApi *api){ GwLog *logger = api->getLogger(); api->getLogger()->logDebug(GwLog::LOG,"obp60init running"); - // Define timer interrupts + // Start timer interrupts bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean(); if(uvoltage == true){ - Timer1.attach_ms(1, underVoltageDetection); // Maximum speed with 1ms + Timer1.start(); // Start Timer1 for undervoltage detection } - Timer2.attach_ms(500, blinkingFlashLED); + Timer2.start(); // Start Timer2 for blinking LED // Extension port MCP23017 // Check I2C devices MCP23017 @@ -365,28 +401,39 @@ void OBP60Task(GwApi *api){ // Task Loop //############################### - GwApi::BoatValue *hdop = boatValues.findValueOrCreate("HDOP"); // Load HDOP + + // Configuration values for main loop String gpsFix = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString(); + bool gps = api->getConfig()->getConfigItem(api->getConfig()->useGPS,true)->asBoolean(); + String backlight = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString(); + // refreshmode defined in init section + // displaycolor defined in init section + // textcolor defined in init section + // pixelcolor defined in init section + // bgcolor defined in init section + + // Boat values for main loop + GwApi::BoatValue *hdop = boatValues.findValueOrCreate("HDOP"); // Load HDOP LOG_DEBUG(GwLog::LOG,"obp60task: start mainloop"); int pageNumber=0; int lastPage=pageNumber; long starttime0 = millis(); // Mainloop long starttime1 = millis(); // Full display refresh - long starttime3 = millis(); // GPS data + long starttime2 = millis(); // Display update + while (true){ + Timer1.update(); // Update for Timer1 + Timer2.update(); // Update for Timer2 if(millis() > starttime0 + 100){ starttime0 = millis(); // Send NMEA0183 GPS data on several bus systems all 1000ms - if(millis() > starttime3 + 1000){ - bool gps = api->getConfig()->getConfigItem(api->getConfig()->useGPS,true)->asBoolean(); - if(gps == true){ // If config enabled - if(gps_ready = true){ - tNMEA0183Msg NMEA0183Msg; - while(NMEA0183.GetMessage(NMEA0183Msg)){ - api->sendNMEA0183Message(NMEA0183Msg); - } + if(gps == true){ // If config enabled + if(gps_ready = true){ + tNMEA0183Msg NMEA0183Msg; + while(NMEA0183.GetMessage(NMEA0183Msg)){ + api->sendNMEA0183Message(NMEA0183Msg); } } } @@ -412,7 +459,6 @@ void OBP60Task(GwApi *api){ { // Decoding all key codes // #6 Backlight on if key controled - String backlight = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString(); if(String(backlight) == "Control by Key"){ if(keyboardMessage == 6){ LOG_DEBUG(GwLog::LOG,"Toggle Backlight LED"); @@ -434,7 +480,6 @@ void OBP60Task(GwApi *api){ pageNumber = numPages - 1; } // #9 or #10 Refresh display befor start a new page if reshresh is enabled - bool refreshmode = api->getConfig()->getConfigItem(api->getConfig()->refresh,true)->asBoolean(); if(refreshmode == true && (keyboardMessage == 9 || keyboardMessage == 10)){ display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Needs partial update before full update to refresh the frame buffer @@ -446,37 +491,43 @@ void OBP60Task(GwApi *api){ // Subtask E-Ink full refresh if(millis() > starttime1 + FULL_REFRESH_TIME * 1000){ + starttime1 = millis(); LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh"); display.update(); // Full update - starttime1 = millis(); } - //refresh data from api - api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues); - api->getStatus(commonData.status); + // Refresh display data + if(millis() > starttime2 + 1000){ + starttime2 = millis(); + //refresh data from api + api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues); + api->getStatus(commonData.status); - //handle the page - if (pages[pageNumber].description && pages[pageNumber].description->header){ - //build some header and footer using commonData - display.setFont(&Ubuntu_Bold32pt7b); - display.setCursor(20, 100); - display.print("Hallo"); - } - - //call the particular page - Page *currentPage=pages[pageNumber].page; - if (currentPage == NULL){ - LOG_DEBUG(GwLog::ERROR,"page number %d not found",pageNumber); - // Error handling for missing page - } - else{ - if (lastPage != pageNumber){ - currentPage->displayNew(commonData,pages[pageNumber].parameters); - lastPage=pageNumber; + // Show header if enabled + display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Clear sreen + if (pages[pageNumber].description && pages[pageNumber].description->header){ + //build some header and footer using commonData + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold8pt7b); + display.setCursor(0, 15); + display.print("AP TCP GPS"); + } + + // Call the particular page + Page *currentPage=pages[pageNumber].page; + if (currentPage == NULL){ + LOG_DEBUG(GwLog::ERROR,"page number %d not found",pageNumber); + // Error handling for missing page + } + else{ + if (lastPage != pageNumber){ + currentPage->displayNew(commonData,pages[pageNumber].parameters); + lastPage=pageNumber; + } + //call the page code + LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber); + currentPage->displayPage(commonData,pages[pageNumber].parameters); } - //call the page code - LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber); - currentPage->displayPage(commonData,pages[pageNumber].parameters); } } diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index e64f1d4..de67cea 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -12,6 +12,7 @@ lib_deps = blemasle/MCP23017 @ 2.0.0 adafruit/Adafruit BusIO @ 1.5.0 zinggjm/GxEPD @ 3.1.0 + sstaub/Ticker @ 4.4.0 build_flags= -D BOARD_NODEMCU32S_OBP60 ${env.build_flags} diff --git a/platformio.ini b/platformio.ini index cd07950..b4b2038 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,13 +7,10 @@ ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html + [platformio] -default_envs= - m5stack-atom - m5stack-atom-canunit - m5stickc-atom-canunit - nodemcu-homberger -extra_configs= +default_envs = nodemcu32s_obp60 +extra_configs = lib/*task*/platformio.ini [env] @@ -33,18 +30,20 @@ board_build.embed_files = lib/generated/config.json.gz lib/generated/xdrconfig.json.gz lib/generated/md5.js.gz -board_build.partitions = partitions_custom.csv +board_build.partitions = partitions_custom.csv extra_scripts = pre:extra_script.py post:post.py -lib_ldf_mode = chain+ +lib_ldf_mode = chain+ monitor_speed = 115200 build_flags = -D PIO_ENV_BUILD=$PIOENV [env:m5stack-atom] board = m5stack-atom -lib_deps = ${env.lib_deps} +lib_deps = + ${env.lib_deps} + sstaub/Ticker@^4.4.0 build_flags = -D BOARD_M5ATOM ${env.build_flags} @@ -53,7 +52,9 @@ upload_protocol = esptool [env:m5stack-atom-canunit] board = m5stack-atom -lib_deps = ${env.lib_deps} +lib_deps = + ${env.lib_deps} + sstaub/Ticker@^4.4.0 build_flags = -D BOARD_M5ATOM_CANUNIT ${env.build_flags} @@ -62,7 +63,9 @@ upload_protocol = esptool [env:m5stickc-atom-canunit] board = m5stick-c -lib_deps = ${env.lib_deps} +lib_deps = + ${env.lib_deps} + sstaub/Ticker@^4.4.0 build_flags = -D BOARD_M5STICK_CANUNIT -D HAS_RTC -D HAS_M5LCD ${env.build_flags} @@ -71,9 +74,40 @@ upload_protocol = esptool [env:nodemcu-homberger] board = nodemcu-32s -lib_deps = ${env.lib_deps} +lib_deps = + ${env.lib_deps} + sstaub/Ticker@^4.4.0 build_flags = -D BOARD_HOMBERGER ${env.build_flags} upload_port = /dev/esp32 upload_protocol = esptool + +[env:testboard] +board = m5stack-atom +lib_deps = + ${env.lib_deps} + own_lib + sstaub/Ticker@^4.4.0 +build_flags = + -D BOARD_TEST + ${env.build_flags} +upload_port = /dev/esp32 +upload_protocol = esptool + +[env:nodemcu32s_obp60] +board_build.partitions = lib/obp60task/partitions_obp60.csv +board = nodemcu-32s +lib_deps = + ${env.lib_deps} + lib_deps = + blemasle/MCP23017 @ 2.0.0 + adafruit/Adafruit BusIO @ 1.5.0 + zinggjm/GxEPD @ 3.1.0 + sstaub/Ticker@^4.4.0 +build_flags = + -D BOARD_NODEMCU32S_OBP60 + ${env.build_flags} +upload_port = COM3 +upload_protocol = esptool +monitor_speed = 115200