My Arduino workings

I’ve been working away on a couple of projects recently – the Auduino synthesiser and DMX control of a Colour Kinetics iColor Flex SLX 50 node light string – and though I’m not quite ready to post about these yet I thought some of my interim research and workings worth noting…

DMX-mixer-2010-07-17-09-55.jpg

Arduino to DMX

I found a recent Frizing project – ARDUINO TO DMX CONVERTER – which uses the same RS485 chip as Daniel Hirschmann’s Super DMX Shield – which I bought all the components for from Farnell bar the 8 Pin DIP IC Socket (doh!) – so although this was all PC based I thought it might worth looking at in the interim.

For testing purposes (and ‘cos I thought they’d be generally useful) I found and bought a couple of these cheap LED Colour Changing DMX Light on ebay – boxed as Prolight Concepts LEDJ Colour Bursts but actually turning out to be the almost identical but now discontinued Kam LED Par36s…

So I built a rationalised version of the breadboard circuit as per the Fritzing file – I didn’t have the 100Ohm resistor so used several smaller resistors run in series, cut and stripped the jack end wires of an old jack to XLR mic cable and identified each using my multimeter – then wired them up to the 3-Way Phoenix Screw Terminal from my Super DMX Shield components referring to the DMX XLR pin values in the LCDJ Colour Burst manual, installed the Enttec OPEN USB drivers on my VMware Fusion Windows XP virtual machine and looked for some simpler DMX control software than the suggested FreeStyler – which I found via Hippy’s somewhat sprawling but very useful Open DMX USB Resources – specifically Terbos.com‘s Lights Up! (and its sourceforge repository) and DmxDesk9 by Kristof Nys (port by hippy)… and yay… it works!

Subsequent research shows this project is an example of an ‘unbuffered’ device – “because the USB to DMX device is not storing or buffing anything” – and is based on the circuit suggested in Tomek Ness’s ‘Your Arduino becomes a OpenDmx USB interface’ PDF downloadable at the Arduino: Playground DMX512 page… which I should have looked at in the first place.

I subsequently bought the missing socket at Maplin and soldered up the Super DMX Shield and Super DMX Fly Lead referring to the online photos and details of the Rev 1B minor fixes. This was my first DIY shield – and I was a little worried about my basic soldering skills… but slightly melting the plastic mounting of a couple of header pins aside I seem to have managed it.

Then getting ahead of myself in Daniel’s Interactive Lighting Workshop notes I installed the Arduino DMXSimple Library from tinker’s code repository and ran the code examples – and barring some idiosyncratic behaviour and DIP switch inconsistencies with the Kam LED Par36s it works… yay!

Controlling DMX over serial via Processing

I thought it would be a good idea to code up a little Processing DMX mixer to control the LED Par36s from a set of on-screen faders. Starting from the Processing: Communications: Dimmer example I got communication between Processing and the Arduino for a single DMX channel – initially via mouse X position value and then by a ControlP5 slider – easily enough.

But developing this into a multi fader mixer was going to be trickier. Combining the data from three sliders in Processing, sending that via serial communication (which in truth I know very little about other than it’s “the process of sending data one bit at a time, sequentially” – though a tutorial such as the ladyada.net on serial communication should help) then separating it back out into it’s respective parts at the Arduino end – isn’t really dealt with in the Arduino Reference.

But Todbot’s blog has a post Arduino Serial protocol design patterns which discusses solutions and has example code for this very issue… so after a bit of tweaking and integration into my existing mixer sketch I managed to code up fairly rough and ready Processing and Arduino sketches which sent values from the red, green and blue ControlP5 faders in Processing via the Arduino and over DMX to the light’s red, green and blue LEDs and also sent the first 6 bytes of data in the Arduino serial buffer back to Processing for monitoring… et voilà… my first DMX mixer – yay!

UPDATE: Actually I later discovered Controlling DMX over serial, and via Processing under DmxSimple at the at the Arduino: Playground DMX512 page… sigh.

External Interrupts

Having bought some Hall Effect sensors for my electro-magnetic rotary sequencer project my interest was piqued by the post Hall Effect Sensors and Arduino Interrupts – which advised that analogRead() and digitalRead() in a loop – known as “busy waiting” or a “polling loop” was generally frowned upon..

“An interrupt is exactly what it sounds like — it interrupts your Arduino script when an outside event happens, your script can do some simple task, then the script goes back to what it was doing earlier. The doorbell on your front door is an excellent example of an interrupt. You could go to the door every minute and check to see if someone is there or you can wait for the doorbell to ring. When it rings (“an interrupt occurs”), you temporarily stop whatever you’re doing and check to see who is at the door (“execute the interrupt routine”). When you’re done answering the door (“servicing the interrupt”) you go back to whatever it is you were doing earlier.”

This seems to me to have wider implications for reducing CPU load – and so with my current Auduino blinking code for an LED array based on frames seizing things up when I run it in the loop() function I’ve been keeping my eyes open for solutions that might help – even though using interrupts is not actually recommended with the Auduino.

