Go Down

Topic: [OPEN] Radio Shack - Single Pin LED Strip - Help (Read 3033 times) previous topic - next topic

dugup46

Apr 19, 2013, 04:26 am Last Edit: Apr 19, 2013, 04:49 am by dugup46 Reason: 1
EDIT: Here is the strip that I own: http://www.radioshack.com/product/index.jsp?productId=16306856 Hope that helps.

Hello everyone, new to the forums, new to the Arduino, new to this nightmare of an LED strip.  I already know I made a mistake by purchasing the Radio Shack strip, and I should have purchased one off adafruit.com; however, I'm getting close I feel to figuring this thing out... I just need a little help in the right direction.

After extensively searching Google/YouTube, it seems just about nobody has any useful example code on this strip.  The documentation Radio Shack gives you (As a 'Level 1 Beginner') is more useful as toilet paper than it is a tutorial on how to use the strip.  I would give the code, but it's way too long.

After looking through it and getting rid of all the garbage they supply, I was able to shrink it down to this... and I was able to grasp a little understanding of how their code works.  What I can't understand is that send_strip function or why the data is stored in the flash memory rather than just sent straight out... anyway... here is the code that I have it down to:

Code: [Select]

#include <avr/pgmspace.h>

// ******** DEBUG ==== should auto config to adapt different mother board *********
#define DATA_1 (PORTC |=  0X01)    // DATA 1    // for UNO
#define DATA_0 (PORTC &=  0XFE)    // DATA 0    // for UNO
#define STRIP_PINOUT (DDRC=0xFF)    // for UNO

//Actually is GBR not RGB format

PROGMEM unsigned long outputvalue[][10]={
 {0X009900, 0X0089AA, 0X007700, 0XFF6600, 0X005500, 0XDD4400, 0X003300, 0X002200, 0X001100, 0X000000},
 };

void setup()
{  
 STRIP_PINOUT;        // set output pin - DEBUG: should auto detect which mother board for use

 reset_strip();
 //noInterrupts();
}

void loop()
{
 send_1M_pattern(outputvalue);
 delay(50);
}

void send_1M_pattern(unsigned long data[][10])
{
 int i=0;
 int j=0;
 int frame_rate = 10;
 uint32_t temp_data;
 
 noInterrupts();
 
 for (j=0;j<10;j++)
 {
   temp_data=pgm_read_dword_near(&data[i][j]);
   send_strip(temp_data);
 }
 interrupts();

 delay(frame_rate);
}

void send_strip(uint32_t data)
{
 int i;
 unsigned long j=0x800000;
 
 for (i=0;i<24;i++)
 {
   if (data & j)
   {
     DATA_1;
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");    
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     DATA_0;
   }
   else
   {
     DATA_1;
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");
     __asm__("nop\n\t");    
     DATA_0;
   }

   j>>=1;
 }
}

void reset_strip()
{
 DATA_0;
 delayMicroseconds(20);
}


Much cleaner.  Here's the problem.  How can I change the output color on the fly?  Since the data is stored in the flash memory before the program even starts, I am unsure how to change it.  I would rather eliminate the memory aspect of the code all together and just have it pass an array if that would work.  I don't understand the defines up top, I don't understand why it has to be stored (or how to change it), and I don't understand that send_strip function at all.

Can somebody PLEASE save me (and I'm sure MANY others) from bashing my head against a wall.

dugup46

For anyone who wants the original code that Radio Shack supplies to their Level 1 Beginners, I had to post in a new message because of the message limit... This is what I had to work with originally.

Code: [Select]
#include <avr/pgmspace.h>

// ******** DEBUG ==== should auto config to adapt different mother board *********
#define DATA_1 (PORTC |=  0X01)    // DATA 1    // for UNO
#define DATA_0 (PORTC &=  0XFE)    // DATA 0    // for UNO
#define STRIP_PINOUT (DDRC=0xFF)    // for UNO

PROGMEM const unsigned long pattern_test_red[10][10]={
  {0xff0000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0xff0000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0xff0000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0xff0000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0xff0000,0x000000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0x000000,0xff0000,0x000000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0xff0000,0x000000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0xff0000,0x000000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0xff0000,0x000000},
  {0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0xff0000},
};

//HAD TO ELIMINATE ABOUT 6 MORE PATTERNS BECAUSE OF MESSAGE LIMIT

PROGMEM const unsigned long pattern_all_on[10][10]={
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
  {0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff,0xffffff},
};

// *                            Power Up Init.

void setup() {               

  STRIP_PINOUT;        // set output pin - DEBUG: should auto detect which mother board for use

  reset_strip();
  //noInterrupts();

}

// *                            Main Loop

void loop()
{
int seconds=0;
//send_1M_pattern(pattern_all_on,10,100);
   
 
  while (1)
  {
    send_digits_pattern(pattern_20digs_mix,seconds );
seconds++;
if(seconds>19)seconds=0;
  }
}

// Function Name  : send_1M_pattern
// Description    : Transmit pattern to whole 1 meter strip                 
// Input          : pointer to ROM pattern; pattern length; frame rate

void send_1M_pattern(const unsigned long data[][10], int pattern_no, int frame_rate)
{
  int i=0;
  int j=0;
  uint32_t temp_data;

  for (i=0;i<pattern_no;i++)
  {
    noInterrupts();
    for (j=0;j<10;j++)
    {
      temp_data=pgm_read_dword_near(&data[i][j]);
      send_strip(temp_data);
    }
    interrupts();

    delay(frame_rate);

  }
}

void send_digits_pattern(const unsigned long data[][9], int coutner)
{
  int i=coutner;
  int j=0;
  uint32_t temp_data;

    noInterrupts();
    for (j=0;j<9;j++)
    {
      temp_data=pgm_read_dword_near(&data[i][j]);
      send_strip(temp_data);
    }
    interrupts();

    delay(1000); //1s
}


// Function Name  : send_strip
// Description    : Transmit 24 pulse to LED strip               
// Input          : 24-bit data for the strip

void send_strip(uint32_t data)
{
  int i;
  unsigned long j=0x800000;
 

  for (i=0;i<24;i++)
  {
    if (data & j)
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");   
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      DATA_0;
    }
    else
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");   
      DATA_0;
    }

    j>>=1;
  }


 
}


// Function Name  : reset_strip
// Description    : Send reset pulse to reset all color of the strip

void reset_strip()
{
  DATA_0;
  delayMicroseconds(20);
}


dugup46

I'm sure this community does not allow bump posts; however, I am checking this post multiple times a day looking for some help or advice on how to proceed.  I can contribute to the above code by stating that I am using an Arduino Uno.  Another question I came up with is the uint32_t data type.  I can find a lot of people using it online; however, I don't see much documentation as to what it is or how it works in storing data.  Any help there would also be greatly appreciated in reference to the above code.

fungus


I'm sure this community does not allow bump posts; however, I am checking this post multiple times a day looking for some help or advice on how to proceed.  I can contribute to the above code by stating that I am using an Arduino Uno.  Another question I came up with is the uint32_t data type.  I can find a lot of people using it online; however, I don't see much documentation as to what it is or how it works in storing data.  Any help there would also be greatly appreciated in reference to the above code.


You waited a whole seven hours before bumping? That's less time than some people were in bed.

Start here: https://www.sparkfun.com/tutorials/317

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

dugup46



You waited a whole seven hours before bumping? That's less time than some people were in bed.

Start here: https://www.sparkfun.com/tutorials/317



Thanks for the information... it must be defined in the include file pgmspace.h file, because it's not defined in the code anywhere that I can see.  I thought maybe it was a default Arduino data type.  I will look into the pgmspace.h more and check out to see what that data type even is.  I would like to read what that data type is outputting, but I can't even get it to print out on the serial monitor. Ideally I would just like to just eliminate the PROGMEM and just have a value sent directly to the strip, from there I could figure out the rest of the program.

Also, it should have been 2 days since the original post; I wouldn't bump in seven hours.

jcrum

I am new on this, I did use those code for both diecinmila and micro too.  The pinout is set on A0, my question is how can I change it to A1 or A3 etc.?

Thank,

jack wp

Maybe this "Single Pin LED Strip" is not used by many/any on this forum. It is a Radio Shack item, you may want to contact them for more info, online first, and then by phone if no help is provided. Then get an RMA if no help is provided.
I think they can provide you with an acceptable solution.

Good luck, Jack

agirgen

Hello,

I don't know if you are still playing around with the RadioShack LED strip or not but I thought I would share some info.  I have been trying to make a 20 section Ambilight with the RadioShack LEDs.  I have been using the stock demo code to read colors from an app written in Processing.  When I initially set up everything, it worked great with one strip (10 controllers) but once I soldered on a second strip (20 controllers), it got all funky.  So, I have spent the last week researching this strip, trying to figure out what its doing, in an effort to get my code to work.  So far, I have had little luck with it but I did find out some stuff that might help you with your project.

