mirror of https://github.com/arendst/Tasmota.git
Merge pull request #8900 from tthk/development
Add support for 0.56" 7-Segment LED Backpack with floating point and raw segment addressing
This commit is contained in:
commit
5e4554e927
|
@ -563,6 +563,9 @@
|
||||||
// MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7
|
// MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7
|
||||||
// Command: DisplayText [yn]8888
|
// Command: DisplayText [yn]8888
|
||||||
// will display 8888 at sevenseg display at I2C address MTX_ADDRESS(n-1)
|
// will display 8888 at sevenseg display at I2C address MTX_ADDRESS(n-1)
|
||||||
|
// Each segment may be address Command: DisplayText [xn]m
|
||||||
|
// where n is 0..4 (4 digits and middle :) and m is decimal for bitmap of which segment to turn on.
|
||||||
|
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
|
||||||
// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
|
// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
|
||||||
// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
|
// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
|
||||||
#endif // USE_I2C
|
#endif // USE_I2C
|
||||||
|
|
|
@ -106,16 +106,18 @@ void SevensegOnOff(void)
|
||||||
|
|
||||||
void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag)
|
void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag)
|
||||||
{
|
{
|
||||||
uint16_t number = 0;
|
enum OutNumType {DECIMAL, HEXADECIMAL, FLOAT, SEGMENTS};
|
||||||
|
int16_t number = 0;
|
||||||
|
double numberf = 0;
|
||||||
boolean hasnumber= false;
|
boolean hasnumber= false;
|
||||||
uint8_t dots= 0;
|
uint8_t dots= 0;
|
||||||
boolean t=false;
|
OutNumType outnumtype= DECIMAL;
|
||||||
boolean T=false;
|
uint8 fds = 0; // number of fractional digits for fp number
|
||||||
boolean d=false;
|
boolean done= false;
|
||||||
boolean hex=false;
|
boolean s= false;
|
||||||
boolean done=false;
|
uint8_t unit= y;
|
||||||
boolean s=false;
|
char *buf;
|
||||||
uint8_t unit=y;
|
|
||||||
if ((unit>=sevensegs) || (unit<0)) {
|
if ((unit>=sevensegs) || (unit<0)) {
|
||||||
unit=0;
|
unit=0;
|
||||||
}
|
}
|
||||||
|
@ -123,29 +125,41 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
||||||
for (int i=0; (str[i]!='\0') && (!done); i++) {
|
for (int i=0; (str[i]!='\0') && (!done); i++) {
|
||||||
// [optional prefix(es) chars]digits
|
// [optional prefix(es) chars]digits
|
||||||
// Some combinations won't make sense.
|
// Some combinations won't make sense.
|
||||||
// Reference: https://learn.adafruit.com/adafruit-led-backpack/1-2-inch-7-segment-backpack-arduino-wiring-and-setup
|
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
|
||||||
|
// This code has been tested on 1.2" and 0.56" 7-Segment LED displays, but should mostly work for others.
|
||||||
//
|
//
|
||||||
// Prefixes:
|
// Prefixes:
|
||||||
// x upcoming number decimal integer displayed as hex
|
// x upcoming decimal integer number displayed as hex
|
||||||
// : turn on middle colon
|
// : turn on middle colon
|
||||||
// ^ turn on top left dot
|
// ^ turn on top left dot
|
||||||
// v turn on bottom left dot
|
// v turn on bottom left dot
|
||||||
// . turn on AM/PM/Degree dot
|
// . turn on AM/PM/Degree dot
|
||||||
// s upcoming number is seconds, print as HH:MM or MM:SS
|
// s upcoming number is seconds, print as HH:MM or MM:SS
|
||||||
// z clear this display
|
// z clear this display
|
||||||
|
// f upcoming number is floating point
|
||||||
|
// r raw segment based on bitmap of upcoming integer number (see reference document above)
|
||||||
//
|
//
|
||||||
// Some sample valid combinations:
|
// Some sample valid combinations:
|
||||||
// 787 -> 787
|
// 787 -> 787
|
||||||
// x47 -> 2F
|
// x47 -> 2F
|
||||||
// s:241 -> 04:01
|
// s:241 -> 04:01
|
||||||
// s241 -> 4 01
|
// s241 -> 4 01
|
||||||
// s1241 -> 20:41
|
// s1241 -> 20:41
|
||||||
// z ->
|
// z ->
|
||||||
// x88 -> 58
|
// x88 -> 58
|
||||||
|
// f8.5 -> 8.5
|
||||||
|
// f-9.34 -> -9.34
|
||||||
|
// f:-9.34 -> -9.:34
|
||||||
|
// r255 -> 8. (all 8 segments on)
|
||||||
|
|
||||||
switch (str[i]) {
|
switch (str[i]) {
|
||||||
case 'x': // print given dec value as hex
|
case 'x': // print given dec value as hex
|
||||||
hex = true;
|
// hex = true;
|
||||||
|
outnumtype = HEXADECIMAL;
|
||||||
|
break;
|
||||||
|
case 'f': // given number is floating point number
|
||||||
|
// fp = true;
|
||||||
|
outnumtype = FLOAT;
|
||||||
break;
|
break;
|
||||||
case ':': // print colon
|
case ':': // print colon
|
||||||
dots |= 0x02;
|
dots |= 0x02;
|
||||||
|
@ -162,6 +176,7 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
||||||
case 's': // duration in seconds
|
case 's': // duration in seconds
|
||||||
s = true;
|
s = true;
|
||||||
break;
|
break;
|
||||||
|
case '-':
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
|
@ -173,7 +188,21 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
hasnumber= true;
|
hasnumber= true;
|
||||||
number = atoi(str+i);
|
if (outnumtype == FLOAT) {
|
||||||
|
// Floating point number is given
|
||||||
|
numberf = atof(str+i);
|
||||||
|
// Find number of fractional digits
|
||||||
|
buf= str+i;
|
||||||
|
char *cp= strchr(buf, '.');
|
||||||
|
if (cp == NULL) {
|
||||||
|
fds= 0;
|
||||||
|
} else {
|
||||||
|
fds= buf+strlen(buf) - 1 - cp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Integer is given
|
||||||
|
number = atoi(str+i);
|
||||||
|
}
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
case 'z': // Clear this display
|
case 'z': // Clear this display
|
||||||
|
@ -182,30 +211,41 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
||||||
s=false;
|
s=false;
|
||||||
sevenseg[unit]->clear();
|
sevenseg[unit]->clear();
|
||||||
break;
|
break;
|
||||||
|
case 'r': // Raw segment
|
||||||
|
outnumtype= SEGMENTS;
|
||||||
|
break;
|
||||||
default: // unknown format, ignore
|
default: // unknown format, ignore
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s) {
|
|
||||||
// number is duration in seconds
|
|
||||||
hex = false;
|
|
||||||
int hour = number/60/60;
|
|
||||||
int minute = (number/60)%60;
|
|
||||||
|
|
||||||
if (hour) {
|
|
||||||
// HH:MM
|
|
||||||
number = hour*100 + minute;
|
|
||||||
} else {
|
|
||||||
// MM:SS
|
|
||||||
number = minute*100 + number%60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasnumber) {
|
if (hasnumber) {
|
||||||
if (hex) {
|
if (s) {
|
||||||
|
// number is duration in seconds
|
||||||
|
int hour = number/60/60;
|
||||||
|
int minute = (number/60)%60;
|
||||||
|
|
||||||
|
if (hour) {
|
||||||
|
// HH:MM
|
||||||
|
number = hour*100 + minute;
|
||||||
|
} else {
|
||||||
|
// MM:SS
|
||||||
|
number = minute*100 + number%60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outnumtype == HEXADECIMAL) {
|
||||||
|
// Hex
|
||||||
sevenseg[unit]->print(number, HEX);
|
sevenseg[unit]->print(number, HEX);
|
||||||
|
} else if (outnumtype == FLOAT) {
|
||||||
|
// Floating point
|
||||||
|
sevenseg[unit]->printFloat(numberf, fds, 10);
|
||||||
|
} else if (outnumtype == SEGMENTS) {
|
||||||
|
// Raw segments
|
||||||
|
sevenseg[unit]->writeDigitRaw(x, number);
|
||||||
} else {
|
} else {
|
||||||
|
// Decimal
|
||||||
sevenseg[unit]->print(number, DEC);
|
sevenseg[unit]->print(number, DEC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue