mirror of https://github.com/arendst/Tasmota.git
Merge pull request #8886 from tthk/development
Add Multiple I2C Seven Segment LED Displays Support
This commit is contained in:
commit
8df6184007
|
@ -559,7 +559,11 @@
|
|||
#define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module
|
||||
#define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module
|
||||
#define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code)
|
||||
#define SEVENSEG_ADDRESS1 0x70 // [DisplayAddress1] I2C address of first sevenseg matrix module
|
||||
// Multiple sevenseg displays are logically arranged vertically with MTX_ADDRESS1 at y=0,
|
||||
// MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7
|
||||
// Command: DisplayText [yn]8888
|
||||
// will display 8888 at sevenseg display at I2C address MTX_ADDRESS(n-1)
|
||||
// #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)
|
||||
#endif // USE_I2C
|
||||
|
||||
|
|
|
@ -28,20 +28,24 @@
|
|||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_LEDBackpack.h> // Seven segment LED
|
||||
|
||||
Adafruit_7segment sevenseg = Adafruit_7segment();
|
||||
|
||||
Adafruit_7segment *sevenseg[8];
|
||||
uint8_t sevensegs = 0;
|
||||
uint8_t sevenseg_state = 0;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void SevensegWrite(void)
|
||||
{
|
||||
sevenseg.writeDisplay();
|
||||
for (uint32_t i = 0; i < sevensegs; i++) {
|
||||
sevenseg[i]->writeDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void SevensegClear(void)
|
||||
{
|
||||
sevenseg.clear();
|
||||
for (uint32_t i = 0; i < sevensegs; i++) {
|
||||
sevenseg[i]->clear();
|
||||
}
|
||||
SevensegWrite();
|
||||
}
|
||||
|
||||
|
@ -50,8 +54,10 @@ void SevensegClear(void)
|
|||
|
||||
void SevensegInitMode(void)
|
||||
{
|
||||
sevenseg.setBrightness(Settings.display_dimmer);
|
||||
sevenseg.blinkRate(0); // 0 - 3
|
||||
for (uint32_t i = 0; i < sevensegs; i++) {
|
||||
sevenseg[i]->setBrightness(Settings.display_dimmer);
|
||||
sevenseg[i]->blinkRate(0);
|
||||
}
|
||||
SevensegClear();
|
||||
}
|
||||
|
||||
|
@ -69,17 +75,25 @@ void SevensegInit(uint8_t mode)
|
|||
void SevensegInitDriver(void)
|
||||
{
|
||||
if (!Settings.display_model) {
|
||||
if (I2cSetDevice(SEVENSEG_ADDRESS1)) {
|
||||
if (I2cSetDevice(Settings.display_address[0])) {
|
||||
Settings.display_model = XDSP_11;
|
||||
}
|
||||
}
|
||||
|
||||
if (XDSP_11 == Settings.display_model) {
|
||||
sevenseg_state = 1;
|
||||
sevenseg.begin(SEVENSEG_ADDRESS1);
|
||||
|
||||
for (sevensegs = 0; sevensegs < 8; sevensegs++) {
|
||||
if (Settings.display_address[sevensegs]) {
|
||||
I2cSetActiveFound(Settings.display_address[sevensegs], "SevenSeg");
|
||||
sevenseg[sevensegs] = new Adafruit_7segment();
|
||||
sevenseg[sevensegs]->begin(Settings.display_address[sevensegs]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Settings.display_width = 4;
|
||||
Settings.display_height = 1;
|
||||
Settings.display_height = sevensegs;
|
||||
|
||||
SevensegInitMode();
|
||||
}
|
||||
|
@ -101,15 +115,34 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
|||
boolean hex=false;
|
||||
boolean done=false;
|
||||
boolean s=false;
|
||||
uint8_t unit=y;
|
||||
if ((unit>=sevensegs) || (unit<0)) {
|
||||
unit=0;
|
||||
}
|
||||
|
||||
for (int i=0; (str[i]!='\0') && (!done); i++) {
|
||||
// [prefix(es) chars]digits
|
||||
// [optional prefix(es) chars]digits
|
||||
// Some combinations won't make sense.
|
||||
// Reference: https://learn.adafruit.com/adafruit-led-backpack/1-2-inch-7-segment-backpack-arduino-wiring-and-setup
|
||||
//
|
||||
// Prefixes:
|
||||
// x upcoming number decimal integer displayed as hex
|
||||
// : turn on middle colon
|
||||
// ^ turn on top left dot
|
||||
// v turn on bottom left dot
|
||||
// . turn on AM/PM/Degree dot
|
||||
// s upcoming number is seconds, print as HH:MM or MM:SS
|
||||
// z clear this display
|
||||
//
|
||||
// Some sample valid combinations:
|
||||
// 787 -> 787
|
||||
// x47 -> 2F
|
||||
// st:241 -> 04:01
|
||||
// sT241 -> 4 01
|
||||
// 787 -> 787
|
||||
// x47 -> 2F
|
||||
// s:241 -> 04:01
|
||||
// s241 -> 4 01
|
||||
// s1241 -> 20:41
|
||||
// z ->
|
||||
// x88 -> 58
|
||||
|
||||
switch (str[i]) {
|
||||
case 'x': // print given dec value as hex
|
||||
hex = true;
|
||||
|
@ -126,12 +159,6 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
|||
case '.': // print ampm
|
||||
dots |= 0x10;
|
||||
break;
|
||||
case 'T': // print as time 12 format
|
||||
t = true;
|
||||
break;
|
||||
case 't': // print as time 24 format
|
||||
T = true;
|
||||
break;
|
||||
case 's': // duration in seconds
|
||||
s = true;
|
||||
break;
|
||||
|
@ -149,6 +176,12 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
|||
number = atoi(str+i);
|
||||
done = true;
|
||||
break;
|
||||
case 'z': // Clear this display
|
||||
hasnumber=false;
|
||||
dots=0;
|
||||
s=false;
|
||||
sevenseg[unit]->clear();
|
||||
break;
|
||||
default: // unknown format, ignore
|
||||
break;
|
||||
}
|
||||
|
@ -171,17 +204,17 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin
|
|||
|
||||
if (hasnumber) {
|
||||
if (hex) {
|
||||
sevenseg.print(number, HEX);
|
||||
sevenseg[unit]->print(number, HEX);
|
||||
} else {
|
||||
sevenseg.print(number, DEC);
|
||||
sevenseg[unit]->print(number, DEC);
|
||||
}
|
||||
}
|
||||
|
||||
if (dots) {
|
||||
sevenseg.writeDigitRaw(2, dots);
|
||||
sevenseg[unit]->writeDigitRaw(2, dots);
|
||||
}
|
||||
|
||||
sevenseg.writeDisplay();
|
||||
sevenseg[unit]->writeDisplay();
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
@ -210,7 +243,7 @@ void SevensegTime(boolean time_24)
|
|||
|
||||
|
||||
// Now print the time value to the display.
|
||||
sevenseg.print(displayValue, DEC);
|
||||
sevenseg[0]->print(displayValue, DEC);
|
||||
|
||||
// Add zero padding when in 24 hour mode and it's midnight.
|
||||
// In this case the print function above won't have leading 0's
|
||||
|
@ -218,15 +251,15 @@ void SevensegTime(boolean time_24)
|
|||
if (time_24) {
|
||||
if (hours == 0) {
|
||||
// Pad hour 0.
|
||||
sevenseg.writeDigitNum(1, 0);
|
||||
sevenseg[0]->writeDigitNum(1, 0);
|
||||
// Also pad when the 10's minute is 0 and should be padded.
|
||||
if (minutes < 10) {
|
||||
sevenseg.writeDigitNum(3, 0);
|
||||
sevenseg[0]->writeDigitNum(3, 0);
|
||||
}
|
||||
}
|
||||
if (hours < 10) {
|
||||
// Always have 4 digits time
|
||||
sevenseg.writeDigitNum(0, 0);
|
||||
sevenseg[0]->writeDigitNum(0, 0);
|
||||
}
|
||||
} else {
|
||||
// Identify and display AM/PM
|
||||
|
@ -235,8 +268,8 @@ void SevensegTime(boolean time_24)
|
|||
}
|
||||
}
|
||||
|
||||
sevenseg.writeDigitRaw(2, dots |= ((second%2) << 1));
|
||||
sevenseg.writeDisplay();
|
||||
sevenseg[0]->writeDigitRaw(2, dots |= ((second%2) << 1));
|
||||
sevenseg[0]->writeDisplay();
|
||||
}
|
||||
|
||||
void SevensegRefresh(void) // Every second
|
||||
|
|
Loading…
Reference in New Issue