After some googling, searching in the Arduino: Forum, Arduino: Playground and freeduino.org and a bit of head scratching I found the simplest implementation advice for external interrupts in the Arduino Reference – attachInterrupt() – and have now replaced the digitalRead() entries for my MIDI and LDR switches in the loop() function with external interrupts (well not both since there are only two interrupt pins on the Duemilanove and the PWM generated from the audioOn() function needs to use one of them – but once I have my Mega I will) – with seemingly no ill effect on the Auduino’s behaviour. It didn’t help much with the blinking LEDs though… UPDATE The ‘seizing up’ actually turned out to be because the LED blinking code used a while loop –“will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false.”… and I’ve since replaced this.

There’s a thorough uC Hobby post on Arduino Interrupts that goes into some details about timer interrupts too…

Blinkin’ LED

I spent quite some time trying to find a solution for blinking a single LED as an indicator of mode number for my Auduino – i.e. blink once for mode one, five times for mode 5 etc. but over the same overall repeat cycle… and without interrupting other code by using delays… such as the standard ‘Blink’ example…

I found a couple of useful posts in the Arduino: Forum that went further than the ‘Blink without Delay’ example too – code for multiple LEDs not working using arrays, Multiple LEDs w/out delay with Potentiometer using the flip-book or frames technique with a more complex implementation of this in a post on james.n.murray’s intermediate.texts – an arduino.8.step.LED.sequencer.in.progress. After that it seems to head off into LED matrix land pretty quickly… of which there are plenty of nice examples on YouTube.

But these seem a bit over-engineered for my needs so in the end I managed to code my own – and here’s the relevant code for the button and LED…

// Button
#define BUTTON_PIN (7)  // the number of the pushbutton pin 
int buttonValue;        // variable for reading the button status
int buttonState;        // variable to hold the button state
int mapMode = 0;        // What mapping mode is in use?

// mapmode LED
#define mapModeLED_PIN (10)    // the number of the LED pin  
int mapModeLEDState = LOW;     // ledState used to set the LED
long previousMillis = 0;       // will store last time LED was updated
int BlinkRate = 5;            // no of blinks per second i.e. fps - empirically tested as just slow enough to count
int BlinkCount = 0;           // variable to store no of blinks
int BlinkLoopLength = 14;    // err... blink loop length

void setup() {
  pinMode(mapModeLED_PIN,OUTPUT);
  pinMode(BUTTON_PIN,INPUT);
}

void loop() {

// button presses cycle through mapping modes
  buttonValue = digitalRead(BUTTON_PIN);      // read input value and store it in val
  if (buttonValue != buttonState) {         // the button state has changed!
    if (buttonValue == 0) {                // check if the button is pressed
      if (mapMode == 0) {          // if set to smooth logarithmic mapping
        mapMode = 1;               // switch to stepped chromatic mapping
      } 
      else {
        if (mapMode == 1) {        // if stepped chromatic mapping
          mapMode = 2;             // switch to stepped major Diatonic mapping
        } 
        else {
          if (mapMode == 2) {      // if stepped major Diatonic mapping
            mapMode = 3;           // switch to stepped minor Diatonic mapping
          }
          else {
            if (mapMode == 3) {      // if stepped minor Diatonic mapping
              mapMode = 4;           // switch to stepped major Pentatonic mapping 
            }
            else {
              if (mapMode == 4) {      // if stepped major Pentatonic mapping 
                mapMode = 5;           // switch to stepped minor Pentatonic mapping 
              }
              else {
                if (mapMode == 5) {      // if stepped major Pentatonic mapping 
                  mapMode = 0;           // switch back to smooth logarithmic mapping
                }
              }
            }
          }
        }
      }
    }
    buttonState = buttonValue;                 // save the new state in our variable     
  }

// mapMode LED indicator - blinks number of mapping mode on a fixed ‘FPS’ cycle
  if (millis() - previousMillis > 1000/BlinkRate)
  {
    BlinkCount =  BlinkCount + 1;
    // save the last time you blinked the LED 
    previousMillis = millis();
    digitalWrite(mapModeLED_PIN, LOW);
    if (BlinkCount <= (mapMode+1)*2) // mapMode starts at 0 - and BlinkCount includes on AND off
    {
      //if the LED is off turn it on and vice-versa:
      if (mapModeLEDState == LOW) 
      {
        mapModeLEDState = HIGH;
      }
      else{
        mapModeLEDState = LOW;
      }
      // set the LED with the ledState of the variable:
      digitalWrite(mapModeLED_PIN, mapModeLEDState);
    }
    // resets after 14 blinks - this sets the overall loop cycle
    else if (BlinkCount >= BlinkLoopLength) 
    {
      BlinkCount = 0;   
    }
    //debug
    //Serial.println(BlinkCount);
  }
}

Tags: , , , ,

Comments are closed.