Shutdown function

This commit is contained in:
norbert-walter 2022-02-25 14:18:36 +01:00
parent 0237ed761d
commit 2e887e9a81
10 changed files with 186 additions and 92 deletions

View File

@ -104,29 +104,37 @@ void setBuzzerPower(uint power){
buzzerpower = power; buzzerpower = power;
} }
/*
void underVoltageDetection(){ void underVoltageDetection(){
noInterrupts(); float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // V = 1/20 * Vin
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 long starttime;
static bool undervoltage = false;
if(actVoltage < MIN_VOLTAGE){ if(actVoltage < MIN_VOLTAGE){
uvDuration ++; if(undervoltage == false){
starttime = millis();
undervoltage = true;
} }
else{ if(millis() > starttime + POWER_FAIL_TIME){
uvDuration = 0; // Timer1.detach(); // Stop Timer1
}
if(uvDuration > POWER_FAIL_TIME){
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setPortPin(OBP_FLASH_LED, false); // Flash LED Off setPortPin(OBP_FLASH_LED, false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20% 20ms 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 // Shutdown EInk display
display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen 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.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 // display._sleep(); // Display shut dow
// Stop system // Stop system
while(true){ while(true){
esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart). esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart).
} }
} }
interrupts(); }
else{
undervoltage = false;
}
} }
*/

View File

@ -33,6 +33,6 @@ void setBlinkingLED(bool on); // Set blinking LED active
void buzzer(uint frequency, uint duration); // Buzzer function void buzzer(uint frequency, uint duration); // Buzzer function
void setBuzzerPower(uint power); // Set buzzer power void setBuzzerPower(uint power); // Set buzzer power
void underVoltageDetection(); // Function for 12V undervoltage detection // void underVoltageDetection(); // Function for 12V undervoltage detection
#endif #endif

View File

