Added analog voltage display
This commit is contained in:
parent
df5ff1c91a
commit
0274b5d755
|
@ -180,6 +180,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);
|
||||||
|
|
|
@ -39,6 +39,14 @@ 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
|
||||||
|
|
||||||
|
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();
|
void hardwareInit();
|
||||||
|
|
||||||
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 +66,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);
|
||||||
|
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -11,6 +11,7 @@ bool keylock = false; // Keylock
|
||||||
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
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
|
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){
|
||||||
|
@ -24,6 +25,16 @@ public:
|
||||||
return 0; // Commit the key
|
return 0; // Commit the key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Switch display mode
|
||||||
|
if (key == 2) {
|
||||||
|
if (mode == 'A') {
|
||||||
|
mode = 'D';
|
||||||
|
} else {
|
||||||
|
mode = 'A';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Trend indicator
|
// Trend indicator
|
||||||
if(key == 5){
|
if(key == 5){
|
||||||
trend = !trend;
|
trend = !trend;
|
||||||
|
@ -38,6 +49,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,6 +181,9 @@ 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
|
||||||
|
|
||||||
|
if (mode == 'D') {
|
||||||
|
// Display mode digital
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
getdisplay().setTextColor(commonData.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt7b);
|
getdisplay().setFont(&Ubuntu_Bold32pt7b);
|
||||||
|
@ -152,25 +201,7 @@ public:
|
||||||
getdisplay().print(batType);
|
getdisplay().print(batType);
|
||||||
|
|
||||||
// Show average settings
|
// Show average settings
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
printAvg(average, 320, 84, true);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Reading bus data or using simulation data
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
||||||
|
@ -221,6 +252,106 @@ public:
|
||||||
getdisplay().fillRect(310, 240, 40, 120, commonData.bgcolor); // Clear area
|
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, 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
|
// Key Layout
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
getdisplay().setTextColor(commonData.fgcolor);
|
||||||
|
@ -228,6 +359,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);
|
||||||
|
|
Loading…
Reference in New Issue