Hardware Hacking

Enter Your Electronics & Design Project for a chance to win a $200 shopping cart!

Submit an EntrySubmit an Entry  Back to homepage
Project14 Home
Monthly Themes
Monthly Theme Poll


Martin Rush MH3 Beam - $5360 CAD

Stage lights are expensive. If it's not a simple par-can, it more than likely has a hefty price tag. Even a simple static LED like the Chauvet COLORado 1 Quad at AUD $760. And then you have your moving "intelligent" lights, like the Martin Rush MH3 Beam at AUD $5700. Oof! Fortunately, unless you're a large national-scale production company putting on large arena or open-air shows (where you might see upwards of 200 lights), these more expensive lights are generally overkill. I'm a solo freelancer and most of the gigs I do are to audiences of less than 500 people, so I'd be looking for cheaper, smaller, lower quality lights anyway. Something like the Chauvet Intimidator Spot Led 350 for around AUD $1100. Cheaper, but still prohibitively expensive for a freelancer like me to get a nice set of a few of these.


So we turn to the wonderful world of counterfeits, knockoffs, replicas made with cheaper components or by companies who don't know the intricacies of stage lights. We go to Aliexpress or Made-In-China to find cheap lights that do a... good enough job. Occasionally, we're lucky enough to find some real good quality gear, like my moving lights similar to the Intimidators. Some miss the mark completely, like my cold-spark fountains that wouldn't actually work via DMX, or my sunstrips that would flicker and cause other lights to flicker and generally misbehave in a loud environment. Most, though, will sit somewhere in the middle, like my static RGBA LEDs that can be put into 6-channel mode that actually has 7 channels, and cause some interference for any fixtures connected to it when it's turned on (let's hope I'm not using a flamethrower that day! Or just turn them on before connecting them...)


This is the story of how I took those flickery and negatively influential sunstrips, and those un-DMX-able cold-spark fountains, and made them be not-flickery and not-influential, and completely DMX-able.



{gallery:autoplay=false} Sunstrips

10-pixel LED sunstrip, front view

10-pixel LED Sunstrip: Front view

Inside the sunstrip

10-pixel LED Sunstrip: Inside the back. Three boards: Power supply, processor, LED controller.

Display side of the sunstrip processor board

10-pixel LED Sunstrip: Display side of the processor board

Component side of the sunstrip processor board

10-pixel LED Sunstrip: Component side of the processor board

Using the sunstrip controller board as a prototyping tool

10-pixel LED Sunstrip: Using the processor board for completely unrelated prototyping

As long as the mechanics and the optics are okay, these buggy fixtures just become a project for me to fix. The sunstrips were my first. I didn't even know what would be involved in a project like this, but I figured I'd give it a go and see if I can work it out. Fortunately, it was really simple and intuitive. Three boards: power supply, processor, and LED controller. The processor board was also really simple. An STM32, an RS-485 transceiver, and a buffer for the LED logic levels. And it came with pins for SWD! How good's that! That said, this was my first time playing with ARM, so I didn't know just how good yet. I didn't know that ARM had a debug protocol that GDB could run, so I just dove right in, reading all the many layers of technical manuals so I could start writing my own debugger/programmer for my Beaglebone Black. Although simple, it worked a treat. I could read and write data, including SRAM, Flash, and core registers.


This was where I also learned that the extracted ARM firmware could be loaded into and disassembled by IDA, and I could even import the peripheral RAM blocks as segments. So from here it was just a matter of looking through the SRAM to see how the peripherals were set up, and decompiling the firmware to see how the program worked. It, too, was quite simple. TIM2,3,4 were set up as PWMs for each individual LED, USART1 received the DMX data, and GPIOs handled the buttons and display. There was a bunch of other stuff too, like auto mode, sound mode, fade times, different channel modes, etc, but I wasn't really interested in that just yet. I just wanted to be able to control the LEDs, and not have it flicker and cause other connected lights to flicker and dance uncontrollably.


