Arduino + lights = funny results

640 views
Skip to first unread message

sc_r

unread,
Sep 28, 2009, 12:24:22 PM9/28/09
to DmxSimple
Hi all, been following the group for a while - lots of interesting
stuff here!

I have built a prototype DMX shield following the circuit - built on a
breadboard - and am having some bizarre results.- I have tried using
the first DMX simple code example - the clean_code example.

I have connected two 'Stairville LED Par cans' - DMX info sheet here:
http://blog.ricohansen.dk/Attachments/Stairville%20LED%2056%20instruction%20manual.pdf

First of all.. should I be setting the lanterns to channel 1 and
channel 2 respectively, or should it be more like channel 1 and
channel 6 [each lantern needs 5 channels input]?

I've tried both ways..

Secondly, I'm getting weird results when I upload the clean_code to my
arduino [diecimilia] board - sometime the lanterns light up, sometimes
not, and the changes to code I am making don't appear to correlate in
any sensible way to how the lanterns are affected.

Weird. Forgive the n00bness but I feel like I've exhausted my
knowledge and thought I'd post up.

Thanks in advance -

s

Peter Knight

unread,
Sep 28, 2009, 12:44:02 PM9/28/09
to DmxSimple
The 512 channels are shared across the DMX chain. Setting a 5 channel
lamp to '1' uses channels 1,2,3,4 and 5. So the next lamp should start
at 6.

What is the "clean_code" example? Do you mean FadeUp, or are you
talking about something else?

Statistically, unpredictable behaviour in the library is most likely
to be one of these problems.
1) The DMX connections aren't right. Check you are signalling on all
the pins - that you haven't mixed up the ground and one of the data
lines, and the data lines aren't swapped. Check for dodgy solder
joints and broken wires too.
2) Is there an array in your code? Are you writing beyond its bounds?
Remember an array with 6 elements has them numbered 0..5, not 1..6.

I suggest you start with FadeUp on one lamp, and expand gradually.
Your lamp has 5 channels, so try something like this, with one lamp at
address 1 and the other at address 6:

#include <DmxSimple.h>

void setup() {
// Lamp 1
DmxSimple.write(1, 0); // RGB control
DmxSimple.write(5, 0); // No speed
// Lamp 2
DmxSimple.write(6, 0); // RGB control
DmxSimple.write(10, 0); // No speed
}

void loop() {
int brightness;
for (brightness = 0; brightness <= 255; brightness++) {
DmxSimple.write(2, brightness); // Red
DmxSimple.write(3, brightness); // Green
DmxSimple.write(4, brightness); // Blue
delay(10); // Wait 10ms
}
for (brightness = 0; brightness <= 255; brightness++) {
DmxSimple.write(7, brightness); // Red
DmxSimple.write(8, brightness); // Green
DmxSimple.write(9, brightness); // Blue
delay(10); // Wait 10ms
}
}


On Sep 28, 5:24 pm, sc_r <stuchi...@googlemail.com> wrote:
> Hi all, been following the group for a while - lots of interesting
> stuff here!
>
> I have built a prototype DMX shield following the circuit - built on a
> breadboard - and am having some bizarre results.- I have tried using
> the first DMX simple code example - the clean_code example.
>
> I have connected two 'Stairville LED Par cans' - DMX info sheet here:http://blog.ricohansen.dk/Attachments/Stairville%20LED%2056%20instruc...

sc_r

unread,
Sep 28, 2009, 1:56:16 PM9/28/09
to DmxSimple
Hi Peter,

wow, fast response!

OK, the 'clean_code' example I've been using is here:
http://www.arduino.cc/playground/DMX/Examples

Here is an example of the code i've been trying:
"


/* DMX Shift Out for arduino - 004 and 005
* -------------
*
* Shifts data in DMX format out to DMX enabled devices
* it is extremely restrictive in terms of timing. Therefore
* the program will stop the interrupts when sending data
*
* The elektronic foundation for DMX is RS 485, so you have to use
* a MAX-485 or a 75176.
*
* wirring for sending dmx with a MAX-485

1 - RO - Receiver Output --- set to ground with a 100 ohm
resistor
2 - RE - Receiver Output Enable -- set to ground
3 - DE - Driver Output Enable -- set to 5v
4 - DI - Driver Input -- Input from Arduino
5 - GnD - Ground Connection -- set to ground -- refence for the
DMX singal --- (DMX pin 1)
6 - A - Driver Output / Receiver Input -- DMX Signal
(hot)------------------ (DMX pin 3)
7 - B - Driver Output / Receiver Input -- DMX Signal inversion
( cold)------ (DMX pin 2)
8 - Vcc - Positive Supply -- 4,75V < Vcc < 5,25V

* Every dmx packet contains 512 bytes of information (for 512
channels).
* The start of each packet is market by a start byte (shiftDmxOut(sig,
0);),
* you should always send all 512 bytes even if you don*t use all 512
channels.
* The time between every dmx packet is market by a break
* between 88us and 1s ( digitalWrite(sig, LOW); delay(10);)
*
* (cleft) 2006 by Tomek Ness and D. Cuartielles
* K3 - School of Arts and Communication
* fhp - University of Applied Sciences
* <http://www.arduino.cc>
* <http://www.mah.se/k3>
* <http://www.design.fh-potsdam.de>
*
* @date: 2006-09-30
* @idea: Tomek Ness
* @code: D. Cuartielles and Tomek Ness
* @acknowledgements: Johny Lowgren for his DMX devices
*
*/

