6565 --------------------------------------------------------------------------------------------
6666 Version yyyymmdd Action Description
6767 --------------------------------------------------------------------------------------------
68+ 1.3.0.1 20251120 update - Reduce send-twice timing from 14 to 10ms fixing MiBoxer DT8
6869 1.3.0.0 20251119 update - Add DALI DT8 RGBWAF color support using Tasmota light control
6970 - Add command `DaliChannels` to select Tasmota color type
7071 1.2.0.0 20251116 update - Add persistence for `DaliTarget` if filesystem is present
123124#endif
124125
125126// #define DALI_LIGHT_COLOR_SUPPORT
127+ // #define DALI_LIGHT_NO_READ_AFTER_WRITE // Use no DTR read-after-write for smooth color transitions (saves 55ms / channel)
126128
127129// #define DALI_DEBUG
128130#ifndef DALI_DEBUG_PIN
@@ -159,13 +161,16 @@ struct DALI {
159161 uint8_t web_dimmer[DALI_MAX_STORED];
160162 uint8_t target_rgbwaf;
161163 uint8_t device_type;
164+ uint8_t probe;
165+ #ifdef DALI_DEBUG
166+ uint8_t log_level;
167+ #endif // DALI_DEBUG
162168 bool allow_light;
163169 bool last_power;
164170 bool power[DALI_MAX_STORED];
165171 bool available;
166172 bool response;
167173 bool light_sync;
168- bool probe;
169174 bool invert_rx;
170175 bool invert_tx;
171176} *Dali = nullptr ;
@@ -412,7 +417,7 @@ void DaliReceiveData(void) {
412417 AddLog (LOG_LEVEL_DEBUG_MORE, PSTR (" DLI: Rx collision" ));
413418 }
414419 }
415- if (Dali->probe ) {
420+ if (1 == Dali->probe ) {
416421 AddLog (LOG_LEVEL_DEBUG, PSTR (" DLI: Rx %05X %d" ), received_dali_data, gap_time);
417422 } else {
418423 if (Dali->response || // Response from last message send
@@ -438,7 +443,7 @@ void DaliSendDataOnce(uint16_t send_dali_data) {
438443 Bit number 01234567890123456789012345678901234567
439444 1 2 3
440445 */
441- Dali->last_activity += 14 ; // As suggested by DALI protocol (> 9.17 ms)
446+ Dali->last_activity += 10 ; // As suggested by DALI protocol (> 9.17 ms)
442447 while (!TimeReached (Dali->last_activity )) {
443448 delay (1 ); // Wait for bus to be free if needed
444449 }
@@ -533,7 +538,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) {
533538 }
534539
535540#ifdef DALI_DEBUG
536- AddLog (LOG_LEVEL_DEBUG , PSTR (" DLI: Tx DT%d, Twice %d, Adr 0x%02X, Cmd 0x%02X" ), Dali->device_type , send_twice, adr, cmd);
541+ AddLog (Dali-> log_level , PSTR (" DLI: Tx DT%d, Twice %d, Adr 0x%02X, Cmd 0x%02X" ), Dali->device_type , send_twice, adr, cmd);
537542#endif // DALI_DEBUG
538543
539544 uint16_t send_dali_data = adr << 8 | cmd;
@@ -568,7 +573,7 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) {
568573 Dali->response = false ;
569574
570575#ifdef DALI_DEBUG
571- AddLog (LOG_LEVEL_DEBUG , PSTR (" DLI: Rx 0x%05X" ), result);
576+ AddLog (Dali-> log_level , PSTR (" DLI: Rx 0x%05X" ), result);
572577#endif // DALI_DEBUG
573578
574579 return result;
@@ -585,9 +590,13 @@ bool DaliSetDTR(uint32_t dtr, uint32_t adr, uint32_t value) {
585590 uint8_t dtr_query[3 ] = { DALI_102_QUERY_CONTENT_DTR0, DALI_102_QUERY_CONTENT_DTR1, DALI_102_QUERY_CONTENT_DTR2 };
586591
587592 if (dtr > 2 ) { dtr = 0 ; }
588- DaliSendData (dtr_set[dtr], value); // Store value in DTR
589- int result = DaliSendWaitResponse (adr | DALI_SELECTOR_BIT, dtr_query[dtr]); // Get DTR value
590- return (result == value);
593+ uint32_t retry = 3 ;
594+ while (retry--) {
595+ DaliSendData (dtr_set[dtr], value); // Store value in DTR
596+ int result = DaliSendWaitResponse (adr | DALI_SELECTOR_BIT, dtr_query[dtr]); // Get DTR value
597+ if (result == value) { return true ; }
598+ }
599+ return false ;
591600}
592601
593602bool DaliSetValue (uint32_t adr, uint32_t getcmd, uint32_t setcmd, uint32_t v) {
@@ -659,12 +668,14 @@ uint32_t DaliQueryRGBWAF(uint32_t adr) {
659668 }
660669 }
661670 if (DALI_209_DEVICE_TYPE == dt) {
662- delay (DALI_TIMEOUT);
663- DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
664- delay (DALI_TIMEOUT);
665- int colour_type = DaliSendWaitResponse (adr, DALI_209_QUERY_COLOUR_TYPE_FEATURES);
666- if (colour_type >= 0 ) {
667- rgbwaf_channels = (colour_type >> 5 ) & 0x07 ; // RGBWAF channels in bits 5..7
671+ uint32_t retry = 3 ;
672+ while (retry--) {
673+ DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
674+ int colour_type = DaliSendWaitResponse (adr, DALI_209_QUERY_COLOUR_TYPE_FEATURES);
675+ if (colour_type >= 0 ) {
676+ rgbwaf_channels = (colour_type >> 5 ) & 0x07 ; // RGBWAF channels in bits 5..7
677+ break ;
678+ }
668679 }
669680 }
670681 return rgbwaf_channels;
@@ -917,51 +928,50 @@ bool DaliSetChannels(void) {
917928 if (255 == cur_col[i]) { cur_col[i] = 254 ; } // Max Dali value
918929 }
919930 uint32_t adr = DaliTarget2Address (Dali->Settings .target );
920-
921931#ifdef DALI_LIGHT_COLOR_SUPPORT
922932 uint32_t channels = Dali->Settings .light_type -8 ;
923- if ((Dali->target_rgbwaf > 0 ) && (channels > 1 )) { // Colour control
933+ if ((Dali->target_rgbwaf > 0 ) && (channels > 0 )) { // Colour control
924934 adr |= DALI_SELECTOR_BIT; // Enable Selector bit
925- /*
926- // This is too slow - 800ms for 5 channels
927- if (!DaliSetDTR(0, adr, 0x7F)) { return true; } // Linked Channel control
935+ # ifdef DALI_LIGHT_NO_READ_AFTER_WRITE
936+ // This takes 310ms for 3 channels but might send bad data as no DTR read-after-write
937+ DaliSendData (DALI_102_SET_DTR0, 0x7F ); // Linked Channel control
928938 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
929939 DaliSendData (adr, DALI_209_SET_TEMPORARY_RGBWAF_CONTROL);
930940
931- uint32_t channels = Dali->Settings.light_type -8;
932- if (!DaliSetDTR(0, adr, cur_col[0])) { return true; } // DALI Red
933- if (!DaliSetDTR(1, adr, cur_col[1])) { return true; } // DALI Green
934- if (!DaliSetDTR(2, adr, cur_col[2])) { return true; } // DALI Blue
941+ DaliSendData (DALI_102_SET_DTR0, cur_col[0 ]); // DALI Red
942+ DaliSendData (DALI_102_SET_DTR1, (channels > 1 ) ? cur_col[1 ] : 255 ); // DALI Green
943+ DaliSendData (DALI_102_SET_DTR2, (channels > 2 ) ? cur_col[2 ] : 255 ); // DALI Blue
935944 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
936945 DaliSendData (adr, DALI_209_SET_TEMPORARY_RGB_DIMLEVEL);
937946
938947 if (channels > 3 ) {
939- if (!DaliSetDTR(0, adr, cur_col[4])) { return true; } // DALI While
940- if (!DaliSetDTR(1, adr, cur_col[3])) { return true; } // DALI Amber
941- if (!DaliSetDTR(2, adr, 255)) { return true; } // DALI Freecolour - no change
948+ DaliSendData (DALI_102_SET_DTR0, cur_col[4 ]); // DALI White
949+ DaliSendData (DALI_102_SET_DTR1, (channels > 4 ) ? cur_col[3 ] : 255 ); // DALI Amber
950+ DaliSendData (DALI_102_SET_DTR2, 255 ); // DALI Freecolour - no change
942951 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
943952 DaliSendData (adr, DALI_209_SET_TEMPORARY_WAF_DIMLEVEL);
944953 }
945- */
946- // This is fastest - 330ms for 3 channels
947- DaliSendData (DALI_102_SET_DTR0, 0x7F ); // Linked Channel control
954+ # else
955+ // This takes 480ms for 3 channels but might send nothing if DTR read-after-write fails
956+ if (! DaliSetDTR ( 0 , adr, 0x7F )) { return true ; } // Linked Channel control
948957 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
949958 DaliSendData (adr, DALI_209_SET_TEMPORARY_RGBWAF_CONTROL);
950959
951- DaliSendData (DALI_102_SET_DTR0, cur_col[0 ]); // DALI Red
952- DaliSendData (DALI_102_SET_DTR1, cur_col[1 ]); // DALI Green
953- DaliSendData (DALI_102_SET_DTR2, cur_col[2 ]); // DALI Blue
960+ if (! DaliSetDTR ( 0 , adr, cur_col[0 ])) { return true ; } // DALI Red
961+ if (! DaliSetDTR ( 1 , adr, (channels > 1 ) ? cur_col[1 ] : 255 )) { return true ; } // DALI Green
962+ if (! DaliSetDTR ( 2 , adr, (channels > 2 ) ? cur_col[2 ] : 255 )) { return true ; } // DALI Blue
954963 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
955964 DaliSendData (adr, DALI_209_SET_TEMPORARY_RGB_DIMLEVEL);
956965
957966 if (channels > 3 ) {
958- DaliSendData (DALI_102_SET_DTR0, cur_col[4 ]); // DALI White
959- DaliSendData (DALI_102_SET_DTR1, cur_col[3 ]); // DALI Amber
960- DaliSendData (DALI_102_SET_DTR2, 255 ); // DALI Freecolour - no change
967+ if (! DaliSetDTR ( 0 , adr, cur_col[4 ])) { return true ; } // DALI While
968+ if (! DaliSetDTR ( 1 , adr, (channels > 4 ) ? cur_col[3 ] : 255 )) { return true ; } // DALI Amber
969+ if (! DaliSetDTR ( 2 , adr, 255 )) { return true ; } // DALI Freecolour - no change
961970 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
962971 DaliSendData (adr, DALI_209_SET_TEMPORARY_WAF_DIMLEVEL);
963972 }
964973
974+ #endif // DALI_LIGHT_NO_READ_AFTER_WRITE
965975 DaliSendData (DALI_102_ENABLE_DEVICE_TYPE_X, DALI_209_DEVICE_TYPE); // Enable Extended command
966976 DaliSendData (adr, DALI_209_ACTIVATE);
967977 return true ;
@@ -1016,6 +1026,7 @@ bool DaliInit(uint32_t function) {
10161026 digitalWrite (Dali->pin_tx , (Dali->invert_tx ) ? LOW : HIGH); // Idle
10171027 pinMode (Dali->pin_rx , INPUT);
10181028#ifdef DALI_DEBUG
1029+ Dali->log_level = LOG_LEVEL_DEBUG;
10191030 pinMode (DALI_DEBUG_PIN, OUTPUT);
10201031 digitalWrite (DALI_DEBUG_PIN, HIGH);
10211032#endif // DALI_DEBUG
@@ -1126,9 +1137,18 @@ bool DaliJsonParse(void) {
11261137void CmndDali (void ) {
11271138 // Dali {"addr":254,"cmd":100} - Any address and/or command
11281139 // Dali 0|1 - Enable DALI receive probe
1140+ // Dali 2 - Disable debug log output
11291141 if (XdrvMailbox.data_len > 0 ) {
1130- if ((XdrvMailbox.payload >= 0 ) && (XdrvMailbox.payload <= 1 )) {
1142+ if ((XdrvMailbox.payload >= 0 ) && (XdrvMailbox.payload <= 2 )) {
11311143 Dali->probe = XdrvMailbox.payload ;
1144+ #ifdef DALI_DEBUG
1145+ if (0 == Dali->probe ) {
1146+ Dali->log_level = LOG_LEVEL_DEBUG;
1147+ }
1148+ else if (2 == Dali->probe ) {
1149+ Dali->log_level = LOG_LEVEL_DEBUG_MORE +1 ;
1150+ }
1151+ #endif // DALI_DEBUG
11321152 ResponseCmndNumber (Dali->probe );
11331153 return ;
11341154 }
@@ -1290,7 +1310,7 @@ void CmndDaliSend(void) {
12901310 uint32_t params = ParseParameters (5 , values);
12911311
12921312#ifdef DALI_DEBUG
1293- AddLog (LOG_LEVEL_DEBUG , PSTR (" DLI: index %d, params %d, values %d,%d,%d,%d,%d" ), XdrvMailbox.index , params, values[0 ], values[1 ], values[2 ], values[3 ], values[4 ]);
1313+ AddLog (Dali-> log_level , PSTR (" DLI: index %d, params %d, values %d,%d,%d,%d,%d" ), XdrvMailbox.index , params, values[0 ], values[1 ], values[2 ], values[3 ], values[4 ]);
12941314#endif // DALI_DEBUG
12951315
12961316 if (DALI_207_DEVICE_TYPE == XdrvMailbox.index ) { // DaliSend6 - DT6 = 207 = Extended LED commands 224...236
0 commit comments