The RadioShack LED strips will work with both the pololuledstrip.h library as well as fastSPI_LED2.h libary.  Those libraries make sending data to the strip much easier and they also have a way to define the number of leds (controllers) you are using as well as the output pin you have the LEDs data line connected to.  The only thing you have to do with these libraries is define the order the RGB colors are outputted... With the pololu library, this has to be done in the code but with the fastSPI_LED2 library it can be done in the line where you define what LED controller you are using: 

Code: [Select]
//Change the color order sent to the leds by changing "GBR".
//GBR is the correct order for the RadioShack LEDs.
FastLED.addLeds<TM1803, DATA_PIN, GBR>(leds, NUM_LEDS);


As for what is in the stock code, I think its written in C (correct me if I'm wrong).  Researching the avr/pgmspace.h library is the key to understanding whats going on in the RadioShack code, I think...  not 100% sure on this as I'm pretty new to Arduino and know almost nothing about C.

I figured this might be usful info for anyone who might stumble across this post..  I know I was (am) getting pretty frustrated.  RadioShack did a SH17 job at documenting these things.  Most of my problems are in the area of trying to send serial data to the arduino though, not with actually getting the colors to display... Oh well...

Take care,
Andrew

NotAGuru

Everyone has been trashing the code that RS provides for their LED strip.  While not elegant - it certainly does work with UNO, without making any changes.  For those who seek more creative pattern, changing colors "on the fly" etc, that will require learning more about this particular program, as well as learning about programming.

The RS program loads the RAM with an array of values that are then sent to the LED strip in groups of 10 (the strip has 10 "nodes" - one for each group of three LEDs.  Each "row" in the array is a single "frame" for the LED strip.  Cycling through multiple frames creates the illusion of a moving pattern.

You can try out one row at a time to set the colors that you want.  Then you create a two-dimensional array, cycling through one row at a time, to change the pattern.

I will try to upload an annotated version of the RS code later today.  But, as others have said, it does work "out of the box" with the code posted on the RS website.

rgbailey

#9
Jun 18, 2014, 01:06 am Last Edit: Jun 18, 2014, 01:10 am by rgbailey Reason: 1
I have been working with this code on a project with the same LED Strip.  I have it working with 12 segments and will post the code that I have working when I get home.

Note: these LED strings are on clearance, they have been replaced with a similar set, I have not worked with them and will not.  The adafruit neopixels look much easier to work with and I will go with them for future LED projects.

I will comment up my code with what I understand of its function, including PROGMEM.


rgbailey

As promised, here is my current working code for 12 LED segments using the Radio Shack code and LED string that is on clearance.
This code is fair game, give credit where credit is due.
NOTE: the actual patterns have been removed to make the post small enough.  If you are interested in the actual patterns, let me know.
Code: [Select]

/***************************************************************************/
// LED sign for our home using RadioShack Tricolor LED Strip  The patterns
// light the segments in a figure in a specfic pattern that starts with LED
// groups two and three.
//  By Richard Bailey  email: rgbailey@gmail.com
//
/***************************************************************************/


/***************************************************************************/   
//            Hardware: RadioShack Tricolor LED Strip
//            Arduino IDE: Arduino-1.0
//            Date:      April 17, 2013
//            Copyright© 2013 RadioShack Corporation
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, see <http://www.gnu.org/licenses/>
//
/*****************************************************************************/

// makes the PROGMEM variable switch work.

#include <avr/pgmspace.h>

// ******** DEBUG ==== should auto config to adapt different mother board *********
//#define DATA_1 (PORTF |=  0X01)    // DATA 1    // for ATMEGA
//#define DATA_0 (PORTF &=  0XFE)    // DATA 0    // for ATMEGA
//#define STRIP_PINOUT DDRF=0xFF  // for ATMEGA
#define DATA_1 (PORTC |=  0X01)    // DATA 1    // for UNO
#define DATA_0 (PORTC &=  0XFE)    // DATA 0    // for UNO
#define STRIP_PINOUT (DDRC=0xFF)    // for UNO


// hex order is GGBBRR

//  PROGEMEM  is a switch for variable intialization that make the variable reside in the program memory, not in the working memory.  Allows for larger arrays without filling up the memory
// const make the variable read only

PROGMEM const unsigned long pattern_test_yellow[][12]={
[code snipped from here due to post size limits.]
}

PROGMEM const unsigned long pattern_test_green[][12]={
[code snipped from here due to post size limits.]
}
PROGMEM const unsigned long pattern_test_blue[][12]={
[code snipped from here due to post size limits.]
}
PROGMEM const unsigned long pattern_test_red[][12]={
[code snipped from here due to post size limits.]
}

PROGMEM const unsigned long pattern_test_rainbow[12][12]={
[code snipped from here due to post size limits.]
}

PROGMEM const unsigned long pattern_test_kelley[][12]={
[code snipped from here due to post size limits.]
}
// variable I used for the while loops.  needs to be declared before it is used.
unsigned int l;

// ***********************************************************************************************************
// *
// *                            Power Up Init.
// *
// *
// ***********************************************************************************************************
void setup() {               

  STRIP_PINOUT;        // set output pin - DEBUG: should auto detect which mother board for use

  reset_strip();
  //noInterrupts();
 

}



// ***********************************************************************************************************
// *
// *                            Main Loop
// *
// *
// ***********************************************************************************************************
void loop()
{
  // set variable l to zero before the while loop
  l=0;
  // this loop lights the LEDs various white intensities
  while (l < 5)
  {
    //send_1M_pattern(name of pattern, number of frames, delay between frames)
    send_1M_pattern(pattern_test_kelley, 28, 160);
    l++;
  }
  // set variable l to zero before the while loop
  l=0;
  // this loop lights the LEDS various yellow intensities
  while (l < 5)
  {
    send_1M_pattern(pattern_test_yellow, 28, 160);
    l++;
  }
  // set variable l to zero before the while loop
  l=0;
    // this loop lights the LEDs various red intensities
  while (l < 5)
  {
    send_1M_pattern(pattern_test_red, 28, 160);
    l++;
  }
  // set variable l to zero before the while loop
  l=0;
  // this loop lights the LEDS various blue intensities
  while (l < 5)
  {
    send_1M_pattern(pattern_test_blue, 28, 160);
    l++;
  }
  // set variable l to zero before the while loop
  l=0;
  // this loop lights the LEDs various green intensities
  while (l < 5)
  {
    send_1M_pattern(pattern_test_green, 28, 160);
    l++;
  }


  /*   This is code from Radio Shack,  I am leaving it here because I have some thoughts on how to use it.  RB
frame++;
    if(frame<=10) LEDSTRIP_PATTERN_0();
    if(10<frame<=20) LEDSTRIP_PATTERN_0();
    if(20<frame<=30) LEDSTRIP_PATTERN_0();
    if(frame>30) frame=1;
   */
  //delay(1);
}


/*******************************************************************************
* Function Name  : send_1M_pattern
* Description    : Transmit pattern to whole 1 meter strip
*                 
* Input          : pointer to ROM pattern; pattern length; frame rate
*                 
* Output         : None
* Return         : None
*******************************************************************************/
void send_1M_pattern(const unsigned long data[][12], int pattern_no, int frame_rate)
{
  int i=0;
  int j=0;
  uint32_t temp_data;

  for (i=0;i<pattern_no;i++)
  {
    noInterrupts();
    for (j=0;j<12;j++)
    {
      temp_data=pgm_read_dword_near(&data[i][j]);
      send_strip(temp_data);
    }
    interrupts();

    delay(frame_rate);

  }




}


/*******************************************************************************
* Function Name  : send_strip
* Description    : Transmit 24 pulse to LED strip
*                 
* Input          : 24-bit data for the strip
*                 
* Output         : None
* Return         : None
*******************************************************************************/
void send_strip(uint32_t data)
{
  int i;
  unsigned long j=0x800000;
 

  for (i=0;i<24;i++)
  {
    if (data & j)
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");   
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
     
/*----------------------------*/
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t"); 
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t"); 
      __asm__("nop\n\t"); 
      __asm__("nop\n\t");       
/*----------------------------*/     
      DATA_0;
    }
    else
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");   
      DATA_0;
/*----------------------------*/     
       __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");     
/*----------------------------*/         
    }

    j>>=1;
  }


 
}

/*******************************************************************************
* Function Name  : reset_strip
* Description    : Send reset pulse to reset all color of the strip
*                 
* Input          : None
*                 
* Output         : None
* Return         : None
*******************************************************************************/
void reset_strip()
{
  DATA_0;
  delayMicroseconds(20);
}


Richard

rgbailey

I am also currently working on a version that will be more program memory efficient.   I can also post it when I get it working if there is interest.

Richard

medpixman

Could you post the code segment that fills the array variable with the LED values, please?
Thanks

Go Up