The HPE H220, now LSI SAS9207-8 and TrueNAS 12

I’ve been running TrueNAS (previously FreeNAS) at home for more than 10 years on various grades of “least expensive” HP Server hardware. I’ve been impressed from the very beginning. With two young boys data has been accumulating at a fast rate for a number of years and my most recent HP ML10V2 server had simply run out of storage space. So when my file server started throwing SMART errors, telling me one of the drives was on the way out it was time to hurry up with that planned upgrade.

I won’t bore anyone with the details suffice to say, it was going to go from a three drive Raid-Z1 array to *at least* a Six drive Raid-Z2 array, increasing storage from 6TiB to a whopping 16TiB and doubling the number of active spindles. That should give us all plenty of time to grow our “media” library somewhat and replace drives as necessary upgrading the pool as we go.

However before I made this jump I needed to get the HP H220 Raid Card re-flashed and reconfigured for a life outside its traditional RAID setup. After a little research on the interwebs it turns out the HP H220 that I’d bought was a rebadged LSI/Avago/Broadcom SAS9207-8 controller with custom firmware. It pays to cruise the interwebs (especially Serve The Home forums) and find out about your cards chipset, since there are two known versions of the HP H220 card in circulation and they use different chipsets, which can be bothersome.

Now these Storage cards are “intelligent” and come configured for SAS/SATA RAID systems in what’s called IR mode. For TrueNAS we need to the card in a more traditional IT or JBOD mode where TrueNAS can see and control the disks each individually. It does seem odd that we take these high-spec cards and dumb them down, but keep in mind the two SFF-8087 connectors on the card can drive up to four SATA drives at 6Gbps without flinching, with all eight channels singing it will bring the I/O load up on any PCI-E 2.0 bus . For less than A$65 at the time of writing this is still good value.

So just how does one re-flash the firmware on these LSI 9207-8 cards without bricking them ? Well it turns out these cards are hard to brick, the software has a number of checks to prevent silly mistakes, so they are not as fragile as many would fear.

However there are some tricks that I learnt which I thought I’d share, note this is not a how to guide just a collection of my notes I made as I went;

  • The DOS version of the SAS2FLSH utility is what we want to use, it will allow the upgrade or downgrade of firmware and card bios, the UEFI, Windows and linux varieties are not so nice, there is a technical article (ID: 1211161501344) that you can read all about it (YMMV).
  • You can download (at the time of writing) all of the firmware for these cards from the Broadcom website. The webpage is not intuitive, start in the Support and Services / Support documents and downloads page, search using “Legacy Products” and “All legacy products” then 9207-8, perservere there are there and can be found; don’t forget to read and accept the Broadcom license agreements.
  • You will need the P20, P19 and the P14 firmware with IT, IR, BIOS for MSDOS, they are 1.7MB zip files.
  • You can then make yourself a FreeDOS boot disk using Rufus
  • Copy the P20 firmware (9207-8.bin), P19 bios (mptsas2.rom) and P14 sas2flsh.exe utility to the DOS boot disk, and you’re done.
  • The P14 SAS2FLSH utility does not balk at the card being branded HPE when it’s expecting to see LSI, later versions of SAS2FLSH (P19/P20) do this check and will refuse to update. Note that once you write the LSI bios you’ll need to find the original HP bios ROM on the interwebs if you want to go back, there didn’t appear to be any “save” current bios options… caveat emptor
  • The P20 bios ROM will “red screen of death” on some HPE server machines, my ML10V2 was no exception; I simply downgraded the bios to P19 which was 6 months older than my HP bios (J10) version and worked.
  • Once flashed, reboot the machine and enter the controller configuration and setup the card the way you need, hint it helps to specify which card/drive you will boot from, might save you a few unnecessary reboots to find out why it’s not working… sigh

Anyway I’ve made this post to firstly remind me what I’ve done if and when I need to repeat this exercise in the future, it may also be helpful to someone that is trying to update the card and is having trouble. These cards are difficult (not impossible) to brick, but the above certainly worked for me on my hardware, as always YMMV.

Motorola CPS on Windows 10/11

It is no secret that Motorola CPS software does not like to run on modern operating systems. I still have a number of UHF Motorola MTS2000 handhelds which once given new batteries have proven themselves useful time and time again.

