Skip to content

Commit

Permalink
Merge pull request #127 from thooge/voltage
Browse files Browse the repository at this point in the history
Voltage analog display
  • Loading branch information
norbert-walter authored Jan 2, 2025
2 parents df5ff1c + 319f3f3 commit 2808c56
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 121 deletions.
70 changes: 68 additions & 2 deletions lib/obp60task/OBP60Extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & 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
Expand All @@ -70,15 +74,35 @@ 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
Wire.setClock(I2C_SPEED); // Set I2C clock on 10 kHz
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){
Expand Down Expand Up @@ -180,6 +204,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<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)
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);
Expand Down
33 changes: 32 additions & 1 deletion lib/obp60task/OBP60Extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
#define FASTLED_ESP32_FLASH_LOCK 1
#include "LedSpiTask.h"
#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)
extern const GFXfont Ubuntu_Bold8pt7b;
Expand Down Expand Up @@ -39,7 +52,15 @@ GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> & getdisplay();
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
#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

Expand All @@ -58,6 +79,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);

Expand All @@ -72,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[] = {
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
2 changes: 2 additions & 0 deletions lib/obp60task/OBP60Hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 6 additions & 43 deletions lib/obp60task/PageFluid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_height 16
static unsigned char fuel_bits[] = {
Expand Down Expand Up @@ -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) {
Expand All @@ -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<Point> pts = {
Expand Down
Loading

0 comments on commit 2808c56

Please sign in to comment.