Show Posts
Pages: [1] 2
1  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 19, 2013, 09:53:17 pm
I am referring to the above advice that the strings in Arduino cause memory issues. Which is what i used in my initial code posting. The reworked code removes all use of Arduino strings in favor of the more reliable (and faster) C++ chars to build the calls from the Serial.read() and trigger the Tlc commands. I posted the reworked code as well.

Hope this helps
2  Using Arduino / LEDs and Multiplexing / SOLVED Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 19, 2013, 04:47:58 am
**** UPDATE *****
So reworking the arduino code to utilize C++ chars rather than strings seems to have solved the problem with it acting inconsistently. The flicker that remained ended up a simple fix. I shortened the length of the wires connecting the buffers as much as physically possible (approximately an inch). I am still unsure why it only was a problem with the Uno and not the Duemilanove. Regardless, it works perfectly on both now. I am attaching a photo of the 1st panel running on the Raspberry Pi with an Uno (Left) and a Duemilanove (Right). All addresses work perfectly and no flicker.


Thanks for all of your help. After this project is over, I'll scour the forum to see if there is anything I can help out with.
3  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 18, 2013, 02:24:55 am
I made a PDF of the schematic, I am attaching it to this post.
4  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 18, 2013, 01:05:51 am
I am not trying to be difficult. I have the schematic on another computer. As soon as I get a chance I will post it. Sorry if I am not moving fast enough on some requests.
5  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 18, 2013, 12:59:20 am
Each output does have a pull-up resistor.
6  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 18, 2013, 12:25:58 am
So I followed the directions to move away from string and use C++ instead. It seems to have helped, though there is still some flickering when the UNO board is driving the system.
I also installed Arduino 1.0.5 and added the malloc.c
Here is the new code:

Code:
// 2013-06-17

/*
    Basic Pin setup:
    ------------                                  ---u----                                          Cable Pin Out  
    ARDUINO   13|-> SCLK (pin 25)   W       OUT1 |1     28| OUT channel 0                          NC   |10  9|   Blank
              12|                           OUT2 |2     27|-> GND (VPRG)                           SIN  |8   7|   SCLCK
              11|-> SIN (pin 26)    B       OUT3 |3     26|-> SIN (pin 11)                         GND  |6   5|   GND
              10|-> BLANK (pin 23)  Y       OUT4 |4     25|-> SCLK (pin 13)                        XLAT |4   3|   GSCLK
               9|-> XLAT (pin 24)   O         .  |5     24|-> XLAT (pin 9)                         GND  |2   1|   VCC (12V)                    
               8|                             .  |6     23|-> BLANK (pin 10)
               7|                             .  |7     22|-> GND
               6|                             .  |8     21|-> VCC (+5V)
               5|                             .  |9     20|-> 10K Resistor -> GND
               4|                             .  |10    19|-> +5V (DCPRG)
               3|-> GSCLK (pin 18)  G         .  |11    18|-> GSCLK (pin 3)
               2|                             .  |12    17|-> SOUT
               1|                             .  |13    16|-> XERR
               0|                           OUT14|14    15| OUT channel 15
    ------------                                  --------

    -  Put the longer leg (anode) of the LEDs in the +5V and the shorter leg
         (cathode) in OUT(0-15).
    -  +5V from Arduino -> TLC pin 21 and 19     (VCC and DCPRG)
    -  GND from Arduino -> TLC pin 22 and 27     (GND and VPRG)
    -  digital 3        -> TLC pin 18            (GSCLK)
    -  digital 9        -> TLC pin 24            (XLAT)
    -  digital 10       -> TLC pin 23            (BLANK)
    -  digital 11       -> TLC pin 26            (SIN)
    -  digital 13       -> TLC pin 25            (SCLK)
    -  The 2K resistor between TLC pin 20 and GND will let ~20mA through each
       LED.  To be precise, it's I = 39.06 / R (in ohms).  This doesn't depend
       on the LED driving voltage.
    - (Optional): put a pull-up resistor (~10k) between +5V and BLANK on the first board so that
                  all the LEDs will turn off when the Arduino is reset.

    If you are daisy-chaining more than one TLC, connect the SOUT of the first
    TLC to the SIN of the next.  All the other pins should just be connected
    together:
        BLANK on Arduino -> BLANK of TLC1 -> BLANK of TLC2 -> ...
        XLAT on Arduino  -> XLAT of TLC1  -> XLAT of TLC2  -> ...
    The one exception is that each TLC needs it's own resistor between pin 20
    and GND.

    This library uses the PWM output ability of digital pins 3, 9, 10, and 11.
    Do not use analogWrite(...) on these pins.
*/    
// for my setup:
// latch green
// clock yellow
// gclock yellow/black
// data blue
// blank blue/black


