Extend Dali driver

This commit is contained in:
Theo Arends 2024-10-07 18:03:20 +02:00
parent abc6e46354
commit 3e0d36af9d
1 changed files with 64 additions and 39 deletions

View File

@ -19,6 +19,9 @@
--------------------------------------------------------------------------------------------
Version yyyymmdd Action Description
--------------------------------------------------------------------------------------------
0.1.0.1 20241007 update - To stablizie communication send Dali datagram twice like Busch-Jaeger does
- Change DaliPower 0..2 to act like Tasmota Power (Off, On, Toggle)
- Keep last Dimmer value as default power on
0.1.0.0 20241006 rewrite - Add support for ESP8266
- Fix decoding of received Dali 1 data
- Refactor command `DaliPower 0..254` controlling Broadcast devices
@ -39,7 +42,7 @@
#define DALI_IN_INVERT 0 // DALI RX inverted ?
#endif
#ifndef DALI_OUT_INVERT
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
#define DALI_OUT_INVERT 0 // DALI TX inverted
#endif
//#define DALI_DEBUG
@ -50,8 +53,6 @@
#define BROADCAST_DP 0b11111110 // 0xFE = 254
#define DALI_TOPIC "DALI"
// http and json defines
#define D_NAME_DALI "DALI"
#define D_PRFX_DALI "Dali"
const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix
@ -139,22 +140,10 @@ void DaliDigitalWrite(bool pin_value) {
digitalWrite(Dali->pin_tx, (pin_value == DALI_OUT_INVERT) ? LOW : HIGH);
}
void DaliSendData(uint8_t firstByte, uint8_t secondByte) {
Dali->address = firstByte;
Dali->command = secondByte;
if (BROADCAST_DP == firstByte) {
Dali->power = (secondByte); // State
Dali->dimmer = secondByte; // Value
}
uint16_t send_dali_data = firstByte << 8;
send_dali_data += secondByte & 0xff;
DaliDisableRxInterrupt();
void DaliSendDataOnce(uint16_t send_dali_data) {
uint32_t bit_time = Dali->bit_time;
uint32_t wait = bit_time;
// digitalWrite(Dali->pin_tx, HIGH); // already in HIGH mode
// digitalWrite(Dali->pin_tx, HIGH); // Already in HIGH mode
uint32_t start = ESP.getCycleCount();
// Settling time between forward and backward frame
@ -177,8 +166,25 @@ void DaliSendData(uint8_t firstByte, uint8_t secondByte) {
}
// Stop bit
DaliDigitalWrite(HIGH);
delay(1);
}
void DaliSendData(uint8_t firstByte, uint8_t secondByte) {
Dali->address = firstByte;
Dali->command = secondByte;
if (BROADCAST_DP == firstByte) {
Dali->power = (secondByte); // State
if (Dali->power) {
Dali->dimmer = secondByte; // Value
}
}
uint16_t send_dali_data = firstByte << 8;
send_dali_data += secondByte & 0xff;
DaliDisableRxInterrupt();
DaliSendDataOnce(send_dali_data); // Takes 14.5 ms
delay(15); // As used by Busch-Jaeger
DaliSendDataOnce(send_dali_data); // Takes 14.5 ms
delay(1); // Block response
DaliEnableRxInterrupt();
}
@ -189,24 +195,30 @@ void DaliPower(uint8_t val) {
/***********************************************************/
void ResponseAppendDali(void) {
ResponseAppend_P(PSTR("\"" D_NAME_DALI "\":{\"Power\":\"%s\",\"Dimmer\":%d,\"Address\":%d,\"Command\":%d}"),
ResponseAppend_P(PSTR("\"" D_PRFX_DALI "\":{\"Power\":\"%s\",\"Dimmer\":%d,\"Address\":%d,\"Command\":%d}"),
GetStateText(Dali->power), Dali->dimmer, Dali->address, Dali->command);
}
void ResponseDali(void) {
Response_P(PSTR("{"));
ResponseAppendDali();
ResponseJsonEnd();
}
void DaliInput(void) {
if (Dali->input_ready) {
Dali->address = Dali->received_dali_data >> 8;
Dali->command = Dali->received_dali_data;
if (BROADCAST_DP == Dali->address) {
Dali->power = (Dali->command); // State
if (Dali->power) {
Dali->dimmer = Dali->command; // Value
}
}
// AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received 0x%04X"), Dali->received_dali_data);
Response_P(PSTR("{"));
ResponseAppendDali();
ResponseJsonEnd();
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_NAME_DALI));
ResponseDali();
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI));
Dali->input_ready = false;
}
@ -366,25 +378,38 @@ bool DaliJsonParse(void) {
}
void CmndDali(void) {
// Dali {"addr":254,"cmd":100} - Any address and/or command
if (XdrvMailbox.data_len > 0) {
if (DaliJsonParse()) {
ResponseCmndDone();
}
DaliJsonParse();
}
ResponseDali();
}
void CmndDaliPower(void) {
// DaliPower 0 - Power off
// DaliPower 1 - Power on to last dimmer state
// DaliPower 2 - Toggle power off or last dimmer state
// DaliPower 3..254 - Equals DaliDimmer command
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) {
if (XdrvMailbox.payload <= 2) {
if (2 == XdrvMailbox.payload) {
XdrvMailbox.payload = (Dali->power) ? 0 : 1;
}
if (1 == XdrvMailbox.payload) {
XdrvMailbox.payload = Dali->dimmer;
}
}
DaliPower(XdrvMailbox.payload);
}
ResponseCmndStateText(Dali->power);
ResponseDali();
}
void CmndDaliDimmer(void) {
// DaliDimmer 0..254 - Set power off or dimmer state
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) {
DaliPower(XdrvMailbox.payload);
}
ResponseCmndNumber(Dali->dimmer);
ResponseDali();
}
/*********************************************************************************************\