diff --git a/src/_P073_7DGT.ino b/src/_P073_7DGT.ino index 2eec59bef..86e34f726 100644 --- a/src/_P073_7DGT.ino +++ b/src/_P073_7DGT.ino @@ -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 diff --git a/src/src/PluginStructs/P073_data_struct.cpp b/src/src/PluginStructs/P073_data_struct.cpp index 06970e1c7..8ffd60142 100644 --- a/src/src/PluginStructs/P073_data_struct.cpp +++ b/src/src/PluginStructs/P073_data_struct.cpp @@ -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 diff --git a/src/src/PluginStructs/P073_data_struct.h b/src/src/PluginStructs/P073_data_struct.h index 43bcaedb7..5e4a91d4a 100644 --- a/src/src/PluginStructs/P073_data_struct.h +++ b/src/src/PluginStructs/P073_data_struct.h @@ -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); };