mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-11 09:04:53 +00:00
[P073] Improve update speed for 74HC595 using DIREct-GPIO
Fix 7dn and 7dt content for 74HC595 displays Also use DIRECT_GPIO for remaining GPIO functions of TM1637 and MAX7219
This commit is contained in:
+4
-2
@@ -42,6 +42,8 @@
|
||||
//
|
||||
|
||||
/** History
|
||||
* 2026-07-24 tonhuisman: Fix 7dn and 7dt commands for 74HC595 to show data correctly for display setups with less than 8 digits
|
||||
* Improve update speed for 74HC595 by using DIRECT_GPIO library for all GPIO commands (also for TM1637 and MAX7219)
|
||||
* 2026-07-21 tonhuisman: Fix wrong content displayed on 74HC595 displays (multiple fixes)
|
||||
* 2026-01-17 tonhuisman: Revert to using 'regular' Arduino GPIO functions for TM1637 displays on ESP8266
|
||||
* 2026-01-12 tonhuisman: Fix initialization of number of digits when upgrading to 20260108 build,
|
||||
@@ -318,7 +320,7 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string)
|
||||
|
||||
# if P073_USE_74HC595
|
||||
|
||||
if (P073_data->is74HC595Matrix()) {
|
||||
if (P073_data->is74HC595Multiplex()) {
|
||||
Scheduler.setPluginTaskTimer(10, event->TaskIndex, 0);
|
||||
}
|
||||
# endif // if P073_USE_74HC595
|
||||
@@ -376,7 +378,7 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string)
|
||||
success = P073_data->plugin_fifty_per_second(event);
|
||||
|
||||
if (success) {
|
||||
Scheduler.setPluginTaskTimer(0, event->TaskIndex, 0);
|
||||
Scheduler.setPluginTaskTimer(5, event->TaskIndex, 0);
|
||||
}
|
||||
|
||||
// success = false; // Don't send out to (not configurable) Controllers or Rules
|
||||
|
||||
@@ -303,16 +303,14 @@ bool P073_data_struct::plugin_fifty_per_second(struct EventStruct *event) {
|
||||
counter50++;
|
||||
# endif // ifdef P073_DEBUG
|
||||
|
||||
if (P073_74HC595_2_8DGT == displayModel) {
|
||||
if (P073_HC595_MULTIPLEX) {
|
||||
hc595_ShowBuffer();
|
||||
}
|
||||
if (is74HC595Multiplex()) {
|
||||
hc595_ShowBuffer();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool P073_data_struct::is74HC595Matrix() { return P073_74HC595_2_8DGT == displayModel && P073_HC595_MULTIPLEX; }
|
||||
bool P073_data_struct::is74HC595Multiplex() { return P073_74HC595_2_8DGT == displayModel && P073_HC595_MULTIPLEX; }
|
||||
|
||||
// ====================================
|
||||
// ---- 74HC595 specific functions ----
|
||||
@@ -353,7 +351,7 @@ void P073_data_struct::hc595_ShowBuffer() {
|
||||
# endif // if P073_USE_74HCMULTIPLEX
|
||||
|
||||
for (; i != stop && i >= 0; i += incr) {
|
||||
shiftOut(pin1, pin2, MSBFIRST, outputbuffer[i]); // Digit data out
|
||||
DIRECT_shiftOut(pin1, pin2, MSBFIRST, outputbuffer[i]); // Digit data out
|
||||
|
||||
// 2, 3 and some 4 digit modules use sequential digit values (in reversed order)
|
||||
// 4, 6 and 8 digit modules use multiplexing in LTR order
|
||||
@@ -373,13 +371,13 @@ void P073_data_struct::hc595_ShowBuffer() {
|
||||
}
|
||||
|
||||
if (digit != 0xFF) { // Select multiplexer digit, 0xFF is invalid
|
||||
shiftOut(pin1, pin2, MSBFIRST, digit);
|
||||
DIRECT_shiftOut(pin1, pin2, MSBFIRST, digit);
|
||||
}
|
||||
# endif // if P073_USE_74HCMULTIPLEX
|
||||
|
||||
if ((P073_HC595_SEQUENTIAL && (0 == i)) || P073_HC595_MULTIPLEX) {
|
||||
digitalWrite(pin3, LOW); // Clock data
|
||||
digitalWrite(pin3, HIGH);
|
||||
DIRECT_pinWrite(pin3, LOW); // Clock data
|
||||
DIRECT_pinWrite(pin3, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,11 +411,21 @@ void P073_data_struct::hc595_ToOutputBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
void P073_data_struct::hc595_ShiftinView() {
|
||||
if (digits < 8) {
|
||||
uint8_t n = 0;
|
||||
|
||||
for (uint8_t i = 8 - digits; i < 8; ++i, ++n) {
|
||||
showbuffer[n] = showbuffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void P073_data_struct::hc595_InitDisplay() {
|
||||
pinMode(pin1, OUTPUT);
|
||||
pinMode(pin2, OUTPUT);
|
||||
pinMode(pin3, OUTPUT);
|
||||
digitalWrite(pin3, HIGH);
|
||||
DIRECT_PINMODE_OUTPUT(pin1);
|
||||
DIRECT_PINMODE_OUTPUT(pin2);
|
||||
DIRECT_PINMODE_OUTPUT(pin3);
|
||||
DIRECT_pinWrite(pin3, HIGH);
|
||||
}
|
||||
|
||||
# endif // if P073_USE_74HC595
|
||||
@@ -1197,6 +1205,7 @@ bool P073_data_struct::plugin_write_7dn(struct EventStruct *event,
|
||||
break;
|
||||
# if P073_USE_74HC595
|
||||
case P073_74HC595_2_8DGT:
|
||||
hc595_ShiftinView();
|
||||
hc595_ToOutputBuffer();
|
||||
|
||||
if (hc595_Sequential()) { // Sequential displays don't need continuous refreshing
|
||||
@@ -1277,6 +1286,7 @@ bool P073_data_struct::plugin_write_7dt(const String& text) {
|
||||
break;
|
||||
# if P073_USE_74HC595
|
||||
case P073_74HC595_2_8DGT:
|
||||
hc595_ShiftinView();
|
||||
hc595_ToOutputBuffer();
|
||||
|
||||
if (hc595_Sequential()) { // Sequential displays don't need continuous refreshing
|
||||
@@ -1633,12 +1643,12 @@ bool P073_data_struct::plugin_write_7dbin(const String& text) {
|
||||
// ---- TM1637 specific functions ----
|
||||
// ===================================
|
||||
|
||||
# define CLK_HIGH() DIRECT_pinWrite(this->pin1, HIGH)
|
||||
# define CLK_LOW() DIRECT_pinWrite(this->pin1, LOW)
|
||||
# define DIO_HIGH() DIRECT_pinWrite(this->pin2, HIGH)
|
||||
# define DIO_LOW() DIRECT_PINMODE_OUTPUT(this->pin2); DIRECT_pinWrite(this->pin2, LOW)
|
||||
# define DIO_INPUT() DIRECT_PINMODE_INPUT(this->pin2)
|
||||
# define DIO_OUTPUT() DIRECT_PINMODE_OUTPUT(this->pin2)
|
||||
# define CLK_HIGH() DIRECT_pinWrite(this->pin1, HIGH)
|
||||
# define CLK_LOW() DIRECT_pinWrite(this->pin1, LOW)
|
||||
# define DIO_HIGH() DIRECT_pinWrite(this->pin2, HIGH)
|
||||
# define DIO_LOW() DIRECT_PINMODE_OUTPUT(this->pin2); DIRECT_pinWrite(this->pin2, LOW)
|
||||
# define DIO_INPUT() DIRECT_PINMODE_INPUT(this->pin2)
|
||||
# define DIO_OUTPUT() DIRECT_PINMODE_OUTPUT(this->pin2)
|
||||
|
||||
void P073_data_struct::tm1637_i2cStart() {
|
||||
# if defined(P073_DEBUG) && !defined(BUILD_NO_DEBUG)
|
||||
@@ -1767,11 +1777,11 @@ void P073_data_struct::tm1637_SetPowerBrightness(uint8_t brightlvl,
|
||||
}
|
||||
|
||||
void P073_data_struct::tm1637_InitDisplay() {
|
||||
pinMode(this->pin1, OUTPUT);
|
||||
pinMode(this->pin2, OUTPUT);
|
||||
DIRECT_PINMODE_OUTPUT(this->pin1);
|
||||
DIRECT_PINMODE_OUTPUT(this->pin2);
|
||||
|
||||
digitalWrite(this->pin1, HIGH);
|
||||
digitalWrite(this->pin2, HIGH);
|
||||
DIRECT_pinWrite(this->pin1, HIGH);
|
||||
DIRECT_pinWrite(this->pin2, HIGH);
|
||||
|
||||
delayMicroseconds(TM1637_CLOCKDELAY);
|
||||
uint8_t bytesToPrint[]{ 0x40 };
|
||||
@@ -1897,10 +1907,10 @@ void P073_data_struct::max7219_spiTransfer(ESPEASY_VOLATILE(uint8_t) opcode,
|
||||
ESPEASY_VOLATILE(uint8_t) data) {
|
||||
spidata[1] = opcode;
|
||||
spidata[0] = data;
|
||||
digitalWrite(pin3, LOW);
|
||||
shiftOut(pin1, pin2, MSBFIRST, spidata[1]);
|
||||
shiftOut(pin1, pin2, MSBFIRST, spidata[0]);
|
||||
digitalWrite(pin3, HIGH);
|
||||
DIRECT_pinWrite(pin3, LOW);
|
||||
DIRECT_shiftOut(pin1, pin2, MSBFIRST, spidata[1]);
|
||||
DIRECT_shiftOut(pin1, pin2, MSBFIRST, spidata[0]);
|
||||
DIRECT_pinWrite(pin3, HIGH);
|
||||
}
|
||||
|
||||
void P073_data_struct::max7219_ClearDisplay() {
|
||||
@@ -1935,10 +1945,10 @@ void P073_data_struct::max7219_SetDigit(int dgtpos,
|
||||
}
|
||||
|
||||
void P073_data_struct::max7219_InitDisplay() {
|
||||
pinMode(pin1, OUTPUT);
|
||||
pinMode(pin2, OUTPUT);
|
||||
pinMode(pin3, OUTPUT);
|
||||
digitalWrite(pin3, HIGH);
|
||||
DIRECT_PINMODE_OUTPUT(pin1);
|
||||
DIRECT_PINMODE_OUTPUT(pin2);
|
||||
DIRECT_PINMODE_OUTPUT(pin3);
|
||||
DIRECT_pinWrite(pin3, HIGH);
|
||||
max7219_spiTransfer(OP_DISPLAYTEST, 0);
|
||||
max7219_spiTransfer(OP_SCANLIMIT, 7); // scanlimit setup to max at Init
|
||||
max7219_spiTransfer(OP_DECODEMODE, 0);
|
||||
@@ -2006,4 +2016,21 @@ void P073_data_struct::max7219_ShowBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
// Borrowed from wiring_shift.c, using DIRECT_GPIO
|
||||
void P073_data_struct::DIRECT_shiftOut(uint8_t dataPin,
|
||||
uint8_t clockPin,
|
||||
uint8_t bitOrder,
|
||||
uint8_t val) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (bitOrder == LSBFIRST) {
|
||||
DIRECT_pinWrite(dataPin, !!(val & (1 << i)));
|
||||
} else {
|
||||
DIRECT_pinWrite(dataPin, !!(val & (1 << (7 - i))));
|
||||
}
|
||||
|
||||
DIRECT_pinWrite(clockPin, HIGH);
|
||||
DIRECT_pinWrite(clockPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ifdef USES_P073
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
|
||||
# define TM1637_POWER_ON 0b10001000
|
||||
# define TM1637_POWER_OFF 0b10000000
|
||||
# define TM1637_CLOCKDELAY 10 // FIXME TD-er: Maybe lower this as we can get as low as 2 usec to remain below the max 250 kHz
|
||||
# define TM1637_CLOCKDELAY 10 // FIXME TD-er: Maybe lower this as we can get as low as 2 usec to remain below the max 250 kHz
|
||||
# define TM1637_4DIGIT 4
|
||||
# define TM1637_6DIGIT 2
|
||||
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
|
||||
# if P073_USE_74HC595
|
||||
bool plugin_fifty_per_second(struct EventStruct *event);
|
||||
bool is74HC595Matrix();
|
||||
bool is74HC595Multiplex();
|
||||
# endif // if P073_USE_74HC595
|
||||
void FillBufferWithTime(bool sevendgt_now,
|
||||
uint8_t sevendgt_hours,
|
||||
@@ -290,10 +290,10 @@ public:
|
||||
uint8_t tm1637_getFontChar(uint8_t index,
|
||||
uint8_t fontset);
|
||||
|
||||
int dotpos = -1;
|
||||
uint8_t showbuffer[8] = { 0 };
|
||||
bool showperiods[8] = { 0 };
|
||||
uint8_t spidata[2] = { 0 };
|
||||
int dotpos = -1;
|
||||
uint8_t showbuffer[8]{};
|
||||
bool showperiods[8]{};
|
||||
uint8_t spidata[2]{};
|
||||
uint8_t pin1 = 0xFF;
|
||||
uint8_t pin2 = 0xFF;
|
||||
uint8_t pin3 = 0xFF;
|
||||
@@ -402,12 +402,17 @@ private:
|
||||
# if P073_USE_74HC595
|
||||
void hc595_InitDisplay();
|
||||
void hc595_ShowBuffer();
|
||||
void hc595_ShiftinView();
|
||||
void hc595_ToOutputBuffer();
|
||||
|
||||
bool hc595_Sequential() { return P073_HC595_SEQUENTIAL; }
|
||||
|
||||
uint8_t outputbuffer[8]{};
|
||||
# endif // if P073_USE_74HC595
|
||||
void DIRECT_shiftOut(uint8_t dataPin,
|
||||
uint8_t clockPin,
|
||||
uint8_t bitOrder,
|
||||
uint8_t val);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user