Commits

Christopher De Vries  committed d7eccd8

Added developer shield support, a color designer that uses the developer shield, the blinky example, and a sketch to control the arduino through a serial connection.

  • Participants
  • Parent commits 7fe306a
  • Tags 1.2

Comments (0)

Files changed (9)

 
 TCL.sendEmptyFrame();
 
+Developer Shield
+----------------
+Cool Neon also sells a developer shield which is a very useful add-on to using
+Total Control Lighting with an Arduino. The shield includes a +5V DC power
+input cable with a 2.1mm jack, compatible with the wall-wart power supplies
+Cool Neon sells (which will power the Arduino as well as the lights). There is
+also a female total control lighting output, which can connect directly to the
+total control lighting pixel strands. What makes the shield special is it also
+comes with four potentiometers, two momentary buttons, and two switches which
+can be configured as inputs to the Arduino. 
+
+If you hold the developer shield so that the two-position switches are at the
+top and the potentiometers are at the bottom, then going clockwise from
+upper-left the potentiometers connect to analog input pins 0, 1, 2, and 3. The
+momentary switches, moving from bottom to top connect to digital pins 4 and 5,
+and the two-position switches from bottom to top connect to digital pins 6 and
+7. When closed, the switches connect the pin to ground, so you should
+configure them to use the internal pull-up resistors. The total control
+library configures the inputs correctly if you issue the command:
+
+TCL.setupDeveloperShield();
+
+There are also defined aliases for each input device:
+
+TCL_POT1       : Potentiometer 1
+TCL_POT2       : Potentiometer 2
+TCL_POT3       : Potentiometer 3
+TCL_POT4       : Potentiometer 4
+TCL_MOMENTARY1 : Button 1
+TCL_MOMENTARY2 : Button 2
+TCL_SWITCH1    : Two-position Switch 1
+TCL_SWITCH2    : Two-position Switch 2
+
+So, for example to read the state of button 1 I would issue the command:
+
+state = digitalRead(TCL_MOMENTARY1);
+
+It would return state==HIGH if the button was open (not being pressed) and
+state==LOW if the button was closed (being pressed). 
+
+Example Code
+------------
+Several examples are loaded into the Arduino examples menu under "TCL." These
+examples include the following:
+
+blinky - A sketch that causes the lights to blink at slightly randomized times
+in random colors. 
+
+color_designer - A sketch that lets you use to the developer shield
+potentiometers to search for colors. The colors will cascade down the lighting
+strand as you turn the first three potentiometers. The first one adjusts the
+amount of red, the second the amount of green, and the third the amount of
+blue. If you find a color you like just hit the first momentary button and it
+will send the appropriate "sendColor" command over the serial port so you can
+add it to your own code. Be sure to use the serial monitor set to 9600 bps in
+order to use this feature.
+
+fire - A sketch that shows flickering with random colors (between yellow and
+red) and random intensity meant to simulate fire.
+
+rainbow - A static red,orange,yellow,green,blue repeating sequence sent onto
+the strand.
+
+serialcontrol - A sketch which allows for direct control of the total control
+lighting pixels from a computer over a serial connection to the arduino. It
+uses a simple ASCII based protocol. This sketch is used by the PixelPainter
+application and a little more information about it can be found in the
+comments within the sketch.
+
+Revision History
+----------------
+January 2, 2012 - Version 1.2 - Added support for the Cool Neon developer
+shield as well as a color designer in the example code and a sketch that
+allows for control of pixels over a serial line to the computer.
+
+December 11, 2011 - Version 1.1 - Library was updated to work on the Version
+1.0 Arduino IDE.
+
+August 16, 2011 - Version 1.0 - Library works using the Arduino SPI library to
+control generation 1 total control lighting strands on pre-Arduino 1.0 IDE.
+
 /*****************************************************************************
  * Tcl.cpp
  *
- * Copyright 2011 Christpher De Vries
+ * Copyright 2011-2012 Christpher De Vries
  * This program is distributed under the Artistic License 2.0, a copy of which
  * is included in the file LICENSE.txt
  ****************************************************************************/
   SPI.setClockDivider(SPI_CLOCK_DIV2);
 }
 