However my trusty old Windows XP laptop, with a real serial port fried its motherboard recently never to boot again. My immediate thought was “yikes what do I use now to program these Motorola radios” ?

So rather than go looking for further ancient hardware I started experimenting if Motorola CPS would run on a Windows 10 64-bit platform. I’ll spare you the gory details, but not amount of compatibility mode twiddling or research would result in a working system. There is something fundamental in the RS232 32-bit sub-system within the CPS software that prevents this from ever working. I could not get the CPS software to “read device” instead receiving a timeout. Grrrr….

So the only alternative was to experiment with an older version of Windows in a virtual machine and passing through a serial port. I remember when Windows 7 was first released Microsoft released a version of Windows XP that would run within Microsoft Virtual PC. The Motorola CPS software is from around the same time, so it was an ideal candidate to try. Turns out this was easier than I expected.

Setup Windows XP Virtual Machine

I found the following setup guide very useful from Help Desk Geek website (click). The download link from the Microsoft site has disappeared, but the alternative link from the CNET site was working at the time of this post.

I followed this guide closely, there are a few steps you needed to pay attention too but otherwise this went smoothly. I’m currently using a Windows 10 host and the only trouble I had was with the mouse, where I could not control the mouse within the Guest correctly, but you can temporarily disable the VirtualBox “mouse integration” feature to get around this until the VirtualBox Guest Additions are installed. Once the Guest additions were installed, everything worked as expected.

Activating Windows XP in 2022

The next challenge is since Windows XP support ended there is no way to “activate” this vanilla of windows any more which is right painful. One work around is to snapshot the VM and rollback each time you wish to use it, I wasn’t a fan. So thankfully the “Adventures in Nostalgia” YouTube channel had a video that shows how a regedit method to work around this problem, don’t forget to leave a like.

Serial Port Pass Through

Now I’m lucky that my Gen-3 I7 desktop machine has a real serial port on the motherboard. This was one of the very last Intel made motherboards with the legacy IO chipset, so not only do I have a serial port it has a parallel port too.

To allow Windows XP access to the host serial port, one just needs to configure the hardware pass through. Within the VirtualBox settings there is a separate “Serial Port” tab that simply requires mapping between the guest and host systems.

As you can see I’ve simply mapped COM1 on the guest to COM1 on the host, simples !

Copying Motorola CPS into Windows XP

So for the grand finale we can install the Motorola CPS software within Windows XP. How one gets the software installed can be done a few different ways.

I decided to use the VirtualBox shared folders mechanism. With the guest additions installed I found once I’d configured the shared folders they were automatically mapped as a network drive the next time I restarted the Windows XP guest. It was a simple matter to then double click the executable and install.

There were a few websites with rough instructions, but I found after watching the following YouTube video from Peter Downie I was able to get it working in short order;

The other method I’ve used to pass software through to a guest is to use a USB thumb drive. Copy the files from the host to the USB, pass the USB through to the guest, move the files and eject to pass it back. Both methods work just as well as each other.

The Proof is in the Pudding

So once you can copy the relevant files into the VM, then it’s a simple matter to install and run the Motorola CPS software. Then simply configure it to talk to the serial port you’ve passed through which is COM1 in my case, then try to read a physical radio. Please note that Motorola CPS software is licensed and cost real $$$ to purchase, please do not request copies of said software fro me as refusal often offends.

You will know you’ve got it right when you hear the radio beep, it says PRGM on the radio display and you are greeted with the contents of your code plug.

I was certainly relieved to be greeted with the screen shown above, make my changes and write the config back to the radio. I’m once again in business. I hope that other users of older Motorola CPS software find this useful.

How do you get on 23cm ?!?

I was recently looking at getting some radio gear that would get me up onto the Australian 23cm Amateur Radio Band. My first thoughts was to find some second hand commercial amateur gear, but this was soon dashed when 20 year old radios on eBay were fetching more than A$1000 in less than pristine condition. They are hard to find !

My second thought was of course a transverter. Where I would take one of my 2m or 70cm transceivers and “up-convert” the output onto the 23cm band. This is usually done by a combination of loads, mixers, fixed oscillators and amplifiers that you buy assembled or as a kit. Since I wanted to do both FM and SSB this presented something of a problem as the receive transmit frequency split for Australian 23cm repeaters is +20MHz. This means the radio attached to the transverter IF port has to be capable of wide band receive, which is not very common. So my calculator again suggested after I’d built a transverter, added a dedicated IF radio I’d be somewhere northwards of A$750… sigh that second hand commercial radio looked good again.