Writing my own code was a bit of a learning curve. I wasn't interested in using a library for something so simple. I figured something like FreeRTOS would be like using the Arduino platform for an AVR. Sure it'll probably make the code easier, but at what cost? So I wrote my own header for the STM32F103. It's not too big a task when I'm only really interested in two peripherals. However, figuring out interrupts and the PLL was the hardest part. But after getting that, it was super easy to get it to respond in a dumb 1-channel-per-pixel fashion. Now I just have to introduce more channel modes, different dimmer curves, fade times, auto programs... when I can be bothered.


Nowadays, when it's not at a gig, I use the processor board as a prototyping tool. Super easy peasy STM32 with buttons, 7-segment display, RS-485 UART, 10 buffered outputs, and 1 direct I/O? What an excellent little board!


Coldspark Fountains

{gallery:autoplay=false} Coldspark Fountains

Dismantled coldspark fountains on a smokey stage

Coldspark fountains: Flashing the firmware on stage the day before a big gig with the Classic Albums Band

Overlaying top and bottom side PCB images, recreating schematic in Altium

Coldspark fountains: Overlaying images of the top and bottom sides of the PCB (right) to recreate the schematic in Altium Designer (left)

Schematic diagram of the coldspark fountain

Coldspark fountains: The schematic diagram

2D PCB layout view in Altium

Coldspark fountains: Laying out the PCB in Altium

3D PCB layout view in Altium

Coldspark fountains: 3D view of the PCB in Altium

Colspark fountains: Testing the new firmware on site the day before a big show

Schematic diagram of the coldspark fountain

Coldspark fountains: Adding more information to the schematic in Altium

Schematic diagram of the coldspark fountain

Coldspark fountains: Adding more information to the schematic in Altium - Isolated DMX I/O

Schematic diagram of the coldspark fountain

Coldspark fountains: Adding more information to the schematic in Altium - Triac controlled motors

Using the Beaglebone and Sunstrip Controller to communicate with the Coldspark

Coldspark fountains: Using a Beaglebone Black and the Sunstrip controller board to communicate with the Coldspark controller board

My next project was to take some knockoff cold-spark fountains that seemed to completely ignore all DMX control, and make them DMX controllable. Of the 6 units, one did listen DMX control - I could hear the relay - but wouldn't actually do anything productive. This was a much more difficult project, the controller board was large and had a lot more on it. It does have its own JTAG connector, but from what I've been able to make out, it's a non-standard pinout, so figuring that out was the first thing I had to do. To my delight, it used exactly the same MCU as the sunstrip! (Though the markings had been scraped off so I didn't know until I hit it with the programmer.) However, it turned out it was readout-protected, so I couldn't access the firmware. Not to be deterred, I downloaded the SRAM so I could see how the peripherals were set up, and I started working out the schematic.


Determined to download the firmware, I read up on ways to bypass STM32 code protection. There was one technique where, if I remember correctly, you can read one word immediately when entering debug mode before CRP kicks in, so you'd have to repeatedly go Reset, Enter debug mode, Read flash word, Reset, repeat. Because of the latency in changing I/O modes on the pins on my Beaglebone (I was using a PRU program I'd written for read/writes, but that depended on the user-mode code to tell the kernel drivers to change the pin direction - PRU doesn't have write access to those registers), I programmed the firmware extractor onto my Sunstrip processor board. But alas, it did not work. It was around this time, looking for solutions, I discovered OpenOCD, and later, how to use GDB with ARM chips. I found that there was a routine in OpenOCD that could disable CRP. I also found out that disabling CRP erases the entire chip! What an absolute disaster! Now I had no choice but to just make it up as I go. Well, I probably wouldn't make it any worse... it doesn't work anymore, so worst case scenario, I set it on fire and it... still doesn't work.


