commit
2808c56a37
|
@ -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){
|
||||||
|
@ -180,6 +204,48 @@ String xdrDelete(String input){
|
||||||
return 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<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
||||||
|
std::vector<Point> rotatedPoints;
|
||||||
|
for (const auto& p : pts) {
|
||||||
|
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
||||||
|
}
|
||||||
|
return rotatedPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillPoly4(const std::vector<Point>& 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)
|
// 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){
|
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);
|
getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color);
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -39,7 +52,15 @@ GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> & getdisplay();
|
||||||
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
|
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void hardwareInit();
|
struct Point {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
Point rotatePoint(const Point& origin, const Point& p, 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 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
|
||||||
|
|
||||||
|
@ -58,6 +79,9 @@ void setBuzzerPower(uint power); // Set buzzer power
|
||||||
|
|
||||||
String xdrDelete(String input); // Delete xdr prefix from string
|
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 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);
|
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
||||||
|
|
||||||
|
@ -72,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[] = {
|
||||||
|
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 };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
|
||||||
std::vector<Point> rotatedPoints;
|
|
||||||
for (const auto& p : pts) {
|
|
||||||
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
|
||||||
}
|
|
||||||
return rotatedPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillPoly4(const std::vector<Point>& 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_width 16
|
||||||
#define fuel_height 16
|
#define fuel_height 16
|
||||||
static unsigned char fuel_bits[] = {
|
static unsigned char fuel_bits[] = {
|
||||||
|
@ -171,7 +134,7 @@ class PageFluid : public Page{
|
||||||
} else {
|
} else {
|
||||||
strcpy(buffer, "---");
|
strcpy(buffer, "---");
|
||||||
}
|
}
|
||||||
drawTextCentered(c.x, c.y + r - 20, String(buffer));
|
drawTextCenter(c.x, c.y + r - 20, String(buffer));
|
||||||
|
|
||||||
// draw symbol (as bitmap)
|
// draw symbol (as bitmap)
|
||||||
switch (fluidtype) {
|
switch (fluidtype) {
|
||||||
|
@ -197,18 +160,18 @@ class PageFluid : public Page{
|
||||||
// scale texts
|
// scale texts
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
||||||
p = {c.x, c.y - r + 30};
|
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);
|
pr = rotatePoint(c, p, -60);
|
||||||
drawTextCentered(pr.x, pr.y, "1/4");
|
drawTextCenter(pr.x, pr.y, "1/4");
|
||||||
pr = rotatePoint(c, p, 60);
|
pr = rotatePoint(c, p, 60);
|
||||||
drawTextCentered(pr.x, pr.y, "3/4");
|
drawTextCenter(pr.x, pr.y, "3/4");
|
||||||
|
|
||||||
// empty and full
|
// empty and full
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt7b);
|
getdisplay().setFont(&Ubuntu_Bold12pt7b);
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 30}, -130);
|
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);
|
p = rotatePoint(c, {c.x, c.y - r + 30}, 130);
|
||||||
drawTextCentered(p.x, p.y, "F");
|
drawTextCenter(p.x, p.y, "F");
|
||||||
|
|
||||||
// lines
|
// lines
|
||||||
std::vector<Point> pts = {
|
std::vector<Point> pts = {
|
||||||
|
|
|
@ -8,25 +8,44 @@ 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
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Switch display mode
|
||||||
|
if (key == 2) {
|
||||||
|
if (mode == 'A') {
|
||||||
|
mode = 'D';
|
||||||
|
} else {
|
||||||
|
mode = 'A';
|
||||||
|
}
|
||||||
|
if (hasFRAM) fram.write(FRAM_VOLTAGE_MODE, mode);
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +57,41 @@ public:
|
||||||
return key;
|
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)
|
virtual void displayPage(CommonData &commonData, PageData &pageData)
|
||||||
{
|
{
|
||||||
GwConfigHandler *config = commonData.config;
|
GwConfigHandler *config = commonData.config;
|
||||||
|
@ -135,92 +189,182 @@ public:
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
||||||
|
|
||||||
// Show name
|
if (mode == 'D') {
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
// Display mode digital
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt7b);
|
|
||||||
getdisplay().setCursor(20, 100);
|
|
||||||
getdisplay().print(name1); // Value name
|
|
||||||
|
|
||||||
// Show unit
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt7b);
|
getdisplay().setTextColor(commonData.fgcolor);
|
||||||
getdisplay().setCursor(270, 100);
|
getdisplay().setFont(&Ubuntu_Bold32pt7b);
|
||||||
getdisplay().print("V");
|
getdisplay().setCursor(20, 100);
|
||||||
|
getdisplay().print(name1); // Value name
|
||||||
|
|
||||||
// Show battery type
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
getdisplay().setFont(&Ubuntu_Bold20pt7b);
|
||||||
getdisplay().setCursor(295, 100);
|
getdisplay().setCursor(270, 100);
|
||||||
getdisplay().print(batType);
|
getdisplay().print("V");
|
||||||
|
|
||||||
// Show average settings
|
// Show battery type
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
||||||
getdisplay().setCursor(320, 84);
|
getdisplay().setCursor(295, 100);
|
||||||
switch (average) {
|
getdisplay().print(batType);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Show average settings
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
printAvg(average, 320, 84, true);
|
||||||
getdisplay().setCursor(20, 240);
|
|
||||||
if(simulation == true){
|
// Reading bus data or using simulation data
|
||||||
if(batVoltage == "12V"){
|
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
||||||
value1 = 12.0;
|
getdisplay().setCursor(20, 240);
|
||||||
}
|
if(simulation == true){
|
||||||
if(batVoltage == "24V"){
|
if(batVoltage == "12V"){
|
||||||
value1 = 24.0;
|
value1 = 12.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);
|
|
||||||
}
|
}
|
||||||
if(value1 >= 10 && value1 < 100){
|
if(batVoltage == "24V"){
|
||||||
getdisplay().print(value1,1);
|
value1 = 24.0;
|
||||||
}
|
|
||||||
if(value1 >= 100){
|
|
||||||
getdisplay().print(value1,0);
|
|
||||||
}
|
}
|
||||||
|
value1 += float(random(0, 5)) / 10; // Simulation data
|
||||||
|
getdisplay().print(value1,1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // Missing bus data
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Trend indicator
|
// Trend indicator
|
||||||
// Show trend indicator
|
// Show trend indicator
|
||||||
if(trend == true){
|
if(trend == true){
|
||||||
getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area
|
getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area
|
||||||
getdisplay().fillRect(315, 183, 35, 4, commonData.fgcolor); // Draw separator
|
getdisplay().fillRect(315, 183, 35, 4, commonData.fgcolor); // Draw separator
|
||||||
if(int(raw * 10) > int(valueTrend * 10)){
|
if(int(raw * 10) > int(valueTrend * 10)){
|
||||||
displayTrendHigh(320, 174, 11, commonData.fgcolor); // Show high indicator
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(int(raw * 10) < int(valueTrend * 10)){
|
// No trend indicator
|
||||||
displayTrendLow(320, 195, 11, commonData.fgcolor); // Show low indicator
|
else{
|
||||||
|
getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// 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<Point> 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<int, String> 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, 7, commonData.fgcolor);
|
||||||
|
getdisplay().fillCircle(c.x, c.y, 4, commonData.bgcolor);
|
||||||
|
|
||||||
|
// Symbol
|
||||||
|
printVoltageSymbol(40, 60, commonData.fgcolor);
|
||||||
|
|
||||||
|
// Additional information 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);
|
||||||
|
|
||||||
|
// FRAM indicator
|
||||||
|
if (hasFRAM) {
|
||||||
|
getdisplay().drawXBitmap(300, 240, fram_bits, fram_width, fram_height, commonData.fgcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Key Layout
|
// Key Layout
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
getdisplay().setTextColor(commonData.fgcolor);
|
||||||
|
@ -228,6 +372,8 @@ public:
|
||||||
if(keylock == false){
|
if(keylock == false){
|
||||||
getdisplay().setCursor(10, 290);
|
getdisplay().setCursor(10, 290);
|
||||||
getdisplay().print("[AVG]");
|
getdisplay().print("[AVG]");
|
||||||
|
getdisplay().setCursor(62, 290);
|
||||||
|
getdisplay().print("[MODE]");
|
||||||
getdisplay().setCursor(130, 290);
|
getdisplay().setCursor(130, 290);
|
||||||
getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]");
|
getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]");
|
||||||
getdisplay().setCursor(293, 290);
|
getdisplay().setCursor(293, 290);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue