May 16&17 18h-20h: Bâtiment d’art contemporain, 28 rue des Bains, 1205 Genève
Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It’s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.
This workshop will introduce the Arduino platform as a controller for LED lighting. We will look at DMX control for large scale lighting, and also smaller scale projects with multiple LEDs. Libraries exist for each of these options, making it more accessible to novice users.
On the first day,after a quick introduction to the Arduino, we will use commonly available ICs like the Texas Instruments TLC5940 for fine, granular control of lights, and Maxim’s MAX7219 and MAX7221 for controlling LED arrays.
On the second day, we will look at the forthcoming DMX library for the Arduino, and experiment with controlling larger lighting arrangements with sensors and other inputs.
For much more information, check out ITP’s Physical Computing site
Workshop Summary
Introduction to the Arduino.
Installing the software and getting set up.
‘Hello world’
Wire up an LED to blink.
Code
int ledPin = 12; // LED connected to digital pin 12 void setup() // run once, when the sketch starts { pinMode(ledPin, OUTPUT); // sets the digital pin as output } void loop() // run over and over again { digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off delay(1000); // waits for a second }
Wiring
- Wired TLC5940
- Hello World Overhead view
- Close up of the breadboard
‘Analog’ fading of an LED
Using PWM, we change the perceived brightness of an LED.
Code
int value = 0; //variable to keep the value int ledpin = 11; //PIN 11 has eh LED void setup() //do this once { pinMode(ledpin, OUTPUT); //turn the pin into an output } void loop() //do this repeatedly { for(value = 0 ; value <= 255; value++) //fade in (from miin to max) { //increase the value from 0 to 255 analogWrite(ledpin, value); //sets the brightness // delay(33); //wait for 33 msec } for(value = 255; value >=0; value--) //fade out (from max to min) { //decrease the value from 255 to 0 analogWrite(ledpin, value); //sets the brightness // delay(33); //wait for 33 msec } }
Wiring
We use the same setup as above, but we move wired from pin 12 to pin 11.
Using the TLC5940
The TLC5940 is a 16 channel constant current sink driver. This chip allows us to control 16 LEDs with 4096 unique levels of brightness. you can cascade ships as well to get more LEDs.
First, we need to install the TLC5940 Library. If you need to, read more about libraries here. You can download the most recent version of the TLC library here. (NB : you must be using an Arduino Diecimila or later with this library).
Code
/*This sketch does a strobe across a line of LEDs. adapted from code by Alex Leone acleone ~AT~ gmail.com*/ #include <Tlc5940.h> //import the TLC library void setup() //do this once { Tlc.init(); //Call Tlc.init() to setup the tlc. } void loop() //do this over and over { int direction = 1; //sets direction for (int channel = 0; channel < NUM_TLCS * 16; channel += direction) { //for each led Tlc.clear(); //clear the value, but do not update it // the code below sets one led to 1/2 brightness // and the ones around it to 1/4 brightness // and the ones next to that less //and the following even less //like this :: 0 0 0 0 100 250 1000 2047 1000 250 100 0 0 0 0 0 if (channel == 0) { direction = 1; } else { Tlc.set(channel - 1, 1000); //LED below the bright one Tlc.set(channel - 2, 250); Tlc.set(channel - 3, 100); } Tlc.set(channel, 2047); //the bright LED if (channel != NUM_TLCS * 16 - 1) { Tlc.set(channel + 1, 1000); //the next LED Tlc.set(channel + 2, 250); Tlc.set(channel + 3, 100); } else { direction = -1; } Tlc.update(); //TLC.update is what changes the lights values. //We need to call this every time we want the lights to change delay(33); //let's wait for a momnet so it doesnt go too fast } }
Wiring
Communicating Serially with the TLC
Using a multimedia computer, we can send complex images to the TLC. The arduino code for communicating with 3 TLCs serially looks like this :
#include <Tlc5940.h> #define MSG_HEADER 255 #define MSG_LEN 49 unsigned int PWMData[]= { 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250, 0,250,0,250}; void setup() { Serial.begin(57600); Tlc.init(4); } void readSerial() { boolean gotMsg = false; if(Serial.available() && (Serial.read()==MSG_HEADER)) { while(Serial.available()<MSG_LEN); for(int i=0;i<MSG_LEN-1;i++){ PWMData[i]=Serial.read(); gotMsg=true; } } if (gotMsg==true){ DoTLC(); } else{ Serial.flush(); } } void DoTLC(){ for(int i =0;i<MSG_LEN-1;i++){ int LEDval=PWMData[i]*4; Tlc.set(i, LEDval); } } void loop() { readSerial(); Tlc.update(); delay(10); }
I use Cycling ’74‘s authoring environment Max to send quicktime movies or generated video to the LEDs.
Below is Max5 code for connecting with an arduino and TLCs
----------begin_max5_patcher----------
1629.3oc0Z00bahCE8YmeEL7rSFDhO2mZ1syr6KclNS2YeoSmLxfpiZAjKHm
j1N8+9Jj.rvAgEXG6zGhHHIPGcz8dz8J7OuZg8J5S3Jaq+v5iVKV7yqVrPTU
cEKZtegcN5ojLTkna143pJzZr8RYaL7SLQ8aJIEr1ZK1lS2xxvLwy.ZpcChk
bOoX8ck3DlbL8bbtwYokq7BzqtDDdii0mZdF4qg88MX4CXa20DIULvzUe45n
1A9yzBVAJWzY6+CWlhJPpsUQ9gnMP830gURQKTcagZItBWvPLBsPAttgPAb8
EWbZJr9T8C8qqtptXog7XA9QNxeFMlQQoqPEqmKSBB8qu3GHtIdLlTLLCwlA
mJ1DLCdQm8EcCtXxjRKaHst7mo0E7jYcMG6js4qvkCOyasVYkjpDTlXrctId
D9nwHwUgVbcFiPDN0iXq3NrwxskDT1fTC3F+XePT3oxdQiezWHranardC+uq
sdyCnLKv3b3.rETRVRZB3DcXWJ9ndWNhub7TMoMHg4cIMlz4bkjQqvS26R0L
BFLSuqvKp2kdqmuwtYcIZkEHvBNSSmXQYT3Iwvw8RpJqgm3aSxkkS4aH5OYq
GIE45ItD5cXNZPVAbIYEFc85L7Lm4vN0WSzfGbtqJo8hr99sbLqjZAgybN5K
DHBfGQvH.mWo5CDltskgGbKEovfmAAoIjCzJID9JTS3GYVqKoa2X4EMSYSWf
zrIzP5YPpw+RZ1rZKiQmc3pMYCIYg5xY31.8sOSZ+ankr4NSatDDOyXGbmbn
4wu76IZkhefjvypdpjhKTDhoaT7NsywM+SxvnxgW+OcRCp.lK4IIjFFg+JHY
3GvkU7DkU58B6cSqfPgirmXKdXDPNG81Mu3D85LZxWwB36zVYJ9yS5kTmg3t
GvQMC8lzzU6IoPMG+8GXz1L1cCyN8a+ynDr1GVCsuvdcIIkVHRoU8Yqqtc.4
lCRw.eUjK5QAZy.OLiRyVgJefTQVISErasfaGiJH73KwLhDQbIl1FI4xitQ8
c06TgTVs64Szq9w7M56ev2afgUUMzuEgNGkl3piGNxQC1oPWTjGxgYDmFMZJ
KZ0Uj+yxSOexrjp.ZISv3jIHRxf.wEOGyny9JO5xU42Q9rceMzl5KylVk1n.
nLHF.vPqTcLJ72XFUIR4YyiRqSW+ijF8esSih25rIq.oOr+vgONQtJvV2DVk
IRn44X41G11mPhPhS8LgiQlMAtiPECbHTZC+wn45t8oyHE51.U.151GlDpna
KSZWaZ1axpOtSwULRQWbKerSycu9cOIMsePBBVljtgx2vuAdxOdwAWzlJpcM
D0gupPM72RT6aHpgupPso109upPcfgnFbBQcSkb3KyDqB8.N8N9nvU6tCwXk
jU7Ppq1OyrQSSYzzSLKGlL5JTVSVgc8x1zjnzhJ0Ne0Nl3D8kNpy6v5CL7l6
4YDgu9Oy1h4INwt+52+1auFL6SroIvjP249IFiujGW0V9tZaG+rLWsNglQKc
al1hooZQ2jBUVReTz217vccW1qTs25OEDHLVdVXfCeLHMejR8eystEVA5ZlK
s3KJXYuRU7M5pQIugduI+kJEpuFFs+P5K6TWoZeSIU85qGbYuR091alLxhhF
CGAavE+9ppUdMu1oFM1ABwCqOuoi1+8+9Nq+4Cu882Z8W7gpjlUuVrrtXWK2
tYy.09VBZ8.U+NZJNuq99toe36EIcMwAF45m2tP.V1izbFN49m0Gkdrqo9Cq
dcBUCXVYN+oNwmhXEt9KnasxxOLvwYxGjdqtTf3Rjq49PCdLqWzu8X8GaYyi
jhT5iy3CJn9Cd.3E19yLZFeRgCeh5hmper+xI39QYzLMeVzEQpQMnKN+dgV+
7vJ1OjBOm3Z4HWe4IQD40cmle2RlB1.C.azzv5QhHWeCfD37BoPSVR8OqXxy
DHEdVgD3EvvGJs6CUOIf8tK.n5SD.NZeBWnASj5f8r.lOQZvGHNPFXTX2cGq
g.nGPzP6vIR67327q+8.Eqvz8uCDpx6h6NK79Dcy53cXKZcZt6HQKz2TqjIh
VwGOumNO3304glHg4clkUcMvxEdd0v1aA6zHhcr5plHrV+Sr4bt1YRfCdSSh
7XoIGSV5NqrT3oGQ.nPSHTlecb6+erKmFtZdFcDeAntnKE04Omfd.f.wdvN6
tqGT427qq9ePnlgAe
-----------end_max5_patcher-----------
I have also done some work with OpenFrameworks and communicating with the TLC. You can download examples here.
DMX
DMX is a lighting control protocol. It is robust and flexible. There are a number of products available on the market for controlling DMX over USB (most notably the ENTEC DMXUSBPro and Open USB DMX boxes). Hwever, the Arduino can send DMX as well. We only need an external IC (We used the MAX485 from Maxim) a 100k resistor and some wires. Oh, also, we will need the SimpleDMX library from here.
It is best to follow these instructions for wiring the 485 and hooking up your female DMX adapter.
Connect Arduino Pin 3 to Pin 4 on the 485.
Figure out what channels your fixtures need to send data to them. The ones we were using had 6 channels per fixture : Red, Green, Blue, Strobe, Rainbow, and Dimmer. In order to see anything turn on, we needed to give the dimmer a value of 255 (full brightness).
Code
#include <DmxSimple.h> void setup() { DmxSimple.maxChannel(6); // Talking to a six channel receiver, so send all six channels. DmxSimple.write(5, 0); // Set Channel 5 (Rainbow) to 0 DmxSimple.write(4, 0); // Set Channel 4 (Strobe) to 0 DmxSimple.write(6, 255); // Set Channel 6 (Dimmer) to 255 (full brightness) } void loop() { int brightness; for (brightness = 0; brightness <= 255; brightness++) { DmxSimple.write(1, brightness); // Set channel 1 (Red) to new value DmxSimple.write(2, 0); // Set channel 2 (blue) to 0 DmxSimple.write(3, 255-brightness); // Set channel 3 (green) to the opposite of channel1 delay(50); // Wait 50ms } }



