Touchdesigner(python) to Arduino for LED control: flickering

This is the place for queries that don't fit in any of the other categories.

Touchdesigner(python) to Arduino for LED control: flickering

Postby VdwJeff » Thu Sep 15, 2016 1:35 pm

I'm trying to make touchdesigner communicate with Arduino (via serial) to control 13 LEDs. I have a table with rgb values set up sending data to arduino. It kind of works, however, the leds seem to be flickering into random colors when they change values. I got both the arduino and the touchdesigner script from this video (https://www.youtube.com/watch?v=1_mFE6GtwwQ) and tweaked them so they would work for this project. The script I'm using in touchdesigner is written in python, so I thought maybe someone on this forum could tell me if there's something wrong with the script. I'm using an arduino UNO and a LPD8806 led strip. Any idea where the problem lies?

Touchdesigner:
Code: Select all
def tableChange(dat):
   
   debugCharLength = 1 # when this is set to one, we build our debug array that will print if set to 1.

   # Lets get the dimensions of our table.
   colNum = dat.numCols
   rowNum = dat.numRows
   
   # Declare our holding array for our entire led array.
   colorTable_RGB = []
   
   # Parse our DAT table into a python friendly array.
   for x in range(int(rowNum)):
      colorSingle_RGB = []
      colorSingle_RGB.append(int(dat[x, 0]))
      colorSingle_RGB.append(int(dat[x, 1]))
      colorSingle_RGB.append(int(dat[x, 2]))
      colorTable_RGB.append(colorSingle_RGB)
      
   debugLengthArray = []
   executeArray = []
   subExArray = []
   firstValueMarker = 1
   for ledColor in colorTable_RGB:
      if((len(subExArray) + 5) < 255): # if the sub array hasn't reached  touch's maximum allowed length for a byte packet, continue adding...
         subExArray.append(ledColor[0])
         subExArray.append(ledColor[1])
         subExArray.append(ledColor[2])
         if(debugCharLength == 1):
            debugLengthArray.append(ledColor[0])
            debugLengthArray.append(ledColor[1])
            debugLengthArray.append(ledColor[2])
      else: # if the sub array will be too big after next iteration, assign to master, and clear sub for new chunk.
         executeArray.append(subExArray)
         subExArray = []
         subExArray.append(ledColor[0])
         subExArray.append(ledColor[1])
         subExArray.append(ledColor[2])
         if(debugCharLength == 1):
            debugLengthArray.append(ledColor[0])
            debugLengthArray.append(ledColor[1])
            debugLengthArray.append(ledColor[2])
   executeArray.append(subExArray) # append the rest of the values gathered to the master execute array.
   if(debugCharLength == 1):
      print(len(debugLengthArray)) # print length of debug array.
   for subArray in executeArray: # for each chunk of serial data..
      if(debugCharLength == 1):
         print(subArray) # print eaceh item of debug array.
      if(int(op("serialCom_enabler")[0]) == 1): # if serial chop is enabled... send serial communication through it using it's send bytes function.
         exec('op("ledSerialConnector").sendBytes(%s)'%(str(subArray).strip('[]'))) # converts array to comma separated string that can be executed at once.
   return


Arduino:
Code: Select all
#include "LPD8806.h"
#include "SPI.h" // Comment out this line if using Trinket or Gemma
#ifdef __AVR_ATtiny85__
 #include <avr/power.h>
#endif
// ------------------- Variables - These need to be set -------------------- //
//#define PIN 2
const int numOfLeds = 13;
const int dataChunkSize = 3;

int maxBright = 255;

// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 2;
int clockPin = 3;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(numOfLeds);

const int numOfBytes = numOfLeds * dataChunkSize;
int byteReturnLen = 0;
int byteReturnCounter = 0;
char inputBuffer[numOfBytes];
int led = 0;
int led_r = 0;
int led_g = 0;
int led_b = 0;
unsigned long currentMillis = 0;
unsigned long time;
unsigned long previousMillis = 0;


// the setup function runs once when you press reset or power the board
void setup()
{
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
  #endif

  strip.begin(); // init strip.
  strip.show(); // push dark pixels to all.
  Serial.begin(9600);
  Serial.setTimeout(500);
 
}

// ------------------- Gama Lookup table -------------------- //
const byte dim_curve[] = {
  0,   0,   0,   0,   0,   0,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
  1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
  1,   2,   2,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,   4,   4,
  4,   4,   4,   5,   5,   5,   5,   6,   6,   6,   6,   7,   7,   7,   7,   8,
  8,   8,   9,   9,   9,  10,  10,  10,  11,  11,  12,  12,  12,  13,  13,  14,
 14,  15,  15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  22,
 22,  23,  23,  24,  25,  25,  26,  26,  27,  28,  28,  29,  30,  30,  31,  32,
 33,  33,  34,  35,  36,  36,  37,  38,  39,  40,  40,  41,  42,  43,  44,  45,
 46,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
 61,  62,  63,  64,  65,  67,  68,  69,  70,  71,  72,  73,  75,  76,  77,  78,
 80,  81,  82,  83,  85,  86,  87,  89,  90,  91,  93,  94,  95,  97,  98,  99,
101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 119, 121, 122, 124,
125, 127, 129, 130, 132, 134, 135, 137, 139, 141, 142, 144, 146, 148, 150, 151,
153, 155, 157, 159, 161, 163, 165, 166, 168, 170, 172, 174, 176, 178, 180, 182,
184, 186, 189, 191, 193, 195, 197, 199, 201, 204, 206, 208, 210, 212, 215, 217,
219, 221, 224, 226, 228, 231, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255 };

// the loop function runs over and over again forever
void loop()
{
   if(Serial.available() > 0)
   {
    byteReturnCounter = Serial.readBytes(inputBuffer, numOfBytes); // read the available serial bytes into "inputBuffer" while returning the number of bytes to "byteReturnCounter"
    byteReturnLen += byteReturnCounter; // iterate our bytes returned counter by how much we recieved just above. we do this to know when we reach the total number of led's worth.
  }
  if(byteReturnLen >= numOfBytes) // if we've recieved a full load of data (number of led's times number of bits per led : 192*3 then we can proceed to set each led's rgb values.)
  {
    for (int j = 0; j < numOfLeds; j++) { // for loop through our total led's set from above.
      led_r = constrain(dim_curve[inputBuffer[(j*dataChunkSize)]], 0, maxBright); // set each r,g, and b value through the gamma table and using offsets and multiple of three to traverse the array.
      led_g = constrain(dim_curve[inputBuffer[(j*dataChunkSize)+1]], 0, maxBright);
      led_b = constrain(dim_curve[inputBuffer[(j*dataChunkSize)+2]], 0, maxBright);
     
      strip.setPixelColor(j, led_r, led_g, led_b);
    }
    strip.show();
    byteReturnLen = 0; // we're done, lets reset this back to 0 for the next update.
   
  }

   
}



Another problem I have is that Arduino doesn't seem to be able to keep up with the data coming in from touchdesigner when fps is above 20. Any help is welcome.
Last edited by micseydel on Thu Sep 15, 2016 2:23 pm, edited 1 time in total.
Reason: Initial post lock.
VdwJeff
 
Posts: 1
Joined: Thu Sep 15, 2016 1:33 pm

Return to General Coding Help

Who is online

Users browsing this forum: Google [Bot] and 1 guest