One of my local radio club members then introduced me to the Analog devices ADALM-Pluto SDR and the Pluto Charon 23cm module from Minikits here in Adelaide. I was hooked and two new toys were duly ordered and shipped. The cost of both the ADALM Pluto and Charon 23cm module was less than A$450 delivered but I did have to do a little shopping around to get the Pluto at a good price.

I then started researching what exactly you can do with one of these little devices and what exactly I’d just bought. I’m simply amazed at what Analog Devices have stuffed into this little box, better yet I’d received one of the Rev D platforms which has all the bells and whistles. As I discover things about the Pluto, I’m sure to blog them here soon.

I was again pleased to find the ADALM-Pluto was already supported by SDR-Console written by Simon Brown G4ELI. I’ve used SDR Console for many years in all of my HF contesting stations to display waterfall information. Using it for transmit was going to be a new experience.

Now to wait for that postman !

Altium Designer & Windows 10

If you are a regular user of an older version of Altium Designer (AD), you may find some “interesting” problems when running on the latest version of Windows 10.

When recently creating a smart PDF I noted that the reference zone text within the page boundaries of a schematic had suddenly disappeared. Thinking this was odd, I also tried printing to a PDF no dice, worse yet a print preview gave the same result. So where did they go ?

There was little useful help from the Altium website about such issues, other than to say it could be a video card or print driver problem and to delete all drivers and add them back one at a time until you work out which one is causing the problem. Sigh, so not helpful.

Instead it turns out in older versions of AD may use the 32-bit GDI+ interface to render text, this was always going to end badly with the latest 64-bit edition of Windows 10.

Thankfully one can disable this feature within AD by clearing the “Render text using GDI+” checkbox in the following Menu;

DXP > Preferences > Schematic > General > Options

After unchecking, the reference zone characters reappeared in both my SmartPDF and printed copies, woo were back ! I’m filing this here so I can remember what to do the next time I have this problems, I hope that others may find this useful.

pfBlockerNG + GeoIP and the unintended consequences

For anyone using pfBlockerNG with GeoIP enabled there are a couple of hidden gotchas if you like Streaming Services !

During this COVID-19 crisis I was able to work from home remotely. During this time I noticed that every hour at 1 minute past the hour that various streaming services would loose connectivity for approximately 60 seconds. Apart from being very annoying and embarrassing, my co-workers began to set their clocks in meetings each time I dropped out.

So after ruling out the usual DHCP issues on my WAN, ISP issues, low level hardware issues etc I then remembered some weeks before this COVID-19 malarkey installing pfBlockerNG using instructions from one of my favourite YouTube channels Lawrence Systems (click). There are no such things as co-incidences.

So investigating various options and double checking configurations I noted this unassuming check box at the bottom of the pfBlockerNG IP configuration page;

So thinking about this a little, what it means is every hour on the hour this will force any current IP states in the firewall found to be within a blocked range to be cleared. This includes established states. It was about then the penny dropped, what if the streaming services I was currently using were in a GeoIP blocked group, every hour on the hour any established connection would close, then be forced to renegotiate a connection. Sigh. So this is how I had configured my GeoIP settings;

What you can’t see here is within Oceania I’d unblocked my own country “Australia” from these rules. What made me twig to this being the problem is some of the streaming services I use were not being interrupted, upon a little digging all of these used a CDN (mainly Cloudflare) and were coming from IP ranges that were not being blocked. Where as services like Foxtel Go, Microsoft Teams and even ssh connections to my virtual server in Japan were dropping with frightening regularity.

To stop this from happening all I needed to do was not enable the kill states and away it went again. I could have also taken a longer route and identified IP ranges for stream services I wanted to allow, and may investigate this further. YMMV.

Surprise Visitor on Doorstep

This week in Adelaide we’ve had a heat wave, where the minimum over night temperatures haven’t dropped below 35 degC (95 degF) with maximums up and over 43 degC (110 degF). It’s been hot, damn hot.

In Australia we typically find our koala’s sitting in trees, however during heat waves we find them seeking cooler places.

So today I found this little munchkin sitting on my front doorstep when I got home from work, it was a small ball of misery when I first saw it.

