mirror of https://github.com/arendst/Tasmota.git
Add support for TM1638 seven segment display
Add support for TM1638 seven segment display by Ajith Vasudevan (#11031)
This commit is contained in:
parent
cea5f6715c
commit
320f0e2776
|
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||||
## [9.3.1.2]
|
## [9.3.1.2]
|
||||||
### Added
|
### Added
|
||||||
- Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) (#5341)
|
- Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) (#5341)
|
||||||
|
- Support for TM1638 seven segment display by Ajith Vasudevan (#11031)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12
|
- PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12
|
||||||
|
|
|
@ -87,6 +87,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
||||||
- Support for XPT2046 touch screen digitizer on ILI9341 display by nonix [#11159](https://github.com/arendst/Tasmota/issues/11159)
|
- Support for XPT2046 touch screen digitizer on ILI9341 display by nonix [#11159](https://github.com/arendst/Tasmota/issues/11159)
|
||||||
- Support for zigbee lumi.sensor_wleak [#11200](https://github.com/arendst/Tasmota/issues/11200)
|
- Support for zigbee lumi.sensor_wleak [#11200](https://github.com/arendst/Tasmota/issues/11200)
|
||||||
- Support for CSE7761 energy monitor as used in ESP32 based Sonoff Dual R3 Pow [#10793](https://github.com/arendst/Tasmota/issues/10793)
|
- Support for CSE7761 energy monitor as used in ESP32 based Sonoff Dual R3 Pow [#10793](https://github.com/arendst/Tasmota/issues/10793)
|
||||||
|
- Support for TM1638 seven segment display by Ajith Vasudevan [#11031](https://github.com/arendst/Tasmota/issues/11031)
|
||||||
- Allow MCP230xx pinmode from output to input [#11104](https://github.com/arendst/Tasmota/issues/11104)
|
- Allow MCP230xx pinmode from output to input [#11104](https://github.com/arendst/Tasmota/issues/11104)
|
||||||
- Berry improvements [#11163](https://github.com/arendst/Tasmota/issues/11163)
|
- Berry improvements [#11163](https://github.com/arendst/Tasmota/issues/11163)
|
||||||
- Extent compile time SetOptions support [#11204](https://github.com/arendst/Tasmota/issues/11204)
|
- Extent compile time SetOptions support [#11204](https://github.com/arendst/Tasmota/issues/11204)
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
#ifdef USE_DISPLAY_TM1637
|
#ifdef USE_DISPLAY_TM1637
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
This driver enables the display of numbers (both integers and floats) and basic text
|
This driver enables the display of numbers (both integers and floats) and basic text
|
||||||
on the inexpensive TM1637- and TM1638-based seven-segment modules.
|
on the inexpensive TM1637- and TM1638-based seven-segment modules.
|
||||||
|
|
||||||
Raw segments can also be displayed.
|
Raw segments can also be displayed.
|
||||||
|
|
||||||
In addition, it is also possible to set brightness (8 levels), clear the display, scroll text,
|
In addition, it is also possible to set brightness (8 levels), clear the display, scroll text,
|
||||||
display a rudimentary bar graph, and a Clock (12 hr and 24 hr).
|
display a rudimentary bar graph, and a Clock (12 hr and 24 hr).
|
||||||
|
|
||||||
To use, compile Tasmota with USE_DISPLAY and USE_DISPLAY_TM1637, or build the tasmota-display env.
|
To use, compile Tasmota with USE_DISPLAY and USE_DISPLAY_TM1637, or build the tasmota-display env.
|
||||||
|
@ -45,15 +45,15 @@
|
||||||
CLK hardware pin --> "TM1638 CLK"
|
CLK hardware pin --> "TM1638 CLK"
|
||||||
STB hardware pin --> "TM1638 STB"
|
STB hardware pin --> "TM1638 STB"
|
||||||
|
|
||||||
|
|
||||||
Once the GPIO configuration is saved and the ESP8266/ESP32 module restarts, set the Display Model to 15
|
Once the GPIO configuration is saved and the ESP8266/ESP32 module restarts, set the Display Model to 15
|
||||||
using the command "DisplayModel 15"
|
using the command "DisplayModel 15"
|
||||||
|
|
||||||
If your display is a TM1637 with 6 digits, set Display Columns to the number of digits your
|
If your display is a TM1637 with 6 digits, set Display Columns to the number of digits your
|
||||||
display has, using the command "DisplayCols 6" and restart the ESP module.
|
display has, using the command "DisplayCols 6" and restart the ESP module.
|
||||||
|
|
||||||
After the ESP8266/ESP32 module restarts again, the following "Display" commands can be used:
|
After the ESP8266/ESP32 module restarts again, the following "Display" commands can be used:
|
||||||
|
|
||||||
|
|
||||||
DisplayClear
|
DisplayClear
|
||||||
|
|
||||||
|
@ -180,39 +180,43 @@ struct {
|
||||||
uint8_t display_type = TM1637;
|
uint8_t display_type = TM1637;
|
||||||
uint8_t prev_buttons;
|
uint8_t prev_buttons;
|
||||||
|
|
||||||
bool driver_inited = false;
|
bool init_done = false;
|
||||||
bool scroll = false;
|
bool scroll = false;
|
||||||
bool show_clock = false;
|
bool show_clock = false;
|
||||||
bool clock_24 = false;
|
bool clock_24 = false;
|
||||||
bool LED[8] = {false, false, false, false, false, false, false, false};
|
bool LED[8] = {false, false, false, false, false, false, false, false};
|
||||||
} TM1637Data;
|
} TM1637Data;
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Init function
|
* Init function
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
bool TM1637Init(void) {
|
|
||||||
|
|
||||||
if(TM1637Data.driver_inited) return true;
|
void TM1637Init(void) {
|
||||||
|
if (PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB)) {
|
||||||
if(PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB)) {
|
|
||||||
TM1637Data.display_type = TM1638;
|
TM1637Data.display_type = TM1638;
|
||||||
TM1637Data.num_digits = 8;
|
TM1637Data.num_digits = 8;
|
||||||
} else if(PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) {
|
}
|
||||||
TM1637Data.display_type = TM1637;
|
else if (PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) {
|
||||||
if(Settings.display_cols[0] <= 6) TM1637Data.num_digits = Settings.display_cols[0];
|
TM1637Data.display_type = TM1637;
|
||||||
else TM1637Data.num_digits = 4;
|
if (Settings.display_cols[0] <= 6) {
|
||||||
|
TM1637Data.num_digits = Settings.display_cols[0];
|
||||||
|
} else {
|
||||||
|
TM1637Data.num_digits = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else return false;
|
|
||||||
|
|
||||||
Settings.display_model == XDSP_15;
|
Settings.display_model == XDSP_15;
|
||||||
|
|
||||||
if(TM1637Data.display_type == TM1637) {
|
if (TM1637Data.display_type == TM1637) {
|
||||||
strcpy(TM1637Data.model_name, "TM1637");
|
strcpy_P(TM1637Data.model_name, PSTR("TM1637"));
|
||||||
tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO));
|
tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO));
|
||||||
tm1637display->begin(TM1637Data.num_digits, 1);
|
tm1637display->begin(TM1637Data.num_digits, 1);
|
||||||
} else if(TM1637Data.display_type == TM1638) {
|
}
|
||||||
strcpy(TM1637Data.model_name, "TM1638");
|
else if (TM1637Data.display_type == TM1638) {
|
||||||
|
strcpy_P(TM1637Data.model_name, PSTR("TM1638"));
|
||||||
tm1638display = new TM1638plus(Pin(GPIO_TM16STB), Pin(GPIO_TM16CLK), Pin(GPIO_TM16DIO), true );
|
tm1638display = new TM1638plus(Pin(GPIO_TM16STB), Pin(GPIO_TM16CLK), Pin(GPIO_TM16DIO), true );
|
||||||
TM1637Data.num_digits = 8;
|
TM1637Data.num_digits = 8;
|
||||||
tm1638display->displayBegin();
|
tm1638display->displayBegin();
|
||||||
|
@ -220,10 +224,8 @@ bool TM1637Init(void) {
|
||||||
TM1637ClearDisplay();
|
TM1637ClearDisplay();
|
||||||
TM1637Data.brightness = (Settings.display_dimmer ? Settings.display_dimmer : TM1637Data.brightness);
|
TM1637Data.brightness = (Settings.display_dimmer ? Settings.display_dimmer : TM1637Data.brightness);
|
||||||
TM1637SetBrightness(TM1637Data.brightness);
|
TM1637SetBrightness(TM1637Data.brightness);
|
||||||
TM1637Data.driver_inited = true;
|
TM1637Data.init_done = true;
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s display driver initialized with %d digits"), TM1637Data.model_name, TM1637Data.num_digits);
|
AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s with %d digits"), TM1637Data.model_name, TM1637Data.num_digits);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -356,7 +358,7 @@ bool CmndTM1637Float(bool clear) {
|
||||||
for(uint32_t i=0, j=0; i<length; i++, j++) {
|
for(uint32_t i=0, j=0; i<length; i++, j++) {
|
||||||
if((j+position) > 7) break;
|
if((j+position) > 7) break;
|
||||||
if(txt[i] == 0) break;
|
if(txt[i] == 0) break;
|
||||||
if(txt[i+1] == '.') {
|
if(txt[i+1] == '.') {
|
||||||
tm1638display->displayASCIIwDot(j+position, txt[i]);
|
tm1638display->displayASCIIwDot(j+position, txt[i]);
|
||||||
i++;
|
i++;
|
||||||
length++;
|
length++;
|
||||||
|
@ -462,8 +464,8 @@ void TM1637ScrollText(void) {
|
||||||
rawBytes[0] = 1 | 2 | 32 | 64;
|
rawBytes[0] = 1 | 2 | 32 | 64;
|
||||||
}
|
}
|
||||||
if(!dotSkipped && TM1637Data.scroll_text[j] == '.') {
|
if(!dotSkipped && TM1637Data.scroll_text[j] == '.') {
|
||||||
j++;
|
j++;
|
||||||
TM1637Data.scroll_index++;
|
TM1637Data.scroll_index++;
|
||||||
rawBytes[0] = tm1637display->encode(TM1637Data.scroll_text[j]);
|
rawBytes[0] = tm1637display->encode(TM1637Data.scroll_text[j]);
|
||||||
}
|
}
|
||||||
if(TM1637Data.scroll_text[j+1] == '.') { rawBytes[0] = rawBytes[0] | 128; }
|
if(TM1637Data.scroll_text[j+1] == '.') { rawBytes[0] = rawBytes[0] | 128; }
|
||||||
|
@ -581,7 +583,7 @@ bool CmndTM1637Raw(void) {
|
||||||
if(i>(TM1637Data.num_digits-1)) break;
|
if(i>(TM1637Data.num_digits-1)) break;
|
||||||
rawBytes[0] = DATA[i-position];
|
rawBytes[0] = DATA[i-position];
|
||||||
tm1637display->printRaw(rawBytes, 1, i);
|
tm1637display->printRaw(rawBytes, 1, i);
|
||||||
}
|
}
|
||||||
} else if(TM1637Data.display_type == TM1638) {
|
} else if(TM1637Data.display_type == TM1638) {
|
||||||
for(uint32_t i=position; i<position+length; i++ ) {
|
for(uint32_t i=position; i<position+length; i++ ) {
|
||||||
if(i>7) break;
|
if(i>7) break;
|
||||||
|
@ -656,7 +658,7 @@ bool CmndTM1637Text(bool clear) {
|
||||||
} else if(sString[j] == '^') {
|
} else if(sString[j] == '^') {
|
||||||
tm1638display->display7Seg(i, (1 | 2 | 32 | 64));
|
tm1638display->display7Seg(i, (1 | 2 | 32 | 64));
|
||||||
} else tm1638display->displayASCII(i, sString[j]);
|
} else tm1638display->displayASCII(i, sString[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -690,7 +692,7 @@ void TM1637SetBrightness(uint8_t val) {
|
||||||
if((val < BRIGHTNESS_MIN) || (val > BRIGHTNESS_MAX)) val = 5;
|
if((val < BRIGHTNESS_MIN) || (val > BRIGHTNESS_MAX)) val = 5;
|
||||||
Settings.display_dimmer = val;
|
Settings.display_dimmer = val;
|
||||||
if(TM1637Data.display_type == TM1637) tm1637display->setBacklight(val*10);
|
if(TM1637Data.display_type == TM1637) tm1637display->setBacklight(val*10);
|
||||||
else if(TM1637Data.display_type == TM1638) tm1638display->brightness(val-1);
|
else if(TM1637Data.display_type == TM1638) tm1638display->brightness(val-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -767,8 +769,8 @@ bool TM1637MainFunc(uint8_t fn) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if(XdrvMailbox.data_len > CMD_MAX_LEN) {
|
if(XdrvMailbox.data_len > CMD_MAX_LEN) {
|
||||||
Response_P(PSTR("{\"Error\":\"Command text too long. Please limit it to %d characters\"}"), CMD_MAX_LEN);
|
Response_P(PSTR("{\"Error\":\"Command text too long. Please limit it to %d characters\"}"), CMD_MAX_LEN);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fn) {
|
switch (fn) {
|
||||||
|
@ -820,22 +822,19 @@ bool TM1637MainFunc(uint8_t fn) {
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
bool Xdsp15(uint8_t function)
|
bool Xdsp15(uint8_t function) {
|
||||||
{
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if(function == FUNC_DISPLAY_MODEL) {
|
if (FUNC_DISPLAY_INIT_DRIVER == function) {
|
||||||
return true;
|
TM1637Init();
|
||||||
}
|
}
|
||||||
|
else if (TM1637Data.init_done && (XDSP_15 == Settings.display_model)) {
|
||||||
if (Settings.display_model == XDSP_15) {
|
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_DISPLAY_INIT_DRIVER:
|
case FUNC_DISPLAY_MODEL:
|
||||||
result = TM1637Init(); // init
|
result = true;
|
||||||
break;
|
break;
|
||||||
case FUNC_DISPLAY_INIT:
|
case FUNC_DISPLAY_INIT:
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: %s: FUNC_DISPLAY_INIT: Display depends on TM1637Data.display_type, currently %d"), TM1637Data.model_name, Settings.display_options.data);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: %s: FUNC_DISPLAY_INIT: Display depends on TM1637Data.display_type, currently %d"), TM1637Data.model_name, Settings.display_options.data);
|
||||||
result = true;
|
|
||||||
break;
|
break;
|
||||||
case FUNC_DISPLAY_SEVENSEG_TEXT:
|
case FUNC_DISPLAY_SEVENSEG_TEXT:
|
||||||
case FUNC_DISPLAY_CLEAR:
|
case FUNC_DISPLAY_CLEAR:
|
||||||
|
|
Loading…
Reference in New Issue