#include "pins_arduino.h"

int sig = 11;

int count = 0;
int swing = 0;
int updown = 0;


/* Sends a DMX byte out on a pin. Assumes a 16 MHz clock.
* Disables interrupts, which will disrupt the millis() function if
used
* too frequently. */


void shiftDmxOut(int pin, int theByte)
{
int port_to_output[] = {
NOT_A_PORT,
NOT_A_PORT,
_SFR_IO_ADDR(PORTB),
_SFR_IO_ADDR(PORTC),
_SFR_IO_ADDR(PORTD)
};

int wasteTime = 0;
int theDelay = 1;
int count = 0;
int portNumber = port_to_output[digitalPinToPort(pin)];
int pinNumber = digitalPinToPort(pin);

// the first thing we do is to write te pin to high
// it will be the mark between bytes. It may be also
// high from before
_SFR_BYTE(_SFR_IO8(portNumber)) |= _BV(pinNumber);
delayMicroseconds(10);

// disable interrupts, otherwise the timer 0 overflow interrupt
that
// tracks milliseconds will make us delay longer than we want.
cli();

// DMX starts with a start-bit that must always be zero
_SFR_BYTE(_SFR_IO8(portNumber)) &= ~_BV(pinNumber);
//we need a delay of 4us (then one bit is transfert)
// at the arduino just the delay for 1us is precise every
thing between 2 and 12 is jsut luke
// to get excatly 4us we have do delay 1us 4 times
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);

for (count = 0; count < 8; count++) {

if (theByte & 01) {
_SFR_BYTE(_SFR_IO8(portNumber)) |= _BV(pinNumber);
}
else {
_SFR_BYTE(_SFR_IO8(portNumber)) &= ~_BV(pinNumber);
}

delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
// to write every bit exactly 4 microseconds, we have to
waste some time here.
//thats why we are doing a for loop with nothing to do,
a delayMicroseonds is not smal enough
for (wasteTime =0; wasteTime <2; wasteTime++) {}


theByte>>=1;
}

// the last thing we do is to write the pin to high
// it will be the mark between bytes. (this break is have to be
between 8 us and 1 sec)
_SFR_BYTE(_SFR_IO8(portNumber)) |= _BV(pinNumber);

// reenable interrupts.
sei();
}

void setup() {
pinMode(sig, OUTPUT);
digitalWrite(13, HIGH);
}

void loop() {

// sending the break (the break can be between 88us and 1sec)
digitalWrite(sig, LOW);
delay(100);

//sending the start byte
shiftDmxOut(sig, 0);

shiftDmxOut(sig, 20); //1
shiftDmxOut(sig, 100); //2
shiftDmxOut(sig, 55); //3
shiftDmxOut(sig, 0); //4
shiftDmxOut(sig, 0); //5


shiftDmxOut(sig, 200); //6
shiftDmxOut(sig, 4); //7
shiftDmxOut(sig, 100); //8
shiftDmxOut(sig, 0); //9
shiftDmxOut(sig, 0); //10



for (count = 1; count<=504; count++){ //the rest
shiftDmxOut(sig, 0);
}
}

"
Now I realise that this is not DMXsimple code - but related to the DIY
shield. I want to get DMXSimple working but..

I recently installed Arduino 17 and now there doesn't seem to be an
install folder, just an executable.

Not sure where I should be putting the DMXSimple libraries?

Really appreciate the help - it's starting to make a bit more sense
now. Once I make sense of controlling one lantern, I'm hoping to
connect up 32 of them. I figure once 1 is sorted, it's applicable to
all the others.

Have checked out all of the wires + connections, they seem to be fine.
Will get a mate to make up a circuit too to double check.

Thanks again - all help fully appreciated, it's been frustrating the
heck out of me but starting to click together.

s :)

Peter Knight

unread,
Sep 28, 2009, 3:46:02 PM9/28/09
to DmxSimple
Ahh...

Okay - first things first. Forget that code. Use DmxSimple. Really.
DmxSimple is much less dependent on the Arduino function calls, so it
doesn't break with new Arduino versions or boards. It produces much
more accurate signal timings, and it sends DMX frames in the
background so you don't have to worry about sending out channels in
the right order. Oh - and having known working examples on tap makes
debugging an awful lot easier.