//#define DEBUG_MESSAGES  // Turn on Serial Print

//#include "Tlc5940.h"

//#include <tlc_servos.h>
//#include <tlc_animations.h>
//#include <tlc_progmem_utils.h>
#include <tlc_config.h>
#include <Tlc5940.h>
//#include <tlc_shifts.h>
//#include <tlc_fades.h>


/* NUM_TLCS is defined in "tlc_config.h" in the
   library folder.  After editing tlc_config.h for your setup, delete the
   Tlc5940.o file to save the changes. */
  
int brightness = 4095; // brightness level for LEDs. 0 - 4095
const int numNames = 16*NUM_TLCS;
int names[numNames];
unsigned long serialdata;
int inbyte;
char indata [12];
static unsigned int input_pos = 0;

void setup()
{
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  clearNames();
  Tlc.init(1000);
  delay(1000);
  Serial.begin(9600);
  while (!Serial) {
    // wait for serial port to connect. Needed for Leonardo only
  }
  Tlc.clear();
  while(Tlc.update());
  delay(50);
  #ifdef DEBUG_MESSAGES
    Serial.println("READY");
  #endif
}



void loop()
{
  while(Serial.available()>0) { //check to see if data is available
    char input = Serial.read();
    //Read Data into indata
    switch(input)
      {
        case ';'://end of string
          indata[input_pos] = '\0';
          processData(indata);
          break;
        default:
          if(input_pos < sizeof(indata)){
            indata[input_pos++] = input;
          }
          break;
      }
  }
}

void processData(char * data){
  #ifdef DEBUG_MESSAGES
    Serial.print("data-");
    Serial.println(data);
  #endif
  switch(data[0]) {
      case 'u': // 'u' means update tlc
        while(Tlc.update());
        #ifdef DEBUG_MESSAGES
          Serial.println("UPDATE");
        #endif
        break;  
      case 'c': // 'c' means clear tlc
        Tlc.clear();
        #ifdef DEBUG_MESSAGES
          Serial.println("CLEARED");
        #endif
        break;
      case 'l': // 'l' means turn on the numbered list of leds which follows. l12,3000;
        parseNames(data);
        int led;
        led = names[0];
        int ledbright;
        ledbright = names[1];
        
        if (ledbright > brightness){
          ledbright = 4095;
        }
        
        if (ledbright < 0) {
          ledbright = 0;
        }
        turnOn(led, ledbright);
        #ifdef DEBUG_MESSAGES
          Serial.print("LED-");
          Serial.print(led);
          Serial.print(": ");
          Serial.println(ledbright);
        #endif
        break;
      case 'a': // 'a' means turn all on. command to send is a####; where #### is brightness level
        Tlc.clear();
        int beginIdx = 1;
        int idx = input_pos - 1;
        int allbright;
        
        char brightString[16];
        memset(&brightString, '\0', sizeof(brightString));
        memcpy(brightString, data + beginIdx, idx);
        allbright = atoi(brightString);
        Tlc.setAll(allbright);
        #ifdef DEBUG_MESSAGES
          Serial.print("All On-");
          Serial.println(allbright);
        #endif
        delay(1);
        break;
    }
    memset(&indata, '\0', sizeof(indata));
    input_pos = 0;
}


// gets light & brightness data from a command of the form
// l15,200;
// that's a lowercase L followed by the led number a comma the brightness a comma and a semicolon

 void parseNames(char * data) { // parse serial data from string to int array
  clearNames();
  int name=0;
  int beginIdx = 1;
  int idx = input_pos - 1;
  char port[16];
  memset(&port,'\0',sizeof(port));
  memcpy(port, data + beginIdx, idx);
  char* chars_array = strtok(port, ",");
  while(chars_array)
    {
       names[name++] = atoi(chars_array);
       chars_array= strtok(NULL, ",");
    }
}


void turnOn(int led, int bright) {
  if (bright > 4095){bright=4095;}
  if (bright < 0){bright=0;}
  Tlc.set(led,bright); // turn on led at port 'led' with brightness 'bright'
  delay(1);
}