It would likely be last years Joey, so about 1-2 yrs old and only just separated from its Mother. I believe I has seen this juvenile koala on his mothers back last summer, there are two females and a male that visit our house regularly.

So given a little water in a big flat dish, a light misting with a water bottle I quietly snuck inside opened the front door and turned the evap air-conditioner on. There was a fair draft of cool moist air headed out that door. With a few hours to cool down and a bit of a nap it once again sat up (a good sign apparently) had clear eyes and bottom. I’m guessing that once darkness falls and it cools down my little visitor will go and find something to eat.

Thankfully a cool change has just arrived and temperatures are finally plummeting back into the low 30’s (mid 80’s F).

And for an encore we also took a swim…

I’m going to have to admit that Juvenile Koalas are very cute and rather photogenic.

The Bus Pirate & my High-2-Sea Adventure.. Arrrrrrr !

This past week I’ve been busy hacking on an Arduino project that uses the I2C bus. It’s been ages since I’d used the Wire library so I was more than a little rusty. Thankfully when it came time to test the code I’d written I could reach into my test equipment box and yank out my Bus Pirate. I’ve been saving up that post title for a while now.

Looking in the test equipment box I noticed at some point in the past I’d purchased one of the SeeedStudio v4 bus pirates which I’d forgotten about. Until now I’d typically used the Sparkfun v3.6 design. Hmm don’t remember when I purchased the new unit, must be old age.. Anyway seemed like a good time to take the plunge with the updated unit.

This new Arduino project monitors the voltage and current in a few external supply rails. Which can then be read by another device over the I2C. I’m sure at some point you’ll find the project code sitting in a public repository along with some hardware files as I complete and test a bit more of the project.

The bus pirates are great if you need to drive and interact with I2C devices. It implements a very simple macro style interface which means you can also edge case test and send out of order I2C signals to make sure your code is working.

So the first surprise with the new v4 unit was when I plugged it into my Windows 7 Dev machine, it needed a driver. I found it here here in the bus pirate archive (click), it actually wasn’t that easy to find. Once I’d updated the “driver” Win 7 it then did its usual thing and turned into a Serial Port.

Connecting to the Bus Pirate with PuTTY is relatively straight forward once you’ve found the serial port number, serial speed is 115200. It was then time to connect the wires. Dangerous Prototypes have a great page on how to do this, you can find it here (click). In a nutshell on my v4 board MOSI connected to SDA, CLK to SCK and GND to GND. Now back to the console. Firstly we need to get the Bus Pirate into I2C mode, so I used the following commands;

1. HiZ
2. 1-WIRE
3. I2C
4. SPI
5. 2WIRE
6. 3WIRE
7. LCD
8. DIO
x. exit(without change)

I2C mode:
 1. Software
 2. Hardware

Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

As you will see I decided to select I2C software mode and a speed of 50kHz to start with. So now we need to turn on the power supplies and turn on the pull-up resistors to talk to the Arduino.

Power supplies ON
Pull-up resistors ON
Warning: no voltage on Vpullup pin

Umm… hold the boat ! What’s happened to the pull-ups? That one threw me for a bit, I don’t remember the Sparkfun v3.6 units doing this.

Well if you’ve only skim read the Dangerous Prototypes v4 page like I had you would have missed you need to connect the Vpu pin to one of the internal supplies, so in my case I used another wire to short Vpu to the 3V3 pin, conveniently they were adjacent to each other.

If you look closely you can see a yellow wire in the top right of the image above, that joins Vpu to 3V3 and is the secret sauce to making this work. Ok so now that’s solved I could then try to get the power supplies and pull-ups working again;

Power supplies ON
Pull-up resistors ON

From here it was straight forward to the rest of the testing. Another good tid bit is the following macro is great for checking things work as expected, essentially it scans the bus and will report all of the devices it can talk to;

Searching I2C address space. Found devices at:
0x40(0x20 W) 0x41(0x20 R)

Sweet. The Bus Pirate found my device and tells me I can read and write to it. More importantly I know what address to use, sometimes things get a little screwy due to the 7-bit I2C address and the read-write bit. Dangerous Prototypes have a good guide that allow you to work out what macros you need to use to build your I2C commands (click).

Here’s an example of me reading a single register from a specific address from within my Arduino I2C firmware;

