Modular Lighting Controller
Introduction:
MLC was designed as a direct response to the increased I/O requirements on the ULC. The project goal was to create a modular de-centralized system.
Architecture:
MLC consists of identically pre-programmed boards that receive their configuration from a master device (MLC CORE). The boards are connected to a variant of 'Lynx-Bus'. The communication physical layer is 3-wire full duplex UART (IN,OUT,GND). It is meant as a inter board communication betwen devices within the same electrical distribution box.
Each board has a 'Left' (master) and a 'Right' (bus) side. The initial configuration is expected to come from the master side and contains device address and device configuration. The bus is self-addressable and daisy-chained non-fault-tolerant, meaning each device that is removed/disabled severs the bus. The bus sub-sections continue to operate amongs the connected modules.
To extend the bus beyond a single electrical distribution box, a Bus EXtension board was created. It provides a isolated full-duplex RS-485 physical layer to transfer the bus data.
Support for functions other than relays are provided with boards for Roller blinds and LED PWM controllers.
Each MLC board contains 8 digital inputs for buttons/switches and 8 open-drain relay outputs. Power is supplied from an external 12Vdc power supply that is usually used to power the relays.
Communication Protocol:
When a input change is detected the board generates an event message and sends it to BOTH sides of the bus. The message contains the unique input number (that is based on the device address and input index) and detected input function. This is not tied to the device configuration (asside from the device address). When any device receives a event packet from either side, it forwards it to the other side and processes it against its own configuration. If it finds an action is assigned to the event packet contents it acts acordigly. This concept propagates the event packet thru the entire bus and all devices act upon it. No packet confirmation is sent, so the communication resembles UDP. The only packet confirmation is with the Config packet. When the device accepts the configuration it replyes to confirm there is a device with such address on the bus.
Packet structure:
Each packet starts with STX(0x02) and ends with ETX(0x03). The second byte is a packet type field. The third byte contains packet length. Before-last byte is a checksum for packet integrity verification. Bytes contained in the checksum calculation are from STX(included) to chksum(excluded). The format is as folows:
- Config packet (0x01):
- Config response packet (0x02):
- Event packet (0x03):
- Initial settings packet (0x04):
- Status request (0x05):
- Status reply (0x06):
Configuration properties:
Each device holds its configuration in RAM and stores it in Flash(EEPROM) upon configuration. On boot, the device looks for a valid configuration at predefined Flash location (0x00400000), named RWW_EEPROM. The EEPROM size is configured to be 1kB long, and is checked for correct size setting upon EEPROM read and/or write operations. If it si found to be wrongly configured in returns with an error and hangs the device with a RED LED status. The stored configuration contains a signature byte (0xAB) and a checksum of the entire configuration. Upon eeprom restore, these are both checked, if either is missing/incorrect, the data is labeled faulty and reset to defaults.
The configuration is legacy limited to 80 input events, 8 rollers and 8 alarms (timed toggling), totaling to 448bytes:
struct eeprom_config_struct {
uint8_t eep_signature;
uint32_t timed_toggle_duration_setting;
uint8_t device_address;
uint8_t init_state;
uint8_t config_length;
struct ActionConfig ActionConfig[80];
struct Roller_control Roller_control[9]; // 9 to avoid index mess
struct Alarm_control Alarm_control[9]; // 9 to avoid index mess
uint32_t padding_1;
uint32_t padding_2;
uint32_t padding_3;
uint8_t eep_checksum;
} ConfigStruct;
Since the flash is only writable in 4byte chunks, there are padding bytes to round the struct up.