@ -20,7 +20,6 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
if (! value->valid){ if (! value->valid){
result.svalue = "---"; result.svalue = "---";
result.unit = "";
return result; return result;
} }
static const int bsize = 30; static const int bsize = 30;
@ -166,15 +165,15 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
else if (value->getFormat() == "formatDop"){ else if (value->getFormat() == "formatDop"){
double dop = value->value; double dop = value->value;
result.unit = "m"; result.unit = "m";
if(dop > 99.9){
dop = 99.9;
}
if(dop < 10){ if(dop < 10){
snprintf(buffer,bsize,"%2.1f",dop); snprintf(buffer,bsize,"%2.1f",dop);
} }
if(dop >= 10 && dop < 100){ if(dop >= 10 && dop < 100){
snprintf(buffer,bsize,"%2.1f",dop); snprintf(buffer,bsize,"%2.1f",dop);
} }
if(dop >= 100){
snprintf(buffer,bsize,"%3.0f",dop);
}
} }
else if (value->getFormat() == "formatLatitude"){ else if (value->getFormat() == "formatLatitude"){
double lat = value->value; double lat = value->value;

View File

@ -42,7 +42,7 @@
#define OBP_ANALOG1 36 // Analog In 1 #define OBP_ANALOG1 36 // Analog In 1
#define OBP_ANALOG2 39 // Analog In 2 #define OBP_ANALOG2 39 // Analog In 2
#define MIN_VOLTAGE 9.0 // Min voltage for under voltage detection (then goto deep sleep) #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 // Extension Port MCP23017
#define MCP23017_I2C_ADDR 0x20 // Addr. 0 is 0x20 #define MCP23017_I2C_ADDR 0x20 // Addr. 0 is 0x20
// Extension Port PA // Extension Port PA

View File

@ -50,8 +50,7 @@ class PageOneValue : public Page{
pixelcolor = GxEPD_WHITE; pixelcolor = GxEPD_WHITE;
bgcolor = GxEPD_BLACK; bgcolor = GxEPD_BLACK;
} }
display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Draw white sreen // Clear display in obp60task.cpp in main loop
display.setTextColor(textcolor);
// Show name // Show name
display.setFont(&Ubuntu_Bold32pt7b); display.setFont(&Ubuntu_Bold32pt7b);

View File

@ -30,6 +30,7 @@ public:
String flashLED = config->getString(config->flashLED); String flashLED = config->getString(config->flashLED);
int batVoltage = config->getInt(config->batteryVoltage); int batVoltage = config->getInt(config->batteryVoltage);
String batType = config->getString(config->batteryType); String batType = config->getString(config->batteryType);
String backlightMode = config->getString(config->backlight);
// Get voltage value // Get voltage value
String name1 = "VBat"; String name1 = "VBat";
@ -39,10 +40,10 @@ public:
// Optical warning by limit violation // Optical warning by limit violation
if(String(flashLED) == "Limit Violation"){ if(String(flashLED) == "Limit Violation"){
// Limits for Pb battery // 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); setBlinkingLED(true);
} }
if(String(batType) == "Pb" && (value1 >= 10.0 && value1 <= 14.5)){ if(String(batType) == "Pb" && (value1 >= 11.0 && value1 <= 14.5)){
setBlinkingLED(false); setBlinkingLED(false);
setPortPin(OBP_FLASH_LED, false); setPortPin(OBP_FLASH_LED, false);
} }
@ -69,8 +70,7 @@ public:
pixelcolor = GxEPD_WHITE; pixelcolor = GxEPD_WHITE;
bgcolor = GxEPD_BLACK; bgcolor = GxEPD_BLACK;
} }
display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Draw white sreen //Clear display in obp60task.cpp in main loop
display.setTextColor(textcolor);
// Show name // Show name
display.setFont(&Ubuntu_Bold32pt7b); display.setFont(&Ubuntu_Bold32pt7b);
@ -113,8 +113,10 @@ public:
display.setFont(&Ubuntu_Bold8pt7b); display.setFont(&Ubuntu_Bold8pt7b);
display.setCursor(115, 290); display.setCursor(115, 290);
display.print(" [ <<<<<< >>>>>> ]"); display.print(" [ <<<<<< >>>>>> ]");
if(String(backlightMode) == "Control by Key"){
display.setCursor(343, 290); display.setCursor(343, 290);
display.print("[ILUM]"); display.print("[ILUM]");
}
// Update display // Update display
display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Partial update (fast) display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Partial update (fast)

View File