I presume you're on a Mac. The libraries folder has moved to:
Documents/Arduino/libraries. You might need to create the libraries
folder. Then copy the DmxSimple directory inside, and restart the
Arduino software.

DmxSimple defaults to outputting on pin 3. You're currently using pin
11. So either swap the pin over, or add: DmxSimple.usePin(11); as the
first line of the setup() function. Whichever is easier.

Let us know how it goes!


Peter

On Sep 28, 6:56 pm, sc_r <stuchi...@googlemail.com> wrote:
> Hi Peter,
>
...

sc_r

unread,
Sep 28, 2009, 6:41:15 PM9/28/09
to DmxSimple
Grand - got FadeUp working on two lanterns - thank you.

Got it in one with the mac - it was the fact that libraries folder
wasn't there that caused me the problem. Made that, DMSSimple in there
and we're away.

Now to play with some more code - will keep all updated :)

On Sep 28, 5:44 pm, Peter Knight <cathed...@gmail.com> wrote:

sc_r

unread,
Sep 29, 2009, 11:27:01 AM9/29/09
to DmxSimple
Progress today - got each lantern working independently now.

I had an issue with the delay function in the code:

"
delay(10); // Wait 10ms

"

when this was in between the RGB values for each lantern, only the
first one responded.

SO, I changed the code to the following:

"
#include <DmxSimple.h>

void setup() {
// Lamp 1
DmxSimple.write(1, 0); // RGB control
DmxSimple.write(5, 99); // No speed
// Lamp 2
DmxSimple.write(6, 0); // RGB control
DmxSimple.write(10, 99); // No speed

}

void loop() {
int brightness;
for (brightness = 0; brightness <= 255; ) {
DmxSimple.write(2, 0); // Red
DmxSimple.write(3, 0); // Green
DmxSimple.write(4, 255); // Blue
DmxSimple.write(7, 255); // Red
DmxSimple.write(8, 255); // Green
DmxSimple.write(9, 255); // Blue
delay(20); // Wait 10ms
}

// for (brightness = 0; brightness <= 255; )
// {

// delay(20); // Wait 10ms
// }

}

"

Now both lanterns are working independently of each other.

I am curious what the " for (brightness = 0; brightness <= 255; ) "
code does though.

Going to connect up a few more lanterns now and see how many I can get
working. I am assuming - as the DMXSimple is limited to 128 values (?)
that I should be able to get 25 different lanterns rigged - each using
5 channels.

I found this handy widget for mac that helps to calculate the dip
switch settings: http://www.apple.com/downloads/dashboard/reference/dmxwidget.html

lovely

Peter Knight

unread,
Sep 29, 2009, 11:45:01 AM9/29/09
to DmxSimple
I didn't say:
for (brightness = 0; brightness <= 255; )

I said:
for (brightness = 0; brightness <= 255; brightness++)

Try that in the original code I gave you above and you'll find it
works much better.


On Sep 29, 4:27 pm, sc_r <stuchi...@googlemail.com> wrote:
> ...
>   for (brightness = 0; brightness <= 255; ) {
> ...

sc_r

unread,
Sep 29, 2009, 11:55:35 AM9/29/09
to DmxSimple
Aha!

I forgot I cut that code out last night to stop the fading.

Makes more sense now. Tried
"
for (brightness = 255; brightness >= 0; brightness--)
"
to make it fade down, and it works. Cheers Peter

Peter Knight

unread,
Sep 29, 2009, 3:45:40 PM9/29/09
to DmxSimple
On Sep 29, 4:27 pm, sc_r <stuchi...@googlemail.com> wrote:
> I am assuming - as the DMXSimple is limited to 128 values (?)
> that I should be able to get 25 different lanterns rigged - each using
> 5 channels.

There is one DmxSimple limitation:
If you're running on an old 1K RAM Arduinos (168 or Mega8), you are
restricted to 128 channels due to the lack of internal RAM. You can
change that in the library if you wish, but swapping out the chip for
an ATmega328 will give you all 512 channels and much more RAM to play
with for only a few pounds.


The other limitations are due to DMX itself, not DmxSimple:

DMX is limited to daisy-chaining 32 devices. If that's not enough, DMX
splitters work as repeaters - they count as 1 device on the input, but
can drive 32 on each output. That way you can extend as much as you
like.

As you have 512 channels, you can independently control 512 / 5 = 102
of your lamps independently - although from a quick scan of your lamp
data sheet, it doesn't look like you can access the higher channel
numbers from the DIP switches. Of course, nothing stops you setting
two lamps to the same channel number if you don't mind them doing the
same thing.


If you need over 512 independent channels, the usual solution is to
run a second DMX network. Another Arduino will to the trick nicely.
Reply all
Reply to author
Forward
0 new messages