I2C>[0x40 0x50[0x41 r]
READ: 0x08

So the macro above can be read from left to right and in words;

  • send a start condition
  • the write address (0x40)
  • a data byte (0x50)
  • a second start condition
  • the read address (0x41)
  • read byte
  • stop condition

.The bus pirate then prints that it READ a value of 0x08 from that register. Actually that value tells me there are 8 bytes in that register strucutre, so I can modify my macro and read the entire contents;

I2C>[0x40 0x50[0x41 r:8]
READ: 0x08 ACK 0x20 ACK 0x1C ACK 0x00 ACK 0x00 ACK 0x98 ACK 0x3A ACK 0x00                       NACK

You’ll see that the last part of the above macro is now set to read 8 bytes and you can see the response from the unit appears to have data in it. The nice thing with an Arduino is you can have it print out messages on it’s serial port and then check the responses match, so I’m gong to call that working !

Now all I need to do is write a script that can then test all of the I2C edge cases to ensure my code really works and I’ll be able to move on to a more interesting part of the project.

Arduino Micro from Scratch

For a while I’ve been building small projects and widgets with combinations of either the Arduino Micro or Leonardo’s. These platforms both use the Atmel ATmega32U4 which is now owned by Microchip. So while working on a recent “ham radio widget” I decided to embed my own custom made Arduino based on the micro platform. This design used DIN rail enclosures which require a fairly funky shaped PCB, so it was time to take the plunge and stop using modules purchased from eBay.

Finding a suitable schematic and parts list was not difficult, laying out the PCB was also uneventful. Since this module would be mounted vertically in an enclosure, I decided to simply squash up the pins on the micro into a double header. This was neat as it then allowed me to re-use the standard Arduino Micro pin map. Anyway a picture speaks a thousand words;

This board is fairly straight forward by design, however it did end up requiring 4 layers to fit within my enclosure with components I could see with my naked eye.

Once built I could then use the 6 pin ISP connector which you can see in the foreground above and my trusty AVRisp mk2 programmer. So now for the crux of the problem and the reason for this post, programming the bootloader.

Since I use AVR Studio and my AVRisp mk2 for professional software development, I had not swapped the usb drivers to libusb-win32 which meant I could not simply use the “burn bootloader” option in the Arduino IDE. So I had to do it the “hard way”.

After a bit of googling I found the bootloader hex file was already on my machine conveniently located within a the standard Arduino IDE directory. I found it in the following sub-directory here;


The next question is what fuse settings are required. Now I struggled to find any references with practical solutions to this question on google. Searches ended up taking me off to ATmega328p or Arduino Pro bootloaders, not the micro. There are a many different fuses that can be set and if you get it wrong you can brick your processor, so playing around can lead to bad things.

Anyway after much nashing of teeth I found a practical guide to setting the fuses for a Leonardo, so I figured they should be the same or similar. So before simply blasting in these fuses I spent a bit of time to understand what exactly would change. There was nothing sinister there other than turning off the JTAG (unused) and swapping to an external 16MHz oscillator, jeez I hope I’ve got the right crystal and caps.

Below is the fuse settings I ended up with;

Low:  0xff
High: 0xd8
Ext:  0xfb

After programming the FLASH and fuses I then unplugged the programmer and external power supply and attached it to my PC via USB. I was happily greeted with detected new USB device, installing drivers, device is ready to use on COM62. Phew it worked !

All that was left was to fire up the Arduino IDE and create the ubiquitous blinky led program like so;

void setup() {
  // put your setup code here, to run once:
  pinMode( 13, OUTPUT );
  digitalWrite( 13, LOW );


void loop() {
  // put your main code here, to run repeatedly:

  digitalWrite( 13, HIGH );
  digitalWrite( 13, LOW );

Hitting the “upload” button saw the code compiled, AVR dude did it’s thing and my RED led flashing merrily. Problem solvered ! Now to continue putting these modules together and getting this board setup in PlatformIO.

DMX RS485 Interface

After having configured a Color Kinetics RGB LED driver I need a way to generate a DMX stream to validate it worked as expected. I searched my project boxes for some RS485 USB interfaces in my workshop, but as usual I had put them in a “special” place. So there was nothing for it but to crack out an Arduino and the soldering iron.

This isn’t the first RS485 interface I’ve built for an Arduino, but if you haven’t done it for DMX then I suggest reading this article on Instructables (click) that explains why the standard RS485 shields available are not suitable. However this interface (click) is one that I have found to work, just note that the TX and RX should be Pins 1 & 0 respectively and the enable input (ENB) should be connected to Pin 2.

I like to use the Freetronics Basic Protoshields when building with Arduino’s they are different around the connectors and seem to have more clearance. The photo of the interface (right) was taken just prior to the RS485 safety resistors being mounted across the output of the RS485 bus.

I’d caution anyone against building RS485 interfaces without these safety resistors. With new RS485 receivers you can get away with out using them, but with older receivers they are mandatory. In a nutshell the safety resistors ensure there is always a 200mV differential across the receiver input that ensures the output of the receiver sits in the “UART idle” state. Otherwise what you find is the receiver will either not toggle it’s output or oscillate, in either case it doesn’t work. You just never know if the device you’re talking too has an old or new receiver, so it’s safer (boom boom) to have them than to not. YMMV.

Once the basic interface was built I then realised that this wasn’t going to work with your standard Arduino Uno. You can’t share the UART with both the USB programming and serial debug interface with the RS485 driver without their being bus contention problems, steering resistors can be used with varying success. So the simple solution to this problem was to switch to a Arduino Leonardo, since they have both an on-chip USB interface for debugging and programming and a separate UART connected to pins 0 and 1. This was not without it’s own problems, so much so there is separate blog post to deal with these (click).

So all that was missing was a DMX library. Now this is something of a mine field, there are so many DMX libraries it got confusing finding the right one. After a lot of searching, downloading and fiddling I settled on the “DMX Library for Arduino” written by William van der Meeren (click). What set this library apart was it would transmit a full DMX 512 byte frame every 26ms from a much smaller buffer held in RAM that was non-blocking. It also has a mechanism to signal to the main loop when it had finished a full frame (click) allowing the firmware to quickly update the DMX channels and then allow it to carry on. This meant that colour washes could be kept atomic and smooth.

Below is one of the test programs that I wrote using the DMX library to test a few ideas on what may be possible with this interface. I have also included the PlatformIO config file that includes the necessary build flags;

#include <Arduino.h>
#include "Conceptinetics.h"
#include "math.h"

#define debug_output_enable()	Serial.begin(115200); while (!Serial){}
#define debug_output_f(...)    	Serial.print(F(__VA_ARGS__))
#define debug_msg_f(...) 	Serial.println(F(__VA_ARGS__))
#define debug_output(...)      	Serial.print(__VA_ARGS__)
#define debug_msg(...) 	      	Serial.println(__VA_ARGS__)

// structure to hold RGB colour information
typedef struct
  uint8_t red;
  uint8_t green;
  uint8_t blue;
} mycolour_t;

// DMX addressing information
const uint8_t DMX_DEVICES = 6;
const uint8_t DMX_CHANNELS_PER_DEVICE = 3;
const uint8_t DMX_CHANNELS_MIN = 1;
const uint8_t DMX_BREAK_USEC = 200;
const uint8_t DMX_TXRX_PIN = 2;       // pin 2 used for RS485 TX/RX pin

// setup DMX master control object
DMX_Master dmx_master( DMX_CHANNELS_MAX , DMX_TXRX_PIN );

// convert sine wave to half wave, clamp value to zero for non-negative
// sine ouptut
float non_negative( float degrees )
  if( sin( degrees * DEG_TO_RAD ) < 0.0 )
    return 0.0;
    return degrees;

// Initialise our hardware
void setup( void ) 
  /* Leonardo has separate USB serial port which is enabled when 
     plugged in.

  // display something to user when deubgging
  debug_output_f("Mallee DMX Test\r\n Initialising...");

  // setup our DMX master
  dmx_master.setChannelRange( DMX_CHANNELS_MIN, DMX_CHANNELS_MAX, 0 );
  debug_msg_f(" Done!");

  // all done

// our main loop that will do stuff
void loop( void )
  /* Check if the DMX master is waiting for a break to happen, 
     the function below runs every 26ms (44Hz) which is the DMX
     maximum frame rate.
  if( dmx_master.waitingBreak() )
    // Temp storage for RGB information
    mycolour_t colour;

    // local count variable
    static float angle = 0.0;

    // how much we'll increment our counter per frame
    angle += 0.25;

    //if we overflow wrap back to zero
    if( angle > 360.0 )
      angle = 0.0;

    /* calculate out our RGB values, including our phase offsets;
       not a lookup table in sight !
    */ = (uint8_t)( 255 * sin( non_negative(angle + 120.0) * \ 
                            DEG_TO_RAD) ); = (uint8_t)( 255 * sin( non_negative(angle + 0.0) * \
                              DEG_TO_RAD) ); = (uint8_t)( 255 * sin( non_negative(angle + 240.0) * \
                             DEG_TO_RAD) );
    /* Now we can update all of the attached devices, note that the DMX
       channels and the lamps are configured by the Color Kinetics 
       QuickPro software separately.
    for( uint8_t i = 0; i < DMX_DEVICES; i++ )
      //calculate DMX address for each lamp device
      uint8_t addr = (i * DMX_CHANNELS_PER_DEVICE) + DMX_CHANNELS_MIN;

      //update individual channels are sequentially addressed
      dmx_master.setChannelValue(addr+0, );
      dmx_master.setChannelValue(addr+1, );
      dmx_master.setChannelValue(addr+2, );

    // Generate break and continue transmitting the next frame
    dmx_master.breakAndContinue ( DMX_BREAK_USEC );
;PlatformIO Project Configuration File
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
; Please visit documentation for the other options and examples
platform = atmelavr
board = leonardo
framework = arduino
monitor_speed = 115200
build_flags =

Color Kinetics PDS-150e

The Color Kinetics PDS-150e is an integrated power supply and driver that was popular during the early 2000’s. It is also the “magic” piece that I need for the Solar Mallee Trees project I’ve been working on.

Inside the unit is a power supply and integrated driver. Each of the six output channels are capable of driving up to 25W of RGB LED’s. So this is easily able to power a single Colorburst 4″ RGB LED per channel, they use just 10W. There are four RJ45 connectors across one size of the PCB that present Ethernet, DMX IN, DMX LOOP and DMX Repeater capabilities. I was certainly keen to see what we could do with the Ethernet interface. For these RGB LED drivers Color Kinetics offers a tool called QuickPlay Pro (TM) as a free download for Windows PC’s.

To use the Ethernet interface is relatively straight forward. The PDS-150e device is already programmed with an IP address somewhere within the classic 10.x.x.x Class A network. So I configured a Windows 7 laptop Ethernet interface with the arbitrary IP of with a subnet mask of I was simply crossing my fingers this wasn’t where the controller was, but it would allow the laptop and PDS-150e to find each other. I was pleased once QuickPlay Pro was started that I could find my PDS-150e listed in the “controller” drop down box. At a guess QuickPlay Pro and the PDS-150e either listen to a broadcast address or have some form of mDNS capabilities to “discover” each other.

Once I had connected QuickPlay Pro to the PDS-150e I was able to test the lamps individually, experiment with colour washing and configure the DMX channels and addressing. Below is an example of the colour wash function within QuickPlay Pro;

(C) 2019 Faith Coleman

I will have to say I’ve been doing this type of work for many years and Lighting Control Software has always been a painful experience. Either the software or devices would do “odd” things, not work, fart, spit, sulk or have quirks that required work around’s. However I was pleasantly surprised when QuickPlay Pro just worked, did what it said it would do without any fuss and or bother. So the Color Kinetics Engineering team have done a great job making this system work so well.

Once I’d gotten over my surprise it was a simple task to configure the RGB Lamps that I had into a sequential series of DMX addresses. Each of the Colorburst RGB lamps uses one DMX channel per colour (i.e. 3 channels for RGB), so I simply stringed the lamps together starting at address one;

DMX ADDR:  01  02  03  04  05  06  ........ 13  14  15
CB4 CH#:   R1  G1  B1  R2  G2  B2  ........ R5  G5  B5
Lamp       \---(1)---/ \---(2)---/ ........ \---(5)---/

One thing I did notice is that each Colorburst 4″ RGB lamp has a unique serial number that is displayed in QuickPlay Pro. This suggests that once each lamp is configured this won’t change if you start swapping the port it is connected too. I was pleased to find this is indeed the case, so once I know which tree each lamp is mounted too I can reconfigure the DMX addressing to be a little more logical.

Now I just need to start sending DMX at the controller and see if the lamps respond. Time to go and find a RS485 interface.