void clearNames() {
  for (int name = 0; name < numNames; name++) {
    names[name] = 0;
  }
}
7  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 16, 2013, 07:05:10 pm
The tlc can only handle 120ma. Therefore, to run higher current you have to use transistors and a constant power supply.
Here is a link to an example I found through the arduino page for the library. http://sonicrobots.com/2012/04/24/the-pwm-controller-tlc-5940-the-arduino-and-a-high-current-output-circuit/
8  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 15, 2013, 05:36:29 pm
There are amperage limits to the TLC. To be able to use an external power source it is standard practice to use the TLC to trigger transistors rather than run the lights directly.
9  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 15, 2013, 04:49:27 pm
I am using Revision 3 (R3). Thanks for your advice on the code. I'll clean it up. If the pin 13 LED is causing the problem is there a way to disable it?

10  Using Arduino / LEDs and Multiplexing / Re: Arduino Uno Inconsistent and Flickering with TLC5940 on: June 15, 2013, 04:09:09 pm
The LED's are being powered by a seperate 5V with a common ground, They are triggered by the TLC5940's through transistors. Each TLC has it's own decoupling caps.
11  Using Arduino / LEDs and Multiplexing / Arduino Uno Inconsistent and Flickering with TLC5940 on: June 15, 2013, 06:05:23 am
I have been working on a project that will be using python on 2 Raspberry Pi's to control 4 Arduinos and 120 tlc5940's (30 per arduino).
I bought 4 new Arduino Uno R3 smd boards to run the program. However, I had been testing on a Duemilanove before.

The code works exactly as expected when it is ran on my old Duemilanove. Which is what is making me think my issue is hardware related.

When I switched over to the Uno the lights no longer light up consistently, some don't light up at all, and others flicker.
When there are many lights turning on at once it the Uno doesn't work without multiple updateTLCs called. This is not a problem with the Duemilanove.

Things I have tried:
  • every baud rate between 9600 and 115200. I found that at 38400 the updateTLC's at least turns on first try.
  • playing with dozens of different delay setups in both the python code and the arduino code
  • making a link with sudo ln /dev/ttyACM0 /dev/ttyS0 on the raspberry pi
  • I have the same troubles when I control the daisy chain directly from the UNO (again not repeatable in the Duemilanove)
  • I have tried external power to the Arduinos
  • Rechecking all pcb boards, decoupling, buffers, and signal terminators
  • Have switched out all 4 Uno's and they all perform identically
  • Have tried an even older Diecimila and it works perfectly like the Duemilanove
  • checked the config code for the TLC5940 library to be sure that it has the correct number of TLC's set
  • gone over the code many times

After checking the software and connections in so many different ways I am wondering if there is a hardware conflict being created by the new USB setup of the UNO. I have ordered some old Due's from ebay (not my favorite choice) especially since this will be installed for a long time, and I would be happier if I could work this out so that I can be using the latest tech. That way I could be more confident about updating it in the future.

I have found issues with uploading to the Uno and getting the Raspberry Pi to communicate with the Uno, neither of these have been an issue for me. I can't find anything directly referring to my problem, any advice or direction would be greatly appreciated.

Below is the Arduino Code
Code:
// 2013-06-15

/*
    Basic Pin setup:
    ------------                                  ---u----                                          Cable Pin Out  
    ARDUINO   13|-> SCLK (pin 25)   W       OUT1 |1     28| OUT channel 0                          NC   |10  9|   Blank
              12|                           OUT2 |2     27|-> GND (VPRG)                           SIN  |8   7|   SCLCK
              11|-> SIN (pin 26)    B       OUT3 |3     26|-> SIN (pin 11)                         GND  |6   5|   GND
              10|-> BLANK (pin 23)  Y       OUT4 |4     25|-> SCLK (pin 13)                        XLAT |4   3|   GSCLK
               9|-> XLAT (pin 24)   O         .  |5     24|-> XLAT (pin 9)                         GND  |2   1|   VCC (12V)                    
               8|                             .  |6     23|-> BLANK (pin 10)
               7|                             .  |7     22|-> GND
               6|                             .  |8     21|-> VCC (+5V)
               5|                             .  |9     20|-> 10K Resistor -> GND
               4|                             .  |10    19|-> +5V (DCPRG)
               3|-> GSCLK (pin 18)  G         .  |11    18|-> GSCLK (pin 3)
               2|                             .  |12    17|-> SOUT
               1|                             .  |13    16|-> XERR
               0|                           OUT14|14    15| OUT channel 15
    ------------                                  --------

    -  Put the longer leg (anode) of the LEDs in the +5V and the shorter leg
         (cathode) in OUT(0-15).
    -  +5V from Arduino -> TLC pin 21 and 19     (VCC and DCPRG)
    -  GND from Arduino -> TLC pin 22 and 27     (GND and VPRG)
    -  digital 3        -> TLC pin 18            (GSCLK)
    -  digital 9        -> TLC pin 24            (XLAT)
    -  digital 10       -> TLC pin 23            (BLANK)
    -  digital 11       -> TLC pin 26            (SIN)
    -  digital 13       -> TLC pin 25            (SCLK)
    -  The 2K resistor between TLC pin 20 and GND will let ~20mA through each
       LED.  To be precise, it's I = 39.06 / R (in ohms).  This doesn't depend
       on the LED driving voltage.
    - (Optional): put a pull-up resistor (~10k) between +5V and BLANK on the first board so that
                  all the LEDs will turn off when the Arduino is reset.

    If you are daisy-chaining more than one TLC, connect the SOUT of the first
    TLC to the SIN of the next.  All the other pins should just be connected
    together:
        BLANK on Arduino -> BLANK of TLC1 -> BLANK of TLC2 -> ...
        XLAT on Arduino  -> XLAT of TLC1  -> XLAT of TLC2  -> ...
    The one exception is that each TLC needs it's own resistor between pin 20
    and GND.

    This library uses the PWM output ability of digital pins 3, 9, 10, and 11.
    Do not use analogWrite(...) on these pins.
*/    
// for my setup:
// latch green
// clock yellow
// gclock yellow/black
// data blue
// blank blue/black


