DALI addressing of multichannel led driver

Hello everyone,

my current project involves different lights to create "scenes" based upon sound. I found this excellent DALI project and was able to rebuild it. On this gitpage is also a good cheatsheet for the commands.

My current setup is

I rewrote the code in the example to send commands directly in binary form in order to play around.

#include <Arduino.h>
#include <Dali.h>

#include<Logger.h>
bool DEBUGLOG = 1;

uint8_t MODE = 0;
uint8_t OK = 0;

#define BROADCAST_DP 0b11111110
#define BROADCAST_C 0b11111111
#define ON_DP 0b11111110
#define OFF_DP 0b00000000
#define ON_DP1 0b00111111
#define ON_DP2 0b11010100
#define ON_DP3 0b11100001
#define ON_C 0b00000101
#define OFF_C 0b00000000
# define QUERY_STATUS 0b10010000
# define RESET 0b00100000

void setup() {
  Serial.begin(9600);

  dali.setupTransmit(3);
  dali.setupAnalogReceive(A7);
  dali.busTest();
  dali.msgMode = true;

  Logger::log("--- Dali EXP ---");
}

bool scanByte(byte &result) {
  bool byteArr[8];
  bool ERR = 0;
  bool scandone = 0;

  while(Serial.available()) {
    // byte _temp = Serial.read();
    // Serial.print("-");Serial.print(_temp);Serial.print("-");

    uint8_t _temp = Serial.read();
    // Logger::log("-",_temp);

    if(_temp==124) { // begin scan

      for(int n=7;n>=0;n--) {
        uint8_t temp = Serial.read();
        
        if(temp==49) {
          byteArr[n] = 1;
        } else if(temp==48) {
          byteArr[n] = 0;
        } else {
          ERR = 1;
        }

      }

      scandone=1;
    } 
    // else if(_temp==88) {
    //   MODE=0;
    //   Serial.println("X");
    //   return false;
    // }

    if(scandone) {
      if(Serial.read()==124) { // end scan
        result = 0;
        for(int i=0;i<8;i++) {
          if(byteArr[i]) {
            result = result | (1<<i);
          }
        }

        if(ERR) {
          return false;
        } {
          return true;
        }
      }
    }
  }
  
  return false;
}

bool dimmer = false;
uint8_t dimlevel = 0b00000101;

void loop() {

  String comMsg;

  if(MODE==0) {

    while(Serial.available()) {
      comMsg = comMsg + (char)(Serial.read());
    }

    if(comMsg == "C") {
      MODE = 1;
      Serial.print("C");
      comMsg = "";
    }
    if(comMsg == "X") {
      MODE = 0;
      Serial.print("X");
    }

    if(comMsg == "ini") {    
      Serial.println(comMsg);
      dali.initialisation();
    }
    if(comMsg == "scan") {
      dali.scanShortAdd();
    }
    if(comMsg == "response") {
      bool res = dali.getResponse;
      Logger::log("Response: ");
      Serial.println(res);
    }
    if(comMsg == "help") {
      Logger::log("help"); 
    }
    if(comMsg== "on") {
      dali.transmit(BROADCAST_C, ON_C);
    }
    if (comMsg == "off") {
      dali.transmit(BROADCAST_C, OFF_C);
    }
    if (comMsg == "dimoff") {
      dimlevel = 0;
      dimmer = false;
      Serial.print("OFF: dim = "); Serial.println(dimlevel);
      dali.transmit(BROADCAST_DP,OFF_DP);
    } else if(comMsg == "dim1") {
      dali.transmit(BROADCAST_DP,ON_DP1);
    } else if(comMsg == "dim2") {
      dali.transmit(BROADCAST_DP,ON_DP2);
    }  else if(comMsg == "dim3") {
      dali.transmit(BROADCAST_DP,ON_DP3);
    }  else if(comMsg == "dim4") {
      dali.transmit(BROADCAST_DP,ON_DP);
    } else if(comMsg == "dimon") {
      dimlevel = 10;
      dimmer = true;
      Serial.print("ON: dim = "); Serial.println(dimlevel);
      dali.transmit(BROADCAST_DP,dimlevel);
    } else if(comMsg == "up" && dimmer) {
      dimlevel += 5;
      Serial.print("dim = "); Serial.println(dimlevel);
      dali.transmit(BROADCAST_DP,dimlevel);
    } else if(comMsg == "down" && dimmer) {
      dimlevel -= 5;
      dali.transmit(BROADCAST_DP,dimlevel);
      Serial.print("dim = "); Serial.println(dimlevel);
    }

  }
  
  if(MODE==1) {

    if(Serial.available()) {
      
      byte result,result1;
      OK = scanByte(result);
      OK &= scanByte(result1);

      if(OK) {
        Serial.print(result,BIN); Serial.print(" "); Serial.println(result1,BIN);
        // Logger::log("result  = ",result,BIN);
        // Logger::log("result1 = ",result1,BIN);

        dali.transmit(result,result1);
        uint8_t resp = dali.receive();
        Serial.print("Respons: "); Serial.print(resp); Serial.print(" "); Serial.println(resp,BIN);
      }

      Serial.flush();

    }


  }

  
  delay(250);
}

