DALI (Digitally Addressable Lighting Interface) with Atmel AVR


The Digitally Addressable Lighting Interface (DALI) is a electrical interface and bus protocol mainly used to control lightning systems. The interface and the protocol are defined in the standard IEC 60929/EN 60929 Section E.4. There is also a NEMA standard NS-243(-2004).

In DALI-bus segment a master can control up to 64 individually addressable slaves who are also called (digital addressable) ballasts. A ballast can for example control the light-level of a fluorescent lamp. Ballasts may be addressed by their slave-address, they can be assigned to groups which can be accessed by a group-address or all ballast connected to the bus can be addressed by a so called broadcast. I will just mention a few characteristics below. For in-depth information please read the standard, the information available from dali.org or from vendors.

Electrical Specification of the Bus

The DALI-Bus is a "voltage-bus". A voltage between 9.5V and 22.5V is called high level and is the non-active/idle-state. A voltage between -6,5V and 6.5V is called low level. The master or slaves pulse the bus to low level when transferring data. A master could also "push/pull" the bus. Isolation of ballasts is mandatory (typically done with opto-couplers). The current on the bus is limited to 250mA. Since there is a rather high signal-noise-ratio. The two bus-wires can in the same cable as the mains-power. The bus does not have to be "daisy-chained".

Data Protocol

Only a master can initialize a transmission. A DALI transmission consists of a forward message frame send by the master, if the forward message frame includes a command which requests an answer from a slave the slave has to answer with a backward message frame in a time-span between 2.92 milliseconds and 9.71ms after receiving the forward message frame. With a forward message frame 16 data-bits are send to the slaves the slave's answer (if any) has 8 bits of data.

The frame forwarded consists of 1 start-bit, 16 data-bits (two bytes) and 2 stop-bits where start and data-bits are bi-phase encoded ("Manchester coding") and the two stop-bits are kept unencoded. A backward frame has basically the same format but does only include 8 data-bits (one byte). The data-rate is fixed to 1200 bits/sec .

Project: A Bridge between a Home-Automation-Network and DALI


My task was to provide soft- and hardware to connect a DALI bus-segment to a "home"-automation network. (Well, not really a network in a private home but more a "building automation system" of a company but I will use the term home-automation-network here.) I have been asked to develop the interface-hardware to the DALI-Bus and a software-library for a AVR microcontroller. The electrical interface to the home-automation network and the firmware to access this network was already available and is not part of the work presented here.

Since other devices on the home-automation bus are already based on Atmel AVR microcontrollers and code to interface with the netword should be reused the bridge had to be designed around an AVR controller too. The hardware also has to provide the power-supply for the DALI-bus it controls. DALI-Bus and home-automation-bus have to be "isolated" from each other to protect other valuable devices on the home-automation bus. Since I had no experience with the DALI-Bus before I spent a few hours reading the standards and searching the net for information. There are a lot of documents available which describe the bus in general but nothing replaces the standards - they are a "must read" when working with DALI - even if some topics could have been explained clearer.

Finally I found two very interesting applciation notes: one from Microchip which describes a DALI-RS232-brige and one from Freescale (still with a Motorola label) which describes a DALI-slave/ballast and a DALI-RS232 bridge. The Microchip application-note is interesting for those who want to save time building a DALI-RS232 bridge and can use the PIC mentioned in the document. The circuit relies an some special features of the used chip (two internal comparators) and the source-code is only available in PIC assembler (my PIC assembler and PIC hardware knowledge is - well - not good, never felt the need to use a PIC in a design).

So I focused on the Motorola application-note. I took a lot of "inspriration" for my hardware-design from the "DALI-side" of the RS232-DALI-bridge presented in this text. It does not rely on any special microcontroller-feature. Just two GPIO-pins for transfer/TX and receive/RX. This has been ideal for the given task since the microcontroller's firmware has to work on different AVR controllers (i.e. most of them offer only one internal analog-comparator) and it simplifies the optical-isolation. The C-source of the bridge's firmware is also given in the appendix of the appnote and I could understand all and reuse most of the ideas for the DALI low-level-routines. So I created my TODO-list:

  • extract those parts of the Motorola AppNote-schematic needed for the DALI-bus electrical interface (bus-supply, current limiting etc.)
  • search replacements for those parts not instantly available
  • create schematic for the DALI-bus-interface with the available parts
  • test the schematic without microcontroller (voltage-levels, current-limiting) and "tune" values
  • add optical-isolation between DALI-bus-interface and microcontroller
  • test optical isolation
  • connect the electrical interface to a microcontroller (used an Atmel AVR ATmega162) and a DALI-ballast (used two EVGs from Osram)
  • fully understand the DALI-parts of the Motorola example's source-code, and try to keep the software-interfaces identical for tests.
  • create a function-collection to init the bus, transfer forward-frames and receive backward-frames
  • test the function-collection with an example-application

