Skip to content

Commit 64491d2

Browse files
committed
Change DALI send-twice timing from 14 to 10ms fixing MiBoxer DT8
1 parent 41d3ffb commit 64491d2

File tree

1 file changed

+57
-37
lines changed

1 file changed

+57
-37
lines changed

tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
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
@@ -123,6 +124,7 @@
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

593602
bool 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) {
11261137
void 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

Comments
 (0)