//#include "Tlc5940.h"

//#include <tlc_servos.h>
//#include <tlc_animations.h>
//#include <tlc_progmem_utils.h>
#include <tlc_config.h>
#include <Tlc5940.h>
//#include <tlc_shifts.h>
//#include <tlc_fades.h>


int brightness = 4095; // brightness level for LEDs. 0 - 4095
const int numNames = 16*NUM_TLCS;
int names[numNames];
unsigned long serialdata;
int inbyte;
String indata;

void setup()
{
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  clearNames();
  Tlc.init(1000);
  delay(1000);
  Serial.begin(9600);
  Tlc.clear();
  while(Tlc.update());
  delay(50);
}

/* NUM_TLCS is defined in "tlc_config.h" in the
   library folder.  After editing tlc_config.h for your setup, delete the
   Tlc5940.o file to save the changes. */

void loop()

{
  indata = ""; // empty buffer for serial data
  if(Serial.available()>0) { //check to see if data is available
    delay(5);  // wait for data to be completely sent
    readData();  // read in string of data until ; is encountered

    switch(indata[0]) {
      case 'u': // 'u' means update tlc
        while(Tlc.update());
        break;
      case 'c': // 'c' means clear tlc
        Tlc.clear();
        break;
      case 'l': // 'l' means turn on the numbered list of leds which follows. l12,3000,;
        parseNames();
        int led;
        led = names[0];
        int bright;
        bright = names[1];
        
        if (bright > brightness){
          bright = 4095;
        }
        
        if (bright < 0) {
          bright = 0;
        }
        turnOn(led, bright);
        break;
      case 'a': // 'a' means turn all on. command to send is a####; where #### is brightness level
        int beginIdx = 1;
        int idx = indata.indexOf(";");
        String brightString = indata.substring(beginIdx, idx);
        char brightArray[16];
        brightString.toCharArray(brightArray,16);
        bright = atoi(brightArray);
        Tlc.setAll(bright);
        break;
    }
  }

}

void readData() { // read data from serial until ; is encountered
  while(Serial.available()>0) { // while data is available
    char inchar = Serial.read(); // get a character
    delay(5);
    if (inchar == ';') { // ; indicates end of command
      break;
    }
    else{
      indata += inchar; // build string.
    }
  }
}
//

// gets light & brightness data from a command of the form
// l15,200,;
// that's a lowercase L followed by the led number a comma the brightness a comma and a semicolon
void parseNames() { // parse serial data from string to int array
  clearNames();
  int name=0;
  int beginIdx = 1;
  int idx = indata.indexOf(",");
  char portBuf[16];
  while (idx != -1) {
    String port = indata.substring(beginIdx, idx);
    port.toCharArray(portBuf, 16);
    names[name++] = atoi(portBuf);
    beginIdx = idx+1;
    idx = indata.indexOf(",",beginIdx);
  }
}

void turnOn(int led, int bright) {
  if (bright > 4095){bright=4095;}
  if (bright < 0){bright=0;}
  Tlc.set(led,bright); // turn on led at port 'led' with brightness 'bright'
  delay(1);
}

