Serial Command Protocol V1.3 - Jan 1, 2007 Controller variations ===================== The controller comes in a few different format now. They are RGBLED - original 13 RGBLED controller uses MAX6966 PWM chip mRGBLED - 3 RGBLED controller uses software for PWM tiRGBLED - 10 RGBLED controller uses a TI TLC5940 PWM chip All version use the same control protocol so you can mix them on the same communication channel if you'd like. However, there are a few differences. These are pointed out below as the topic arises. To summarize: Max Max LEDs LED Type Curnt LED Current Control via ---- -------- ------ ------------------------------ RGBLED 13 CA only 20ma Software, 10 or 20ma per color mRGBLED 3 CA OR CC 20ma Manual, via resistor choice tiRGBLED 10 CA only 120ma Software, from 1.8 to 120ma in 1.8ma steps Addressing Notes ================ * Board (controller) address Each controller can be assigned a device address (called a Board ID), allowing that commands to be address to a that specific controller. This allows multiple controllers to be attached to the same serial communications line and yet still be individually controlled. There are 240 discreete board/controller addresses (values from 0 - 239 (0x00 to 0xEF). Multiple contollers can be assigned the same board ID and will respond as a single unit to commands. All commands can be targetted to a specific controller/board ID. Boards/controllers can also be assigned to one of 15 controller groups. This is in addition to a boards ID. Commands can be targetted to a controller group and all boards with that assigned group #, regardless of their board ID, will respond. Groups are addressed from 0xf0 (group 0) to 0xfe (group 14). Each board/controller can belong to at least one group (or it may belong to no group). The maximum number of board groups depends on the controller. Currently, both the mRGBLED and tiRGBLED controllers support being assigned to 17 groups (primary and 16 additional ones). The RGBLED controller supports one group (no RAM space for additional groups). All board/controllers will respond to commands send to the broadcast board ID of 0xff (255). This wildcard will address all controllers, regardless of their ID and/or group assignments. * LED Addressing Each single "LED" is really a collection of 3 seperate PWM channels -- one for Red, one for Green and one for Blue. Since the goal of this project is RGBLED control, when you see reference to an LED (or RGBLED), it really means a device that uses three PWM channels). Each LED has a specific address based on it's physical position on the controller. The first LED is addressed as 0 the last LED is the # of LEDs the controller supports, less one. So the RGBLED controller supports LEDS 0-12, the mRGBLED controller 0-2 and the TI based RGBLED controller 0-9. Attempts to address a non-existing LED on a board (lile. trying to address LED 5 on an mRGBLED board that only has 3 RGBLEDs) results in the command being ignored and the controllers error light being lit. Ranges of LEDs may be addressed in a single command with a special form of LED addressing. Since the maximum LED is 12 (hex 0x0c), if the top nibble of an LED address is non-zero, it's indicates a contiguous range of LEDs to affect. The low part of the byte is the starting LED and the high part of the byte is the ending LED (both are inclusive). So, in hex, the LED address "A8" would address the command to LEDs 08 through 0A (i.e. 8 - 10 in decimal). Each LED can also be assigned one of 15 LED groups. The group assignment is in addition to the LED #. When a command to an LED is sent, it can be directed to all LEDs in the group via a single command. LEDs do not belong to any group by default, but can be assigned to one or removed from them at any time. LED groups and controller/board groups, while sharing some common concepts, are not in any way internally related -- there are two seperate classes of groups (i.e. there is no interaction between board/controller groups and LED groups). Unlike boards, each LED can belong to only zero or one group. In addition, all LEDs on a controller/board will respond to the LED address FF (255). It's a broadcast or wildcard address. NOTE On Invalid LED Addresses ----------------------------- When you have a mix of different types of RGBLED controllers (13, 3 and 10 LED units) on the same network, you may find times when addressing all boards (wildcard) or certain board groups that you want to address an LED that is not valid for all boards. For example, consider the case where you have mRGBLED and RGBLED controllers on the same serial port and send a #FF0004 command (broadcast to turn off LED #4 on all boards). The RGBLED controller can accept this, the mRGBLED controller will not. Also consider a command like #FF0080 which is a broadcast command to all boards to turn off LEDs 0 through 8. In this case, the mRGBLED board will process the requests for LEDs 0-2 and ignore 3-8 while the RGBLED controller will process all LEDs from 0 to 8. So, in short, when a command is sent to all boards or a board group, the board will process as many LEDs as it can without causing any error condition (i.e. in the first example, the mRGBLED board will ignore the command for LED #4 *and* will NOT light it's error light -- in the second example, LEDs 0-2 are processed by the mRGBLED board and again, the error light will NOT turn on). However, when a board is directly addressed and it receives commands addressing invalid LEDs (either specifically invalid LED or a range that contains *ANY* invalid LEDs), the entire command is discarded (no partial execution as what happens for wildcard and group board addressing) and the error light comes on. Standard Command Format ======================= Commands are in a ASCII text format and consist of a lead-in character, a series of hex pairs and a line terminator character. Invalid commands and characters are ignored. The format of a command is as follows: #BBCC[.....] That is a pound sign is the intro character, then a 2 character hex board ID (00-FF), then a 2 character hex command (00-FF), then an optional number of additional pairs of hex characters, then a single CR (carriage return, ASCII 13 decimal). All alphabetic portions of a hex pair must be in upper case (i.e. FF is valid, ff is not). Any character received before the # is discarded. Any character after the # must be a valid hex character or a . Anything else aborts the command. If the command length exceeds an internal buffer, the command is aborted. If the command does not consist of an even number of hex characters when the is received, the command is aborted. All messages are a minimum of 4 characters (plus the start and stop character) describing the board ID and the command. Messages may be much longer, depending on the command and any necessary parameters. Binary Command Format ===================== When interfacing the RGBLED controller to another hardware device, typically over the SPI interface (though this works with RS232 as well), requiring all commands to be formatted into ascii text representation of hex values can add a lot of work to what may be a very limited processor. In those cases, it may be easier to just send the binary equivilent of the hex characters that make up a command in Standard mode. This reduces the number of bytes sent over the line and simplifies the logic your controller needs to implement to be able to talk to the RGBLED controller. To send a binary command, the prefix is a % (percent sign). The next byte needs to be the number of bytes to read for the command as an 8 bit binary value. If the # of bytes is less than 2 (the shortest valid command) or more than the maximum valid command length, the bad byte count clears binary mode and sets the RGBLED board back to idle mode. Once in binary mode, the only way out is to send the number of bytes you specified. Because this is binary, there is no escape character/byte. After the command length count, you then send that number of bytes over in simple 8-bit binary format. Once the last byte is complete, the command is then processed like a standard command. As a comparison, turning a single LED on using Standard format would take 8 bytes (#000100 + CR). In Binary mode, it would take 5 (%, the # of bytes in the command (3) and the thee bytes of the command (0, 1 and 0)). You can mix standard and binary commands when speaking to the controller. That is, one command may be binary and the next standard (you cannot switch from binary to standard or vice versa in the middle of a command). Command pacing ============== Up through baudrates of 19.2K (or the equivilent in SYNC terms), the CPU should be able to keep up with the incoming commands with no delays. However, as the baudrate goes up, the CPU can sometimes lag behind. When using the SPI interface, there is a BUSY line that can act as a hardware throttle (when it goes high, stop sending data until it goes low again). For RS232 or SPI when you don't have hardware throttling, you may need to introduce some minor delays to let the CPU keep up. At 38.4kbaud and up, adding a 1ms second delay between each command should be enough The CPU can buffer upto 26 characters of a command. Since commands are converted from the ASCII Hex into bytes as they are received, a command that takes 12 ASCII HEX characters requires only 6 bytes of in the buffer (plus one byte for bookkeeping). The opening # and closed are not buffered and do not consume buffer space. 26 characters allows you to buffer from 3 to 8 full commands (depending on the command size). Command Summary =============== 00 - Turn LED(s) "L" off 01 - Turn LED(s) "L" on at last set values* 02 - Set LED(s) "L " color values (followed by 3 bex pairs - R, G and B) 03 - Set LED(s) "L" current For RGBLED, next hex pair is 00 for 10ma or 01 for 20ma For tiRGBLED, next hex pair is 01-3F (64 steps) which is multiplied by 1.85ma (0B == 20ma, 3F = approx 118ma, default is 0B/20ma). Form mRGBLED, command is ignored (not software controllable) 10 - Slave LED(s) "L" to master LED (master LED in next hex pair) 11 - Liberate/Unslave LED(s) "L" 15 - Assign LED to group X (the group ID is in the next hex pair). The group ID must be a value from 0x00 to 0x0E. Any other value is invalid and an error/ignored. 16 - Clear LED group. After this, the LED is no longer part of any group 20 - Enable Animation for LED(s) L (if any is setup -- ignored if not) Enabling animation for a slaved LED(s) is ignored. Note: Enabling does not turn on the LED -- if the LED(s) is off and you want to see the animated LED, it needs to be turned on (before or after starting animation is fine) 21 - Disable Animation for LED(s) L (LED(s) color/setting left as is) 22 - Init LED(s) animation. If the LED(s) animation is enabled, it's disabled, any colors reset/cleared. The command is followed by two hex pairs -- the animation control flags and animation delay. The flags are described below in the section on animation. 23 - Change animation options for LED(s). The command is followed by two hex pairs -- the animation control flags and animation delay. The flags are described below in the section on animation. 24 - Add a color to the list of colors for the LED(s). Three hex pairs (RGB) follow the LED#. The change takes place immediatly *IF* there is space in the color table. If there is no space, the command is ignored. 25 - Add the "current" color of the LED(s) as a step in the animation. This takes no parameters. It's useful when you want to start an animation at the LEDs current color but you cannot be 100% what that color is (for example, if you disabled animation while it was in process and are not sure what color was installed when it was disabled). Other than using the "current" color at the time the command is received, this otherwise behaves exactly line a command 24. F0 - Change Board ID # (new ID # follows). Like other changes, this change is not permanent until the boards settings are preserved (change from earlier versions of the firmware). F1 - Preserve all settings. Board ID, Group IDs, LED values, states, current, animations, etc are all saved for power on use F2 - Set to common anode LED output (Software PWM version ONLY) [Default] F3 - Set to common cathode LED output (Software PWM version ONLY) F5 - Set Board Group ID -- next hex pair. Group ID must be between 0x00 and 0x0E. Any other value is invalid and ignored. Regardless of how many (if any) additional/auxillary groups a board may have, this command always sets the primary group (unlike F7 which never overwrites any group). F6 - Clear Board Group ID. After this, the board is not part of any group. The primary and any additional/auxillary group IDs are cleared. F7 - Add a Board Group ID (next hex pair). Group ID must be between 0x00 and 0x0E -- any other value is invalid and ignored. If this is called and no primary group ID has been set for the board, then the primary is set. If the primary is already set, then the additional/auxillary groups, if any, are scanned and when an unused group ID slot is found, this is installed. If there are no free additional/auxillary group slots (either the controller doesn't support them or they are all full), the command is discarded. FF - Reboot/Reinitialize all hardware to power-up settings Preserving settings uses the EEPROM on the PIC chip. This has an estimated write/change life of 1,000,000 changes. This is probably more than adequate, but if you issue F1 commands in a loop, it may be possible to exhaust the EEPROM lifetime. After that, at a minimum, settings may be corrupted or at worst, the unit might lockup (reading bad data from bad EEPROM). So exercise a little bit of care and restraint in saving settings. * Default initial values for an LED are 0,0,0 @ 20ma, Off, no group * Default initial values for a board is ID #0, no group Sample commands =============== #000000 -- Turn off LED #0 on board #0 #0100FF -- Turn off all LEDs on board #01 #FF00FF -- Turn off all LEDs on ALL boards #0200A0 -- Turn off LEDs 0-A on board #02 #0001F2 -- Turn on LEDs in LED Group #2 on board 0 #F501F1 -- Turn on LEDs in LED Group 1 on all boards in group 5 #000204FFFF00
- Set LED #04 to Yellow (R=FF,G=FF,B=00) on Board #00 #0003FF01 - Set All LEDs on Board #00 to 20ma output (RGBLED controller) #0010FF00 - Slave all LED on Board #00 to master LED #00 #00FF - reboot the board back to power up defaults. LED Slaving =========== Slaving allows the color values and On/Off state of a "master" LED to immediatly be mirrored in it's slaves. This allows either multiple LEDs to all have the same output or to paralell multiple LED outputs to provide more current. For example, if you have an LED that requires more than the 20ma that can be drawn off a PWM driver, you can "gang" or parallel the outputs of multiple LEDs together. Consider an LED that needs 30ma. You could parallel the LED drivers for the 2nd RGB LED to the outputs of the 1st RGB LED, configure the second LED to put out 10ma and the first to put out 20ma. Then slave the second LED to the first and and changes to the first LED result in both outputs having the same values, but with the 10+20ma (30ma) available for drive. Another example might be wanting a number of LEDs all to react the same way. Backlighting is a great example. To get an even backlight, you frequently need multiple LEDs spaced around whatever it is your are backlighting. In this case, you need multiple LEDs, but you want them to all display the same thing at the same time. Slave them all to a common master and then you need only control one to control them all. When an LED is slaved to another, setting of the slave LEDs on/off status or RGB values are set for the LED, but do not take effect. Any change to a master LED on/off state or color result in all attached slaves immediately taking on those values. When an slaved LED is liberated, it immediatly takes on the values last set for it. The one aspect of an LED that is not subject to slaving is the current setting. This is always independent and changing a masters current output has no impact on a slave (or vice versa). LEDs can have their current settings changed even when they are slaved. You can have as many master/slave configs as needed. In fact, you could slave LEDs 1-9 to LED #0 if you wanted. You cannot slave an LED to another slave. If you do, the target LED will instead be slaved to the your "master" LEDs actual master. An attempt to slave an LED to itself or a non-existant LED will be ignored. NOTE: Slaving works with either the hardware of software PWM versions of this device. With software version, you can tie outputs together to increase current output, but you will need to alter the current limiting resistors too. The software version has no internal current control or limitor, so nothing stops you from over-drawing current. Drawing more than 25ma per LED will likely fry the controller. Keep current draw, per LED output to 20ma for best operation (meaning 60ma for all three legs of an RGBLED). Animation ========= Animation allows you to define a series of colors an LED should cycle through. You describe the time between color changes, the method for changing the color and the list of colors. The LED will then follow those colors until animation is disabled. You can manually install a color (02 command) while an LED is being animated, but the color will be replaced with the next color scheduled for the LED as soon as the next color change is to occur. With wash or morph based color changes, this will happen almost immediatly. When animation is disabled, the LED is left as is. That is, whatever color the LED was set to at the moment it was disabled is left in place. The LED color animation information is retained, allowing you to restart animation again without having to redefined it. However, since the animation is consuming color space, if you know the LED won't be animated again, it's a good idea to re-initialize it (which releases the color table space). There is a fixed amount of space for LED colors in the processor. There are at most 32 color steps that can be allocated in any way to the LEDs (a single LED could have all 32 steps). For fades, you can enable color morphing/washing to allow the processor to figure out the intermediate colors between two points and save a lots of space in the color table. An attempt to add a color to an LED when the color table is full is ignored. Each LED has option flags and a time delay. You set them with two hex pairs follwing the Init command (22) or the change options command (23). The first byte is options and the second one includes the delay between color changes. Options are bit flags within the byte. Options bit 0&1 - color change option 00 -- colors are changed absolutely at each time increment. The color remains untouched until the next time increment. 01 -- colors are continually "morphed" or "wash" to the next color such that each defined color for the LED is only true when the time increment occurs, then it immediatly starts changing to the next color. The rate of change depends on how much difference there is between the current color and the next and the amount of time the color delay is set to. Animation always happens on 1/100s of a second, so if you were washing from black to white over the course of 1 second (the delay time), the LEDs values would change roughly 2 "steps" every 1/100th of a second. If you were going from a dull red (CC0000) to a bright red (FF0000) in one second, you'd see a change in the color about every 1/50th of a second (there are about 50 steps between those two color, spread over one second). 2 - one shot color change When set, the defined animation occurs once and after it occurs, animation for that LED is disabled. The LED is left at the last color of the animation. This is good for static color transitions. If animation is later re-enabled for the device, the animation starts at the begining and repeats, stopping at the last color as before. When clear, the animation repeats endlessly until animation is disabled for the device. 3 - release colors when animation disabled If set, as soon as the animation is disabled, the color table space used by the LED is released to be used for other LEDs. This is most often used with a one shot color change (where you just want to animate a change from one long-term color to another and be done with it), but can be used for repeating colors too. The colors are released when the LED animation is explicitly disabled (via a 21 command) or implicitly disabled (at the end of a one-shot animation). Subsequent attempts to enable animation on the LED will be ignored (at least until another set of colors is programmed). 4&5 - time increment units. 00 -- time increment is in 1/100s of a second 01 -- time increment is in 1/10s of a second 10 -- time increment is in seconds 6 - reserved 7 - reserved Some examples of setting up animation #002200200A - Init LED #00, use explicit color changes and change color every 10 seconds #002400FF0000 - Add color FF0000 (red) to LED #0 #00240000FF00 - Add color 00FF00 (green) to LED #0 #0024000000FF - Add color 0000FF (blue) to LED #0 #002000 - Start animating LED with first color #002100 - Stop animating LED and install first color (FF0000) for LED #00 Updated January 1, 2007