Building the Hardware

Most of the hardware-work went smoothly. I had to modify the DALI interface schematic given in the application-note and some resistor-values a little bit since I only could get different power-transistors and analog-comparators from the local dealer. The galvanic isolation was demanded between DALI-bus-interface and microcontroller to achieve flexible connection-options for the home-automation-bus. So I added two opto-couplers and a few resistors. Since only a prototype without connection-circuit to the home-automation-bus has been requested I just connected the input/output opto-couplers of the DALI-hardware-interface to an Atmel STK500 development-board to continue with the firmware-development. The following picture shows the DALI hardware-interface.

DALI-AVR interface


Since the DALI-protocol can not be transferred with the usual AVR UARTs (AFAIK so far only AT90PWMs offer build-in support for this) the transmission and reception of the frames is done by a "software-UART" which does the decoding and encoding in a timer-interrupt-service-routine. The Freescale application-note once again has been a source of valuable information but the code presented in the document is focused on just bridging between RS232 and DALI. Since the microcontroller has to handle the home-automation-protocol too I encapsulated the DALI-interface in a "function library" written in C using the AVR GNU tool-chain (avr-gcc and friends, collected in WinAVR) and added a hardware-abstraction-layer (HAL) to ease porting between different targets. Since the prototype had to be done with an ATmega162 I had to take care that no resources needed for the home-automation-interfacing software-layer get used by DALI-interface software. Also with the HAL porting the code to i.e. ARM-based controllers will be easy once someone needs this. The software interface (excerpts):

// Initialize
// this does not enable the interrupt - must be done
// by caller to use the DALI interface (AVR: sei())
void dali_Init(void);

// Sends the DALI address and command on the dali port
// for special commands adr is byte 1 and cmd byte 2
// returns 1/TRUE if the command needs to be repeated
// -> call function a second time with same parameters
// within 100ms
// This function blocks if the bus is busy 
// until the previous transfer is finished (use dali_Busy).
unsigned char dali_SendData(unsigned char adr, unsigned char cmd);

// Sends the DALI address and command on the dali port
// (for special commands adr is byte 1 and cmd byte 2)
// and reads answer if requested by *ans != NULL
// returns 1/TRUE if answer has been received (mth)
unsigned char dali_WriteRead(
	unsigned char addr, /* or special cmd byte 1 */
	unsigned char cmd,  /* or special cmd byte 2 */
	unsigned char *ans, /* ptr to answer, NULL if no answer expeced */
	unsigned int  timeout /* * 10ms, ignored if ans==NULL */ );

// returns 1 if busy sending or receiving (mth)
unsigned char dali_Busy( void );

// Check Bus idle (Hardware) - Voltage-level high (mth)
// useful to detect shortage on bus
unsigned char dali_CheckBusIdle(void);

// "Interrupt-Save"/"atomic" flag-handling (flag is 16bit)(mth)
void dali_SetFlag(unsigned int newval);
unsigned int dali_GetFlag(void);

// get DALI answer (ret: 0=no answer, 1 answer avail.) (mth)
unsigned char dali_GetAnswer( unsigned char *answer );

// the interface provides a timer-value (incremented every 10ms) (mth)
unsigned int dali_GetTimerValue(void);
unsigned int dali_ElapsedTime(unsigned int time_start);

// Address utils
// short-address to address-byte for commands
static inline unsigned char dali_saddr_cmd(unsigned char saddr)
	return ( saddr << 1 ) | 0x01;
// short-address to address-byte for direct arc
static inline unsigned char dali_saddr_arc(unsigned char saddr)
	return ( saddr << 1 );


The hardware and software works as expected. I handed out the prototype-interface and the source-code which are now used as templates to create a small series of bridge-devices with connectors for the home-automation-/building-automation-bus for further testing in a "real" environment with more than just two DALI-slaves.

I have no plans to publish any source-code here. Feel free to contact me to request the conditions under which the software is available. I do not offer a "ready-made", "fully qualified", "approved" or "licensed" solution but I can offer help to integrate a DALI master interface into your devices.


back to my AVR projects page

Martin Thomas

60904 hits since September 7, 2007
Last mod.: Sunday, 29-Nov-2009 13:44:15 CET