From 0274b5d75555e307e7c8caf76a22fbde0bdf5ce1 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Tue, 24 Dec 2024 20:24:48 +0100 Subject: [PATCH 1/4] Added analog voltage display --- lib/obp60task/OBP60Extensions.cpp | 42 +++++ lib/obp60task/OBP60Extensions.h | 11 ++ lib/obp60task/PageFluid.cpp | 49 +---- lib/obp60task/PageVoltage.cpp | 285 ++++++++++++++++++++++-------- 4 files changed, 268 insertions(+), 119 deletions(-) diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 5fa9521..5ef81d8 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -180,6 +180,48 @@ String xdrDelete(String input){ return input; } +Point rotatePoint(const Point& origin, const Point& p, double angle) { + // rotate poind around origin by degrees + Point rotated; + double phi = angle * M_PI / 180.0; + double dx = p.x - origin.x; + double dy = p.y - origin.y; + rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy; + rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy; + return rotated; +} + +std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle) { + std::vector rotatedPoints; + for (const auto& p : pts) { + rotatedPoints.push_back(rotatePoint(origin, p, angle)); + } + return rotatedPoints; +} + +void fillPoly4(const std::vector& p4, uint16_t color) { + getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color); + getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color); +} + +// Draw centered text +void drawTextCenter(int16_t cx, int16_t cy, String text) { + int16_t x1, y1; + uint16_t w, h; + getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); + getdisplay().setCursor(cx - w / 2, cy + h / 2); + getdisplay().print(text); +} + +// Draw right aligned text +void drawTextRalign(int16_t x, int16_t y, String text) { + int16_t x1, y1; + uint16_t w, h; + getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); + getdisplay().setCursor(x - w, y); + getdisplay().print(text); +} + // Show a triangle for trend direction high (x, y is the left edge) void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){ getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color); diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index 0c7c117..c07bd54 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -39,6 +39,14 @@ GxEPD2_BW & getdisplay(); GxEPD2_BW & getdisplay(); #endif +struct Point { + double x; + double y; +}; +Point rotatePoint(const Point& origin, const Point& p, double angle); +std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle); +void fillPoly4(const std::vector& p4, uint16_t color); + void hardwareInit(); void setPortPin(uint pin, bool value); // Set port pin for extension port @@ -58,6 +66,9 @@ void setBuzzerPower(uint power); // Set buzzer power String xdrDelete(String input); // Delete xdr prefix from string +void drawTextCenter(int16_t cx, int16_t cy, String text); +void drawTextRalign(int16_t x, int16_t y, String text); + void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color); void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color); diff --git a/lib/obp60task/PageFluid.cpp b/lib/obp60task/PageFluid.cpp index 37dc2dc..ae7349e 100644 --- a/lib/obp60task/PageFluid.cpp +++ b/lib/obp60task/PageFluid.cpp @@ -22,43 +22,6 @@ TODO */ -struct Point { - double x; - double y; -}; - -Point rotatePoint(const Point& origin, const Point& p, double angle) { - // rotate poind around origin by degrees - Point rotated; - double phi = angle * M_PI / 180.0; - double dx = p.x - origin.x; - double dy = p.y - origin.y; - rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy; - rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy; - return rotated; -} - -std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle) { - std::vector rotatedPoints; - for (const auto& p : pts) { - rotatedPoints.push_back(rotatePoint(origin, p, angle)); - } - return rotatedPoints; -} - -void fillPoly4(const std::vector& p4, uint16_t color) { - getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color); - getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color); -} - -void drawTextCentered(int16_t tx, int16_t ty, String text) { - int16_t x, y; - uint16_t w, h; - getdisplay().getTextBounds(text, 0, 0, &x, &y, &w, &h); - getdisplay().setCursor(tx - w / 2, ty + h / 2); - getdisplay().print(text); -} - #define fuel_width 16 #define fuel_height 16 static unsigned char fuel_bits[] = { @@ -171,7 +134,7 @@ class PageFluid : public Page{ } else { strcpy(buffer, "---"); } - drawTextCentered(c.x, c.y + r - 20, String(buffer)); + drawTextCenter(c.x, c.y + r - 20, String(buffer)); // draw symbol (as bitmap) switch (fluidtype) { @@ -197,18 +160,18 @@ class PageFluid : public Page{ // scale texts getdisplay().setFont(&Ubuntu_Bold8pt7b); p = {c.x, c.y - r + 30}; - drawTextCentered(p.x, p.y, "1/2"); + drawTextCenter(p.x, p.y, "1/2"); pr = rotatePoint(c, p, -60); - drawTextCentered(pr.x, pr.y, "1/4"); + drawTextCenter(pr.x, pr.y, "1/4"); pr = rotatePoint(c, p, 60); - drawTextCentered(pr.x, pr.y, "3/4"); + drawTextCenter(pr.x, pr.y, "3/4"); // empty and full getdisplay().setFont(&Ubuntu_Bold12pt7b); p = rotatePoint(c, {c.x, c.y - r + 30}, -130); - drawTextCentered(p.x, p.y, "E"); + drawTextCenter(p.x, p.y, "E"); p = rotatePoint(c, {c.x, c.y - r + 30}, 130); - drawTextCentered(p.x, p.y, "F"); + drawTextCenter(p.x, p.y, "F"); // lines std::vector pts = { diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index e187d60..a1e95fa 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -11,6 +11,7 @@ bool keylock = false; // Keylock int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s bool trend = true; // Trend indicator [0|1], 0=off, 1=on double raw = 0; +char mode = 'D'; // display mode (A)nalog | (D)igital public: PageVoltage(CommonData &common){ @@ -24,6 +25,16 @@ public: return 0; // Commit the key } + // Switch display mode + if (key == 2) { + if (mode == 'A') { + mode = 'D'; + } else { + mode = 'A'; + } + return 0; + } + // Trend indicator if(key == 5){ trend = !trend; @@ -38,6 +49,41 @@ public: return key; } + void printAvg(int avg, uint16_t x, uint16_t y, bool prefix) { + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(x, y); + if (prefix) { + getdisplay().print("Avg: "); + } + switch (average) { + case 0: + getdisplay().print("1s"); + break; + case 1: + getdisplay().print("10s"); + break; + case 2: + getdisplay().print("60s"); + break; + case 3: + getdisplay().print("300s"); + break; + default: + getdisplay().print("1s"); + break; + } + } + + void printVoltageSymbol(uint16_t x, uint16_t y, uint16_t color) { + getdisplay().setFont(&Ubuntu_Bold16pt7b); + getdisplay().setCursor(x, y); + getdisplay().print("V"); + getdisplay().fillRect(x, y + 6, 22, 3, color); + getdisplay().fillRect(x, y + 11, 6, 3, color); + getdisplay().fillRect(x + 8, y + 11, 6, 3, color); + getdisplay().fillRect(x + 16, y + 11, 6, 3, color); + } + virtual void displayPage(CommonData &commonData, PageData &pageData) { GwConfigHandler *config = commonData.config; @@ -135,92 +181,177 @@ public: // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - // Show name - getdisplay().setTextColor(commonData.fgcolor); - getdisplay().setFont(&Ubuntu_Bold32pt7b); - getdisplay().setCursor(20, 100); - getdisplay().print(name1); // Value name + if (mode == 'D') { + // Display mode digital - // Show unit - getdisplay().setFont(&Ubuntu_Bold20pt7b); - getdisplay().setCursor(270, 100); - getdisplay().print("V"); + // Show name + getdisplay().setTextColor(commonData.fgcolor); + getdisplay().setFont(&Ubuntu_Bold32pt7b); + getdisplay().setCursor(20, 100); + getdisplay().print(name1); // Value name - // Show battery type - getdisplay().setFont(&Ubuntu_Bold8pt7b); - getdisplay().setCursor(295, 100); - getdisplay().print(batType); + // Show unit + getdisplay().setFont(&Ubuntu_Bold20pt7b); + getdisplay().setCursor(270, 100); + getdisplay().print("V"); - // Show average settings - getdisplay().setFont(&Ubuntu_Bold8pt7b); - getdisplay().setCursor(320, 84); - switch (average) { - case 0: - getdisplay().print("Avg: 1s"); - break; - case 1: - getdisplay().print("Avg: 10s"); - break; - case 2: - getdisplay().print("Avg: 60s"); - break; - case 3: - getdisplay().print("Avg: 300s"); - break; - default: - getdisplay().print("Avg: 1s"); - break; - } + // Show battery type + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(295, 100); + getdisplay().print(batType); - // Reading bus data or using simulation data - getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b); - getdisplay().setCursor(20, 240); - if(simulation == true){ - if(batVoltage == "12V"){ - value1 = 12.0; - } - if(batVoltage == "24V"){ - value1 = 24.0; - } - value1 += float(random(0, 5)) / 10; // Simulation data - getdisplay().print(value1,1); - } - else{ - // Check for valid real data, display also if hold values activated - if(valid1 == true || holdvalues == true){ - // Resolution switching - if(value1 < 10){ - getdisplay().print(value1,2); + // Show average settings + printAvg(average, 320, 84, true); + + // Reading bus data or using simulation data + getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b); + getdisplay().setCursor(20, 240); + if(simulation == true){ + if(batVoltage == "12V"){ + value1 = 12.0; } - if(value1 >= 10 && value1 < 100){ - getdisplay().print(value1,1); - } - if(value1 >= 100){ - getdisplay().print(value1,0); + if(batVoltage == "24V"){ + value1 = 24.0; } + value1 += float(random(0, 5)) / 10; // Simulation data + getdisplay().print(value1,1); } else{ - getdisplay().print("---"); // Missing bus data - } - } - - // Trend indicator - // Show trend indicator - if(trend == true){ - getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area - getdisplay().fillRect(315, 183, 35, 4, commonData.fgcolor); // Draw separator - if(int(raw * 10) > int(valueTrend * 10)){ - displayTrendHigh(320, 174, 11, commonData.fgcolor); // Show high indicator + // Check for valid real data, display also if hold values activated + if(valid1 == true || holdvalues == true){ + // Resolution switching + if(value1 < 10){ + getdisplay().print(value1,2); + } + if(value1 >= 10 && value1 < 100){ + getdisplay().print(value1,1); + } + if(value1 >= 100){ + getdisplay().print(value1,0); + } + } + else{ + getdisplay().print("---"); // Missing bus data + } } - if(int(raw * 10) < int(valueTrend * 10)){ - displayTrendLow(320, 195, 11, commonData.fgcolor); // Show low indicator - } - } - // No trend indicator - else{ - getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area - } + // Trend indicator + // Show trend indicator + if(trend == true){ + getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area + getdisplay().fillRect(315, 183, 35, 4, commonData.fgcolor); // Draw separator + if(int(raw * 10) > int(valueTrend * 10)){ + displayTrendHigh(320, 174, 11, commonData.fgcolor); // Show high indicator + } + if(int(raw * 10) < int(valueTrend * 10)){ + displayTrendLow(320, 195, 11, commonData.fgcolor); // Show low indicator + } + } + // No trend indicator + else{ + getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area + } + + } + else { + // Display mode analog + + // center + Point c = {260, 270}; + uint8_t r = 240; + + Point p1, p2; + std::vector pts; + + // Instrument + getdisplay().drawCircleHelper(c.x, c.y, r + 2, 0x01, commonData.fgcolor); + getdisplay().drawCircleHelper(c.x, c.y, r + 1, 0x01, commonData.fgcolor); + getdisplay().drawCircleHelper(c.x, c.y, r , 0x01, commonData.fgcolor); + + // Scale + // angle to voltage scale mapping + std::map mapping = { + {15, "10"}, {30, "11"}, {45, "12"}, {60, "13"}, {75, "14"} + }; + pts = { + {c.x - r, c.y - 1}, + {c.x - r + 12, c.y - 1}, + {c.x - r + 12, c.y + 1}, + {c.x - r, c.y + 1} + }; + getdisplay().setFont(&Ubuntu_Bold10pt7b); + for (int angle = 3; angle < 90; angle += 3) { + if (angle % 15 == 0) { + fillPoly4(rotatePoints(c, pts, angle), commonData.fgcolor); + p1 = rotatePoint(c, {c.x - r + 30, c.y}, angle); + drawTextCenter(p1.x, p1.y, mapping[angle]); + } + else { + p1 = rotatePoint(c, {c.x - r, c.y}, angle); + p2 = rotatePoint(c, {c.x - r + 6, c.y}, angle); + getdisplay().drawLine(p1.x, p1.y, p2.x, p2.y, commonData.fgcolor); + } + } + + // Pointer rotation and limits + double angle; + if (not valid1) { + angle = -0.5; + } + else { + if (value1 > 15.0) { + angle = 91; + } + else if (value1 <= 9) { + angle = -0.5; + } + else { + angle = (value1 - 9) * 15; + } + } + + // Pointer + // thick part + pts = { + {c.x - 2, c.y + 3}, + {c.x - r + 38, c.y + 2}, + {c.x - r + 38, c.y - 2}, + {c.x - 2, c.y - 3} + }; + fillPoly4(rotatePoints(c, pts, angle), commonData.fgcolor); + // thin part + pts = { + {c.x - r + 40, c.y + 1}, + {c.x - r + 5, c.y + 1}, + {c.x - r + 5, c.y -1}, + {c.x - r + 40, c.y - 1}, + }; + fillPoly4(rotatePoints(c, pts, angle), commonData.fgcolor); + + // base + getdisplay().fillCircle(c.x, c.y, 8, commonData.fgcolor); + getdisplay().fillCircle(c.x, c.y, 6, commonData.bgcolor); + + // Symbol + printVoltageSymbol(40, 60, commonData.fgcolor); + + // Additional informatio at right side + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(300, 60); + getdisplay().print("Source:"); + getdisplay().setCursor(300, 80); + getdisplay().print(name1); + + getdisplay().setCursor(300, 110); + getdisplay().print("Type:"); + getdisplay().setCursor(300, 130); + getdisplay().print(batType); + + getdisplay().setCursor(300, 160); + getdisplay().print("Avg:"); + printAvg(average, 300, 180, false); + + } // Key Layout getdisplay().setTextColor(commonData.fgcolor); @@ -228,6 +359,8 @@ public: if(keylock == false){ getdisplay().setCursor(10, 290); getdisplay().print("[AVG]"); + getdisplay().setCursor(62, 290); + getdisplay().print("[MODE]"); getdisplay().setCursor(130, 290); getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); getdisplay().setCursor(293, 290); From 3bc0082bb8b5689035ff1f8b82b947eb3d12c91a Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Tue, 24 Dec 2024 20:31:45 +0100 Subject: [PATCH 2/4] Fix pointer base display --- lib/obp60task/PageVoltage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index a1e95fa..8a30006 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -329,8 +329,8 @@ public: fillPoly4(rotatePoints(c, pts, angle), commonData.fgcolor); // base - getdisplay().fillCircle(c.x, c.y, 8, commonData.fgcolor); - getdisplay().fillCircle(c.x, c.y, 6, commonData.bgcolor); + getdisplay().fillCircle(c.x, c.y, 7, commonData.fgcolor); + getdisplay().fillCircle(c.x, c.y, 4, commonData.bgcolor); // Symbol printVoltageSymbol(40, 60, commonData.fgcolor); From daaefc7eba2825103622bc542f5b4610da8cf52f Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Wed, 25 Dec 2024 19:23:44 +0100 Subject: [PATCH 3/4] Use I2C FRAM module if available to store page voltage state --- lib/obp60task/OBP60Extensions.cpp | 28 ++++++++++++++++++++++++++-- lib/obp60task/OBP60Extensions.h | 22 +++++++++++++++++++++- lib/obp60task/OBP60Hardware.h | 2 ++ lib/obp60task/PageVoltage.cpp | 19 ++++++++++++++++--- lib/obp60task/obp60task.cpp | 2 +- lib/obp60task/platformio.ini | 1 + 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 5ef81d8..c288bd8 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -61,6 +61,10 @@ GxEPD2_BW & getdisplay(){r // Horter I2C moduls PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter +// FRAM +Adafruit_FRAM_I2C fram; +bool hasFRAM = false; + // Global vars bool blinkingLED = false; // Enable / disable blinking flash LED bool statusLED = false; // Actual status of flash LED on/off @@ -70,7 +74,7 @@ int uvDuration = 0; // Under voltage duration in n x 100ms LedTaskData *ledTaskData=nullptr; -void hardwareInit() +void hardwareInit(GwApi *api) { Wire.begin(); // Init PCF8574 digital outputs @@ -78,7 +82,27 @@ void hardwareInit() if(pcf8574_Out.begin()){ // Initialize PCF8574 pcf8574_Out.write8(255); // Clear all outputs } - + fram = Adafruit_FRAM_I2C(); + if (esp_reset_reason() == ESP_RST_POWERON) { + // help initialize FRAM + api->getLogger()->logDebug(GwLog::LOG,"Delaying I2C init for 250ms due to cold boot"); + delay(250); + } + // FRAM (e.g. MB85RC256V) + if (fram.begin(FRAM_I2C_ADDR)) { + hasFRAM = true; + uint16_t manufacturerID; + uint16_t productID; + fram.getDeviceID(&manufacturerID, &productID); + // Boot counter + uint8_t framcounter = fram.read(0x0000); + fram.write(0x0000, framcounter+1); + api->getLogger()->logDebug(GwLog::LOG,"FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter); + } + else { + hasFRAM = false; + api->getLogger()->logDebug(GwLog::LOG,"NO FRAM detected"); + } } void startLedTask(GwApi *api){ diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index c07bd54..a0be7cd 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -8,6 +8,19 @@ #define FASTLED_ESP32_FLASH_LOCK 1 #include "LedSpiTask.h" #include // E-paper lib V2 +#include // I2C FRAM + +// FRAM address reservations 32kB: 0x0000 - 0x7FFF +// 0x0000 - 0x03ff: single variables +#define FRAM_VOLTAGE_AVG 0x000A +#define FRAM_VOLTAGE_TREND 0x000B +#define FRAM_VOLTAGE_MODE 0x000C +// Barograph history data +#define FRAM_BAROGRAPH_START 0x0400 +#define FRAM_BAROGRAPH_END 0x13FF + +extern Adafruit_FRAM_I2C fram; +extern bool hasFRAM; // Fonts declarations for display (#inclues see OBP60Extensions.cpp) extern const GFXfont Ubuntu_Bold8pt7b; @@ -47,7 +60,7 @@ Point rotatePoint(const Point& origin, const Point& p, double angle); std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle); void fillPoly4(const std::vector& p4, uint16_t color); -void hardwareInit(); +void hardwareInit(GwApi *api); void setPortPin(uint pin, bool value); // Set port pin for extension port @@ -83,4 +96,11 @@ void startLedTask(GwApi *api); void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request); +#define fram_width 16 +#define fram_height 16 +static unsigned char fram_bits[] PROGMEM = { + 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, + 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f }; + #endif diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index f450790..4782b4c 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -30,6 +30,8 @@ #define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator // Horter modules #define PCF8574_I2C_ADDR1 0x20 // First digital out module + // FRAM (e.g. MB85RC256V) + #define FRAM_I2C_ADDR 0x50 // SPI (E-Ink display, Extern Bus) #define OBP_SPI_CS 39 #define OBP_SPI_DC 40 diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index 8a30006..cdee817 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -8,20 +8,26 @@ class PageVoltage : public Page { bool init = false; // Marker for init done bool keylock = false; // Keylock -int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s +uint8_t average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s bool trend = true; // Trend indicator [0|1], 0=off, 1=on double raw = 0; char mode = 'D'; // display mode (A)nalog | (D)igital public: PageVoltage(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageVoltage"); + common.logger->logDebug(GwLog::LOG,"Instantiate PageVoltage"); + if (hasFRAM) { + average = fram.read(FRAM_VOLTAGE_AVG); + trend = fram.read(FRAM_VOLTAGE_TREND); + mode = fram.read(FRAM_VOLTAGE_MODE); + } } virtual int handleKey(int key){ // Change average if(key == 1){ average ++; average = average % 4; // Modulo 4 + if (hasFRAM) fram.write(FRAM_VOLTAGE_AVG, average); return 0; // Commit the key } @@ -32,12 +38,14 @@ public: } else { mode = 'A'; } + if (hasFRAM) fram.write(FRAM_VOLTAGE_MODE, mode); return 0; } // Trend indicator if(key == 5){ trend = !trend; + if (hasFRAM) fram.write(FRAM_VOLTAGE_TREND, trend); return 0; // Commit the key } @@ -335,7 +343,7 @@ public: // Symbol printVoltageSymbol(40, 60, commonData.fgcolor); - // Additional informatio at right side + // Additional information at right side getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(300, 60); getdisplay().print("Source:"); @@ -351,6 +359,11 @@ public: getdisplay().print("Avg:"); printAvg(average, 300, 180, false); + // FRAM indicator + if (hasFRAM) { + getdisplay().drawXBitmap(300, 240, fram_bits, fram_width, fram_height, commonData.fgcolor); + } + } // Key Layout diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 7f65bbc..40a00c7 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -43,7 +43,7 @@ void OBP60Init(GwApi *api){ // Init hardware - hardwareInit(); + hardwareInit(api); // Init power rail 5.0V String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString(); diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index 14bd788..63f1085 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -35,6 +35,7 @@ lib_deps = paulstoffregen/OneWire@2.3.8 milesburton/DallasTemperature@3.11.0 signetica/SunRise@2.0.2 + adafruit/Adafruit FRAM I2C@^2.0.3 build_flags= #https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL # -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device) From 319f3f3e68a344fc8d7e4bd56e6490a6b4e97545 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Mon, 30 Dec 2024 19:46:54 +0100 Subject: [PATCH 4/4] Improve FRAM icon --- lib/obp60task/OBP60Extensions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index a0be7cd..79695ef 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -98,8 +98,8 @@ void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUM #define fram_width 16 #define fram_height 16 -static unsigned char fram_bits[] PROGMEM = { - 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, +static unsigned char fram_bits[] = { + 0xf8, 0x1f, 0xff, 0xff, 0x9f, 0xff, 0x98, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f };