Use I2C FRAM module if available to store page voltage state

This commit is contained in:
Thomas Hooge 2024-12-25 19:23:44 +01:00
parent 3bc0082bb8
commit daaefc7eba
6 changed files with 67 additions and 7 deletions

View File

@ -61,6 +61,10 @@ GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay(){r
// Horter I2C moduls // Horter I2C moduls
PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter
// FRAM
Adafruit_FRAM_I2C fram;
bool hasFRAM = false;
// Global vars // Global vars
bool blinkingLED = false; // Enable / disable blinking flash LED bool blinkingLED = false; // Enable / disable blinking flash LED
bool statusLED = false; // Actual status of flash LED on/off 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; LedTaskData *ledTaskData=nullptr;
void hardwareInit() void hardwareInit(GwApi *api)
{ {
Wire.begin(); Wire.begin();
// Init PCF8574 digital outputs // Init PCF8574 digital outputs
@ -78,7 +82,27 @@ void hardwareInit()
if(pcf8574_Out.begin()){ // Initialize PCF8574 if(pcf8574_Out.begin()){ // Initialize PCF8574
pcf8574_Out.write8(255); // Clear all outputs 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){ void startLedTask(GwApi *api){

View File

@ -8,6 +8,19 @@
#define FASTLED_ESP32_FLASH_LOCK 1 #define FASTLED_ESP32_FLASH_LOCK 1
#include "LedSpiTask.h" #include "LedSpiTask.h"
#include <GxEPD2_BW.h> // E-paper lib V2 #include <GxEPD2_BW.h> // E-paper lib V2
#include <Adafruit_FRAM_I2C.h> // 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) // Fonts declarations for display (#inclues see OBP60Extensions.cpp)
extern const GFXfont Ubuntu_Bold8pt7b; extern const GFXfont Ubuntu_Bold8pt7b;
@ -47,7 +60,7 @@ Point rotatePoint(const Point& origin, const Point& p, double angle);
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle); std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
void fillPoly4(const std::vector<Point>& p4, uint16_t color); void fillPoly4(const std::vector<Point>& p4, uint16_t color);
void hardwareInit(); void hardwareInit(GwApi *api);
void setPortPin(uint pin, bool value); // Set port pin for extension port 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); 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 #endif

View File

@ -30,6 +30,8 @@
#define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator #define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator
// Horter modules // Horter modules
#define PCF8574_I2C_ADDR1 0x20 // First digital out module #define PCF8574_I2C_ADDR1 0x20 // First digital out module
// FRAM (e.g. MB85RC256V)
#define FRAM_I2C_ADDR 0x50
// SPI (E-Ink display, Extern Bus) // SPI (E-Ink display, Extern Bus)
#define OBP_SPI_CS 39 #define OBP_SPI_CS 39
#define OBP_SPI_DC 40 #define OBP_SPI_DC 40

View File

@ -8,20 +8,26 @@ class PageVoltage : public Page
{ {
bool init = false; // Marker for init done bool init = false; // Marker for init done
bool keylock = false; // Keylock 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 bool trend = true; // Trend indicator [0|1], 0=off, 1=on
double raw = 0; double raw = 0;
char mode = 'D'; // display mode (A)nalog | (D)igital char mode = 'D'; // display mode (A)nalog | (D)igital
public: public:
PageVoltage(CommonData &common){ 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){ virtual int handleKey(int key){
// Change average // Change average
if(key == 1){ if(key == 1){
average ++; average ++;
average = average % 4; // Modulo 4 average = average % 4; // Modulo 4
if (hasFRAM) fram.write(FRAM_VOLTAGE_AVG, average);
return 0; // Commit the key return 0; // Commit the key
} }
@ -32,12 +38,14 @@ public:
} else { } else {
mode = 'A'; mode = 'A';
} }
if (hasFRAM) fram.write(FRAM_VOLTAGE_MODE, mode);
return 0; return 0;
} }
// Trend indicator // Trend indicator
if(key == 5){ if(key == 5){
trend = !trend; trend = !trend;
if (hasFRAM) fram.write(FRAM_VOLTAGE_TREND, trend);
return 0; // Commit the key return 0; // Commit the key
} }
@ -335,7 +343,7 @@ public:
// Symbol // Symbol
printVoltageSymbol(40, 60, commonData.fgcolor); printVoltageSymbol(40, 60, commonData.fgcolor);
// Additional informatio at right side // Additional information at right side
getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setFont(&Ubuntu_Bold8pt7b);
getdisplay().setCursor(300, 60); getdisplay().setCursor(300, 60);
getdisplay().print("Source:"); getdisplay().print("Source:");
@ -351,6 +359,11 @@ public:
getdisplay().print("Avg:"); getdisplay().print("Avg:");
printAvg(average, 300, 180, false); printAvg(average, 300, 180, false);
// FRAM indicator
if (hasFRAM) {
getdisplay().drawXBitmap(300, 240, fram_bits, fram_width, fram_height, commonData.fgcolor);
}
} }
// Key Layout // Key Layout

View File

@ -43,7 +43,7 @@ void OBP60Init(GwApi *api){
// Init hardware // Init hardware
hardwareInit(); hardwareInit(api);
// Init power rail 5.0V // Init power rail 5.0V
String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString(); String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();

View File

@ -35,6 +35,7 @@ lib_deps =
paulstoffregen/OneWire@2.3.8 paulstoffregen/OneWire@2.3.8
milesburton/DallasTemperature@3.11.0 milesburton/DallasTemperature@3.11.0
signetica/SunRise@2.0.2 signetica/SunRise@2.0.2
adafruit/Adafruit FRAM I2C@^2.0.3
build_flags= build_flags=
#https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL #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) # -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device)