With the serial input I can "scan", "ini" and "dimon\dimoff". The basic commands work. With the Serial input "C" it is possible to go into command-mode. Then the commands can be sent directly using following style

|YAAAAAAS||xxxxxxxx|

I bought two DALI drivers from skydance. Every channel should have its own address. Unfortunately I can not detect every single channel, but only get one address per driver. I would like to control each channel individually.

Here is the output of the short addresses after startup and using "scan"

--- Dali EXP ---
Short addresses:
BIN: 0 DEC: 0 HEX: 0 Get response
BIN: 1 DEC: 1 HEX: 1 No response
BIN: 10 DEC: 2 HEX: 2 No response
BIN: 11 DEC: 3 HEX: 3 No response
BIN: 100 DEC: 4 HEX: 4 No response
BIN: 101 DEC: 5 HEX: 5 No response
BIN: 110 DEC: 6 HEX: 6 No response
BIN: 111 DEC: 7 HEX: 7 No response
BIN: 1000 DEC: 8 HEX: 8 No response
BIN: 1001 DEC: 9 HEX: 9 No response
BIN: 1010 DEC: 10 HEX: A No response
BIN: 1011 DEC: 11 HEX: B No response
BIN: 1100 DEC: 12 HEX: C No response
BIN: 1101 DEC: 13 HEX: D No response
BIN: 1110 DEC: 14 HEX: E No response
BIN: 1111 DEC: 15 HEX: F No response
BIN: 10000 DEC: 16 HEX: 10 No response
BIN: 10001 DEC: 17 HEX: 11 No response
BIN: 10010 DEC: 18 HEX: 12 No response
BIN: 10011 DEC: 19 HEX: 13 No response
BIN: 10100 DEC: 20 HEX: 14 No response
BIN: 10101 DEC: 21 HEX: 15 No response
BIN: 10110 DEC: 22 HEX: 16 No response
BIN: 10111 DEC: 23 HEX: 17 No response
BIN: 11000 DEC: 24 HEX: 18 No response
BIN: 11001 DEC: 25 HEX: 19 No response
BIN: 11010 DEC: 26 HEX: 1A No response
BIN: 11011 DEC: 27 HEX: 1B No response
BIN: 11100 DEC: 28 HEX: 1C No response
BIN: 11101 DEC: 29 HEX: 1D No response
BIN: 11110 DEC: 30 HEX: 1E No response
BIN: 11111 DEC: 31 HEX: 1F No response
BIN: 100000 DEC: 32 HEX: 20 No response
BIN: 100001 DEC: 33 HEX: 21 No response
BIN: 100010 DEC: 34 HEX: 22 No response
BIN: 100011 DEC: 35 HEX: 23 No response
BIN: 100100 DEC: 36 HEX: 24 No response
BIN: 100101 DEC: 37 HEX: 25 No response
BIN: 100110 DEC: 38 HEX: 26 No response
BIN: 100111 DEC: 39 HEX: 27 No response
BIN: 101000 DEC: 40 HEX: 28 No response
BIN: 101001 DEC: 41 HEX: 29 No response
BIN: 101010 DEC: 42 HEX: 2A No response
BIN: 101011 DEC: 43 HEX: 2B No response
BIN: 101100 DEC: 44 HEX: 2C No response
BIN: 101101 DEC: 45 HEX: 2D No response
BIN: 101110 DEC: 46 HEX: 2E No response
BIN: 101111 DEC: 47 HEX: 2F No response
BIN: 110000 DEC: 48 HEX: 30 No response
BIN: 110001 DEC: 49 HEX: 31 No response
BIN: 110010 DEC: 50 HEX: 32 No response
BIN: 110011 DEC: 51 HEX: 33 No response
BIN: 110100 DEC: 52 HEX: 34 No response
BIN: 110101 DEC: 53 HEX: 35 No response
BIN: 110110 DEC: 54 HEX: 36 No response
BIN: 110111 DEC: 55 HEX: 37 No response
BIN: 111000 DEC: 56 HEX: 38 No response
BIN: 111001 DEC: 57 HEX: 39 No response
BIN: 111010 DEC: 58 HEX: 3A No response
BIN: 111011 DEC: 59 HEX: 3B No response
BIN: 111100 DEC: 60 HEX: 3C No response
BIN: 111101 DEC: 61 HEX: 3D No response
BIN: 111110 DEC: 62 HEX: 3E No response
BIN: 111111 DEC: 63 HEX: 3F No response

I can directly send commands to the address "0" (e.g. |00000001||00011010| for lower light), but all the channels respond equally.

Is there a special way to initialize each channel? How can I separate the driver from its channels?

Dali.cpp (10.7 KB) Dali.h (3.5 KB) Logger.cpp (527 Bytes) Logger.h (296 Bytes)

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.