@ -289,7 +289,7 @@
"name": "underVoltage", "name": "underVoltage",
"label": "Undervoltage", "label": "Undervoltage",
"type": "boolean", "type": "boolean",
"default": "false", "default": "true",
"description": "If undervoltage detection [on|off] lower than 9V then switch off the device", "description": "If undervoltage detection [on|off] lower than 9V then switch off the device",
"category": "OBP60 Hardware", "category": "OBP60 Hardware",
"capabilities": { "capabilities": {

View File

@ -20,21 +20,57 @@
//#include GxEPD_BitmapExamples // Example picture //#include GxEPD_BitmapExamples // Example picture
#include "MFD_OBP60_400x300_sw.h" // MFD with logo #include "MFD_OBP60_400x300_sw.h" // MFD with logo
#include "Logo_OBP_400x300_sw.h" // OBP Logo #include "Logo_OBP_400x300_sw.h" // OBP Logo
#include "OBP60QRWiFi.h" // Functions lib for WiFi QR code #include "OBP60QRWiFi.h" // Functions lib for WiFi QR code
/*
tNMEA0183Msg NMEA0183Msg;
tNMEA0183 NMEA0183;
// Timer Interrupts for hardware functions // Timer Interrupts for hardware functions
Ticker Timer1; // Under voltage detection Ticker Timer1; // Under voltage detection
Ticker Timer2; // Binking flash LED Ticker Timer2; // Binking flash LED
*/
tNMEA0183Msg NMEA0183Msg;
tNMEA0183 NMEA0183;
// Global vars // Global vars
bool initComplete = false; // Initialization complete bool initComplete = false; // Initialization complete
int taskRunCounter = 0; // Task couter for loop section int taskRunCounter = 0; // Task couter for loop section
bool gps_ready = false; // GPS initialized and ready to use 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 // Hardware initialization before start all services
//################################################## //##################################################
@ -42,12 +78,12 @@ void OBP60Init(GwApi *api){
GwLog *logger = api->getLogger(); GwLog *logger = api->getLogger();
api->getLogger()->logDebug(GwLog::LOG,"obp60init running"); api->getLogger()->logDebug(GwLog::LOG,"obp60init running");
// Define timer interrupts // Start timer interrupts
bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean(); bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean();
if(uvoltage == true){ 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 // Extension port MCP23017
// Check I2C devices MCP23017 // Check I2C devices MCP23017
@ -365,22 +401,34 @@ void OBP60Task(GwApi *api){
// Task Loop // 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(); 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"); LOG_DEBUG(GwLog::LOG,"obp60task: start mainloop");
int pageNumber=0; int pageNumber=0;
int lastPage=pageNumber; int lastPage=pageNumber;
long starttime0 = millis(); // Mainloop long starttime0 = millis(); // Mainloop
long starttime1 = millis(); // Full display refresh long starttime1 = millis(); // Full display refresh
long starttime3 = millis(); // GPS data long starttime2 = millis(); // Display update
while (true){ while (true){
Timer1.update(); // Update for Timer1
Timer2.update(); // Update for Timer2
if(millis() > starttime0 + 100){ if(millis() > starttime0 + 100){
starttime0 = millis(); starttime0 = millis();
// Send NMEA0183 GPS data on several bus systems all 1000ms // 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 == true){ // If config enabled
if(gps_ready = true){ if(gps_ready = true){
tNMEA0183Msg NMEA0183Msg; tNMEA0183Msg NMEA0183Msg;
@ -389,7 +437,6 @@ void OBP60Task(GwApi *api){
} }
} }
} }
}
// If GPS fix then LED on (HDOP) // If GPS fix then LED on (HDOP)
if(String(gpsFix) == "GPS Fix" && hdop->valid == true && int(hdop->value) <= 50){ if(String(gpsFix) == "GPS Fix" && hdop->valid == true && int(hdop->value) <= 50){
@ -412,7 +459,6 @@ void OBP60Task(GwApi *api){
{ {
// Decoding all key codes // Decoding all key codes
// #6 Backlight on if key controled // #6 Backlight on if key controled
String backlight = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString();
if(String(backlight) == "Control by Key"){ if(String(backlight) == "Control by Key"){
if(keyboardMessage == 6){ if(keyboardMessage == 6){
LOG_DEBUG(GwLog::LOG,"Toggle Backlight LED"); LOG_DEBUG(GwLog::LOG,"Toggle Backlight LED");
@ -434,7 +480,6 @@ void OBP60Task(GwApi *api){
pageNumber = numPages - 1; pageNumber = numPages - 1;
} }
// #9 or #10 Refresh display befor start a new page if reshresh is enabled // #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)){ if(refreshmode == true && (keyboardMessage == 9 || keyboardMessage == 10)){
display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_WHITE); // Draw white sreen 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 display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Needs partial update before full update to refresh the frame buffer
@ -446,24 +491,29 @@ void OBP60Task(GwApi *api){
// Subtask E-Ink full refresh // Subtask E-Ink full refresh
if(millis() > starttime1 + FULL_REFRESH_TIME * 1000){ if(millis() > starttime1 + FULL_REFRESH_TIME * 1000){
starttime1 = millis();
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh"); LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh");
display.update(); // Full update display.update(); // Full update
starttime1 = millis();
} }
// Refresh display data
if(millis() > starttime2 + 1000){
starttime2 = millis();
//refresh data from api //refresh data from api
api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues); api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues);
api->getStatus(commonData.status); api->getStatus(commonData.status);
//handle the page // Show header if enabled
display.fillRect(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, bgcolor); // Clear sreen
if (pages[pageNumber].description && pages[pageNumber].description->header){ if (pages[pageNumber].description && pages[pageNumber].description->header){
//build some header and footer using commonData //build some header and footer using commonData
display.setFont(&Ubuntu_Bold32pt7b); display.setTextColor(textcolor);
display.setCursor(20, 100); display.setFont(&Ubuntu_Bold8pt7b);
display.print("Hallo"); display.setCursor(0, 15);
display.print("AP TCP GPS");
} }
//call the particular page // Call the particular page
Page *currentPage=pages[pageNumber].page; Page *currentPage=pages[pageNumber].page;
if (currentPage == NULL){ if (currentPage == NULL){
LOG_DEBUG(GwLog::ERROR,"page number %d not found",pageNumber); LOG_DEBUG(GwLog::ERROR,"page number %d not found",pageNumber);
@ -478,6 +528,7 @@ void OBP60Task(GwApi *api){
LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber); LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber);
currentPage->displayPage(commonData,pages[pageNumber].parameters); currentPage->displayPage(commonData,pages[pageNumber].parameters);
} }
}
} }
} }

View File

@ -12,6 +12,7 @@ lib_deps =
blemasle/MCP23017 @ 2.0.0 blemasle/MCP23017 @ 2.0.0
adafruit/Adafruit BusIO @ 1.5.0 adafruit/Adafruit BusIO @ 1.5.0
zinggjm/GxEPD @ 3.1.0 zinggjm/GxEPD @ 3.1.0
sstaub/Ticker @ 4.4.0
build_flags= build_flags=
-D BOARD_NODEMCU32S_OBP60 -D BOARD_NODEMCU32S_OBP60
${env.build_flags} ${env.build_flags}

View File

@ -7,13 +7,10 @@
; ;
; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[platformio] [platformio]
default_envs= default_envs = nodemcu32s_obp60
m5stack-atom extra_configs =
m5stack-atom-canunit
m5stickc-atom-canunit
nodemcu-homberger
extra_configs=
lib/*task*/platformio.ini lib/*task*/platformio.ini
[env] [env]
@ -44,7 +41,9 @@ build_flags =
[env:m5stack-atom] [env:m5stack-atom]
board = m5stack-atom board = m5stack-atom
lib_deps = ${env.lib_deps} lib_deps =
${env.lib_deps}
sstaub/Ticker@^4.4.0
build_flags = build_flags =
-D BOARD_M5ATOM -D BOARD_M5ATOM
${env.build_flags} ${env.build_flags}
@ -53,7 +52,9 @@ upload_protocol = esptool
[env:m5stack-atom-canunit] [env:m5stack-atom-canunit]
board = m5stack-atom board = m5stack-atom
lib_deps = ${env.lib_deps} lib_deps =
${env.lib_deps}
sstaub/Ticker@^4.4.0
build_flags = build_flags =
-D BOARD_M5ATOM_CANUNIT -D BOARD_M5ATOM_CANUNIT
${env.build_flags} ${env.build_flags}
@ -62,7 +63,9 @@ upload_protocol = esptool
[env:m5stickc-atom-canunit] [env:m5stickc-atom-canunit]
board = m5stick-c board = m5stick-c
lib_deps = ${env.lib_deps} lib_deps =
${env.lib_deps}
sstaub/Ticker@^4.4.0
build_flags = build_flags =
-D BOARD_M5STICK_CANUNIT -D HAS_RTC -D HAS_M5LCD -D BOARD_M5STICK_CANUNIT -D HAS_RTC -D HAS_M5LCD
${env.build_flags} ${env.build_flags}
@ -71,9 +74,40 @@ upload_protocol = esptool
[env:nodemcu-homberger] [env:nodemcu-homberger]
board = nodemcu-32s board = nodemcu-32s
lib_deps = ${env.lib_deps} lib_deps =
${env.lib_deps}
sstaub/Ticker@^4.4.0
build_flags = build_flags =
-D BOARD_HOMBERGER -D BOARD_HOMBERGER
${env.build_flags} ${env.build_flags}
upload_port = /dev/esp32 upload_port = /dev/esp32
upload_protocol = esptool 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