+void TclClass::setupDeveloperShield() {
+  pinMode(TCL_MOMENTARY1, INPUT);
+  pinMode(TCL_MOMENTARY2, INPUT);
+  pinMode(TCL_SWITCH1, INPUT);
+  pinMode(TCL_SWITCH2, INPUT);
+
+  digitalWrite(TCL_MOMENTARY1, HIGH);
+  digitalWrite(TCL_MOMENTARY2, HIGH);
+  digitalWrite(TCL_SWITCH1, HIGH);
+  digitalWrite(TCL_SWITCH2, HIGH);
+}
+
 void TclClass::end() {
   SPI.end();
 }
 }
 
 void TclClass::sendColor(byte red, byte green, byte blue) {
-  byte flag = makeFlag(red,green,blue);
+  byte flag;
+
+  flag = makeFlag(red,green,blue);
 
   sendFrame(flag,red,green,blue);
 }
 /*****************************************************************************
  * TCL.h
  *
- * Copyright 2011 Christpher De Vries
+ * Copyright 2011-2012 Christpher De Vries
  * This program is distributed under the Artistic License 2.0, a copy of which
  * is included in the file LICENSE.txt
  ****************************************************************************/
 #endif
 #include "SPI.h"
 
+#define TCL_POT1 A0
+#define TCL_POT2 A1
+#define TCL_POT3 A2
+#define TCL_POT4 A3
+#define TCL_MOMENTARY1 4
+#define TCL_MOMENTARY2 5
+#define TCL_SWITCH1 6
+#define TCL_SWITCH2 7
+
 class TclClass {
   public:
     static void begin();
+    static void setupDeveloperShield();
     static void end();
     static void sendFrame(byte flag, byte red, byte green, byte blue);
     static void sendColor(byte red, byte green, byte blue);
 <project name="arduino-tcl" default="zip" basedir=".">
 
   <target name="init">
-    <property name="version" value="1.1"/>
+    <property name="version" value="1.2"/>
     <property name="zipname" value="arduino-TCL-${version}.zip"/>
   </target>
 

File examples/blinky/blinky.ino

+/*****************************************************************************
+ * blinky.ino
+ *
+ * An example total control lighting script which causes each pixel to blink
+ * on and off in slightly randomized simes around 1 second on and 1 second
+ * off and in a color randomly selected from red, orange, yellow, green, and
+ * blue. 
+ *
+ * Copyright 2012 Christopher De Vries
+ * This program is distributed under the Artistic License 2.0, a copy of which
+ * is included in the file LICENSE.txt along with this library.
+ ****************************************************************************/
+#include <SPI.h>
+#include <TCL.h>
+
+const int LEDS = 100;
+const int COLORS = 6;
+const int BLACK = 0;
+const int RED = 1;
+const int ORANGE = 2;
+const int YELLOW = 3;
+const int GREEN = 4;
+const int BLUE = 5;
+
+byte color_values[COLORS][3];
+long change_time[LEDS];
+int current_color[LEDS];
+
+void setup() {
+  int i;
+  unsigned long time;
+  
+  TCL.begin();
+  
+  color_values[BLACK][0] = 0x00;
+  color_values[BLACK][1] = 0x00;
+  color_values[BLACK][2] = 0x00;
+  
+  color_values[RED][0]=0xff;
+  color_values[RED][1]=0x00;
+  color_values[RED][2]=0x00;
+  
+  color_values[ORANGE][0]=0xff;
+  color_values[ORANGE][1]=0x60;
+  color_values[ORANGE][2]=0x00;
+  
+  color_values[YELLOW][0]=0xff;
+  color_values[YELLOW][1]=0xb0;
+  color_values[YELLOW][2]=0x00;
+  
+  color_values[GREEN][0]=0x00;
+  color_values[GREEN][1]=0x80;
+  color_values[GREEN][2]=0x00;
+  
+  color_values[BLUE][0]=0x00;
+  color_values[BLUE][1]=0x00;
+  color_values[BLUE][2]=0xff;
+
+  time = millis();
+  for(i=0;i<LEDS;i++) {
+    change_time[i] = time+random(700,1300);
+    current_color[i]=BLACK;
+  }
+  update_strand();
+}
+
+void loop() {
+  int i;
+  unsigned long time;
+  
+  time=millis();
+  
+  for(i=0;i<LEDS;i++) {
+    if(change_time[i]<time) {
+      change_time[i]=time+random(700,1300);
+      if(current_color[i]==BLACK) {
+        current_color[i]=random(1,COLORS);
+      }
+      else {
+        current_color[i]=BLACK;
+      }
+    }
+  }
+  update_strand();
+}
+
+void update_strand() {
+  int i;
+  int color;
+  
+  TCL.sendEmptyFrame();
+  for(i=0;i<LEDS;i++) {
+    color = current_color[i];
+    TCL.sendColor(color_values[color][0],color_values[color][1],color_values[color][2]);
+  }
+  TCL.sendEmptyFrame();
+}

File examples/color_designer/color_designer.ino

+/*****************************************************************************
+ * color_designer.ino
+ *
+ * This sketch will allow you to use the potentiometers on the Total Control
+ * Lighting Developer Shield to adjust the colors of the LEDs and select an
+ * appropriate color. Push the first button to send the command which
+ * generates this color back over the serial port. The colors will cascade
+ * the lighting strand as you adjust the potentiometers. Be sure to open the
+ * serial monitor to see the color information on your computer.
+ *
+ * Copyright 2011-2012 Christopher De Vries
+ * This program is distributed under the Artistic License 2.0, a copy of which
+ * is included in the file LICENSE.txt along with this library.
+ ****************************************************************************/
+#include <SPI.h>
+#include <TCL.h>
+
+const int LEDS = 100; // This assumes that there are 100 LEDs in the TCL strand.
+const int update_interval = 100; // Milliseconds between color updates
+
+/* Current values for the pixels are stored in the following three arrays */
+byte red_values[LEDS];
+byte green_values[LEDS];
+byte blue_values[LEDS];
+
+
+
+void setup() {
+  int i;
+
+  TCL.begin(); // Begin protocol for communicating with the TCL strand
+  TCL.setupDeveloperShield(); // Set up developer shield for inputs
+  Serial.begin(9600); // Start serial communication at 9600 baud
+
+  /* Start by initializing all pixels to black */
+  for(i=0;i<LEDS;i++) {
+    red_values[i]=0;
+    green_values[i]=0;
+    blue_values[i]=0;
+  }
+
+  update_strand(); // Send the black pixels to the strand to turn off all LEDs.
+}
+
+void loop() {
+  int i; // A variable for looping
+  static long nextupdate=0l; // Time when next update of colors should occur.
+  static boolean sent_color=false; // Have I printed out the color to serial?
+  long time = millis(); // Current time in milliseconds
+
+  /* Check if the strand should be updated */
+  if(time>nextupdate) {
+    /* Move colors down the line by one */
+    for(i=LEDS-1;i>0;i--) {
+      red_values[i]=red_values[i-1];
+      green_values[i]=green_values[i-1];
+      blue_values[i]=blue_values[i-1];
+    }
+    /* Read the current red value from potentiometer 1
+     * Values are 10 bit and must be left shifted by 2 in order to fit in 8
+     * bits */
+    red_values[0]=analogRead(TCL_POT1)>>2;
+    
+    /* Read the current green value from potentiometer 2 */
+    green_values[0]=analogRead(TCL_POT2)>>2;
+
+    /* Read the current blue value from potentiometer 3 */
+    blue_values[0]=analogRead(TCL_POT3)>>2;
+
+    update_strand(); // Send all the pixels out
+    nextupdate=time+update_interval; // Set the time of the next update
+  }
+
+  /* Check if the button is pressed and if we have to send a color choice to serial */
+  if(digitalRead(TCL_MOMENTARY1)==LOW) { // The button is active (closed)
+    if(sent_color) {
+      // Do nothig. We already sent this one
+    }
+    else {
+      sent_color=true; // Send the message only one time per button press.
+      Serial.print("TCL.sendColor(0x");
+      Serial.print(red_values[0],HEX);
+      Serial.print(",0x");
+      Serial.print(green_values[0],HEX);
+      Serial.print(",0x");
+      Serial.print(blue_values[0],HEX);
+      Serial.println(")");
+    }
+  }
+  else { // The button is open
+    sent_color=false;
+  }
+}
+
+void update_strand() {
+  int i;
+
+  TCL.sendEmptyFrame();
+  for(i=0;i<LEDS;i++) {
+    TCL.sendColor(red_values[i],green_values[i],blue_values[i]);
+  }
+  TCL.sendEmptyFrame();
+}

File examples/fire/fire.ino

 #include <SPI.h>
 #include <TCL.h>
 
-const int LEDS = 25; // There are 25 LEDs in the Total Control Lighting Strand
+const int LEDS = 100; // There are 100 LEDs in the Total Control Lighting Strand
 byte color1[] = {0xff, 0x00, 0x00};
 byte color2[] = {0xff, 0x90, 0x00};
 

File examples/rainbow/rainbow.ino

 #include <SPI.h>
 #include <TCL.h>
 
-const int LEDS = 25; // There are 25 LEDs in the Total Control Lighting Strand
+const int LEDS = 100; // There are 100 LEDs in the Total Control Lighting Strand
 const byte red[] = {0xff, 0xff, 0xff, 0x00, 0x00};
 const byte green[] = {0x00, 0x60, 0xb0, 0x80, 0x00};
 const byte blue[] = {0x00, 0x00, 0x00, 0x00, 0xff};

File examples/serialcontrol/serialcontrol.ino

+/*****************************************************************************
+ * serialcontrol.ino
+ *
+ * This code reads commands from the serial port at 115200 bps and controls an
+ * arbitraty number of total control lighting pixels. There are two commands.
+ * The commands are described below.
+ *
+ * CHECK
+ * When receiving the command "CHECK" followed by a newline, the program
+ * responds by sending "CONNECT" followed by a newline. This is meant to
+ * check for an established connection. Occasionally there is some noise when
+ * a program first connects and you may need to resend "CHECK"
+ *
+ * DATA [n]
+ * The command "DATA" is followed by an integer and a newline. The integer
+ * indicates how many triplets of RGB color data follow. Each color is sent as
+ * a single byte, so each triplet is three bytes. The program will then enter
+ * a loop to read 3n bytes of data. It will send a blank frame to the pixels,
+ * send the RGB data to the pixels, and then send another blank frame after
+ * reading all n triplets. 
+ *
+ * The commands are sent in ASCII and the integer in decimal. The bytes are
+ * sent in binary red, green, then blue. The maximum command length (excluding
+ * bytes, which are of a fixed and known length) is 128 bytes of ASCII. 
+ *
+ * Copyright 2011-2012 Christopher De Vries
+ * This program is distributed under the Artistic License 2.0, a copy of which
+ * is included in the file LICENSE.txt along with this library.
+ ****************************************************************************/
+#include <SPI.h>
+#include <TCL.h>
+
+char incomingBuffer[128];
+int bufPosition;
+
+void setup() {
+  Serial.begin(115200);
+  TCL.begin();
+}
+
+void loop() {
+  int inbyte;
+  String inputCommand;
+  String color_frames_string;
+  char color_frames_chararray[6];
+  byte red, green, blue;
+  int color_frames;
+  int i;
+  
+  if(Serial.available()>0) {
+    inbyte = Serial.read();
+    if(inbyte==10) {
+      // Command Received, parse it
+      incomingBuffer[bufPosition]='\0';
+      inputCommand = String(incomingBuffer);
+      bufPosition=0;
+      if(inputCommand.equals(String("CHECK"))) {
+        Serial.println("CONNECT");
+      }
+      else if(inputCommand.startsWith(String("DATA"))) {
+        color_frames_string = inputCommand.substring(5);
+        color_frames_string.toCharArray(color_frames_chararray,6);
+        color_frames = atoi(color_frames_chararray);
+        TCL.sendEmptyFrame();
+        for(i=0;i<color_frames;i++) {
+          while(!Serial.available()) { }
+          red = (byte)Serial.read();
+          while(!Serial.available()) { }
+          green = (byte)Serial.read();
+          while(!Serial.available()) { }
+          blue = (byte)Serial.read();
+          TCL.sendColor(red,green,blue);
+        }
+        TCL.sendEmptyFrame();
+      }
+    }
+    else {
+      incomingBuffer[bufPosition]=(char)inbyte;
+      bufPosition++;
+      if(bufPosition==128) {
+        Serial.println("OVERFLOW");
+        bufPosition=0;
+      }
+    }
+  } 
+}