So I start mindlessly writing code, reading datasheets, writing code, researching triac dimming, writing code, researching microcurrent transformers, writing code. One of the motors is PWM controlled, and I already know the frequency from the SRAM. The other two motors are triac controlled, which is obviously fixed to the mains frequency... but how do I detect the phase? Is that what the microcurrent transformer is for? (To this day, I still don't know. I've just left those motors to run at full power. If anybody can help, please do!) I was surprised to learn that there's a huge heating element that heats up the powder. That was surprising because it's a "cold" spark machine - there's no heat in the sparks, you can put your hand in it, you can put your head in it! It uses a titanium-zirconium mix powder, and I couldn't find any information on how to make sparks from it. There was an SPI thermocoupler (which I had to bit-bang because it wasn't on any SPI pins).


To figure out all the parameters, I decide to go the empirical route and make each peripheral controllable via DMX. One channel to control the relay, one channel to control the heater, one channel per motor. I make the temperature read out on the 7-segment LED display, so I can monitor the temperature. I have absolutely no idea how hot it's supposed to get, and I have absolutely no idea how hot it can safely get before parts start failing, so when I start this, naturally I'm quite nervous. I also don't even know what polarity the devices on the other end are, if they're active-high or active-low. But I dive in anyway. I activate the relay (or deactivate? Which way is on?) and wait for awhile to see if anything happens. Nothing. So seemingly, I have everything the right way round. Whichever logic level I'd programmed to mean Off, was correct. I activate the heating element, and the temperature shoots up at a speed that, quite frankly, frightened me! Now it's just a matter of intermittently activating all the motors and waiting until the it stops blowing powder and starts blowing sparks.


Once I found all that out, it was time to consolidate the code and reduce everything into one DMX channel. The "make-it-go" channel. But I also decided to add a second "control" channel, to switch the unit into shutdown mode (all motors, heater, relay off), safe mode (heater on, motors disabled so you can't accidentally make it shoot when you don't want it to), evacuation mode (heater and feeder motor off, grinder and blower motor on, so you can empty the heater/grinder of any powder that's left behind), or normal run mode. I also have a fault detector, inspired simply by the presence of a "Fault" LED, for when the thermocoupler returns a fault code (which as luck would have it, happens when it gets to its maximum temperature) which puts it into shutdown mode. There probably should be some other safety measures, but I don't know what they would be. You could previously only run the machine for 30 seconds at a time, but I couldn't see why. Or more specifically, I couldn't see any measurements that changed with the length of the burst, that would lead me to see a safe upper limit. When shooting bright sparks up into the air, 30 seconds is an extraordinarily long time, and I doubt I'd ever get close to that anyway.


I still have to figure out the triac dimming so I can adjust spark height, and I have no idea how the remote control works, but for now, it's a safe, working product that does exactly what I want it to.


Future Projects

{gallery:autoplay=false} Future Projects

PCB of lighting faderboard

Future projects: A dumb faderboard with faders, buttons, and LEDs; no logic

PCB of lighting faderboard

Future projects: A smart (ish) RS-232RS-232 faderboard with logic and a PIC

Display side of the LED controller board

Future projects: Display side of the simple LED processor board

MCU on the LED processor board

Future projects: The MCU used on the simple LED processor board - STC616AD-5V

I love doing this sort of thing. I enjoy the challenge of figuring out how things work, I enjoy learning about different ways that different manufacturers approach problems. I like learning about new components, and even whole new families or technologies that I hadn't previously given any thought to. I have no education in either electronics or programming, so I feel that this is an exceptional way to learn.


I also have a Behringer pedalboard for use with my live keyboard rig, which does about 10% of what I want it to, so I've done some hacking on that. The proto-board got really messy because of the number of connections, though, so I'm currently using a reduced version and have yet to finish it off. I might write a separate blog post for that. For my next projects, I've acquired some old fader boards for lighting control, that I'm going to try and make useful. Maybe I'll turn them into USB peripherals? I've also acquired some LED controller boards, similar to the sunstrips, but they use an MCU for which I can only find information on in Chinese. Translating the manual will probably be the biggest challenge there!