void clearNames() {
  for (int name = 0; name < numNames; name++) {
    names[name] = 0;
  }
}




12  Forum 2005-2010 (read only) / Syntax & Programs / Re: Working with uint8_t encoded data (virtualwire) on: February 14, 2010, 11:40:23 pm
Thanks anyways, sometimes you just need to write the problem out to figure it out.  It clicked not long after I posted this.  Here is the answer allowing you to receive data from the transmitter and then convert it to integers after creating a single string from the data.

Code:
///////////////////////////////////////////Receive Data
void rx(){

  //   vw_rx_start();
  // Serial.println("Receive");//Debug Only
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  vw_wait_rx();
  if (vw_get_message(buf, &buflen)) // check to see if anything has been received
  {
    for (int i=0;i<buflen;i++) msg[i]=0;
    {
      int i;
      char vBuff[30]="";
      // Message with a good checksum received.
      // Serial.print("Got: ");
      for (int i = 0; i < buflen; i++)
      {
        // Serial.print(buf[i], BYTE);
        msg[i]=buf[i];
      }
      Serial.println();
      //Create String from received data
      strcat(vBuff, msg);
      //Convert to individual integers from char
      char *rxString = vBuff;
      char *str[30];
      int convert[30];
      int j=0;
      while((str[j] = strtok_r(rxString, ":,", &rxString)) !=NULL){ // delimiter : and ,
        convert[j]=atoi(str[j]);
        if(j==0){
          Serial.print("Sensor= ");
          Serial.println(convert[j]);
        }else{
          Serial.print("near= ");
          Serial.println(convert[j]);
        }
        j++;
      }
    }
  }
}
13  Forum 2005-2010 (read only) / Syntax & Programs / Working with uint8_t encoded data (virtualwire) on: February 14, 2010, 10:16:12 pm
As usual I have managed to solve some problems while failing to solve others. Currently I am stuck on the translation of data. I am building a cheap tranceiver using radio transmitters and receivers I have got from Sparkfun. I am able to send an address and receive the addresses of others transmitting theirs.

The trick I am trying to pull off in the larger view is that I want to also send which tranceivers each individual tranceiver can see. I am able to send the data from variables as follows- 0:1,2 where 0 is the tranceiver that can see 1 and 2. However, currently the 1 and 2 is only hard coded not a variable like the address.

I am having trouble parsing the uint8_t data that I receive. I have worked out a script to translate a string to integers with , delineation. However I cannot get the uint8_t data to convert to a char so that i can strcat it into a string for parsing into int's.

here is the script where it needs to go.
Code:
char msg[30]="";

///////////////////////////////////////////Receive Data
void rx(){

 //   vw_rx_start();
 // Serial.println("Receive");//Debug Only
  uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    vw_wait_rx();
    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
      for (int i=0;i<buflen;i++) msg[i]=0;
    int i;

     // Message with a good checksum received.
      Serial.print("Got: ");
       for (int i = 0; i < buflen; i++)
        {
          Serial.print(buf[i], BYTE);
          msg[i]=buf[i];
        }
     Serial.println();
   }
}

I have tried many things (removed because they failed). Typically the error is either cannot convert uint8_t to const *char or cannot convert char to *char.

What is the proper method for parsing uint8_t to char. So far I can print the msg var but cannot do anything useful with it.

Thanks
14  Forum 2005-2010 (read only) / Interfacing / Arduino nrf24L01+ Module - send larger payloads on: July 22, 2010, 05:27:20 am
I understand that the max payload of the nrf24L01+ module  is 32. However, I need to create a network that daisy chains the sensors it can see -- within a meter or 2 -- and the sensors each visible sensor can see as well, up to possibly 100 sensors. Is there an efficient  manner in which I can send this data, regardless of the 32 max payload.

I used another variation of receiver/transmitter that was too slow but it worked well otherwise.  In general, the from of data I am sending looks like this assuming 4 sensors (of a possible 100+).

extremely short example:
[1:2,3][2:1,4][3:1,4][4:2,3]

obviously with 100 roving sensors this will become considerably more complex.

if anybody has a direction they can point me to pass more than a payload of 32 -- even in increments -- I would appreciate it. I need to be able to daisy chain large payloads, efficiently.
15  Forum 2005-2010 (read only) / Troubleshooting / Re: Pro Mini, 6 LED's, and tone.h library help on: July 22, 2010, 05:35:17 am
I am unsure exactly what you are trying to do, but have you checked out the mux breakout
http://www.sparkfun.com/commerce/product_info.php?products_id=9056
Pages: [1] 2