Question

I am just starting to learn about the Arduino. I have a 1 meter LED strip from Radio Shack to play around with.

The strip came with a sample program so I looked at it and whittled it down to the basics, but I don't understand what's going on. I am looking for someone to explain what is going on and how the functional code works.

Here's the code:

#include <avr/pgmspace.h>

#define DATA_1 (PORTC |=  0X01)
#define DATA_0 (PORTC &=  0XFE)
#define STRIP_PINOUT (DDRC=0xFF)

/*
green 0xff0000
cyan 0xff7f00
truquoise 0xffff00
dark blue 0x00ff00
red 0x0000ff
dark yellow 0x6f00ff
yellow 0x8f00ff
white 0xffffff
off white 0x444444
dim white 0x111111
off 0x000000
*/

PROGMEM long test[10][10]={
  {0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000},
};

void setup() {

  STRIP_PINOUT;

  reset_strip();

}


void loop() 
{
  while (1)
  {
    send_pattern(test, 10, 50);
    reset_strip();
  }
}


void send_pattern(long data[][10], int length, int rate)
{
  int i=0;
  int j=0;

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

    delay(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);
}
Was it helpful?

Solution

That code is not a good place to start if you don't know C and/or haven't used an Arduino before.

The Arduino programming language (called Wiring) abstracts lots of the raw details of the C code into more simplified formats (and/or language) so that it is easier for beginners to make progress with their ideas and not get stuck in "becoming programmers." The Wiring code gets interpreted to C code before compiling which enables users to mix C (and C++) with Wiring in one sketch.

Your code above is mixing C and Wiring syntax so you won't find all the info about the syntax in the Arduino docs but it is worth searching on keywords or terms you don't understand. The big thing that is done differently involves setting up and using the serial port. See the Arduino docs for Serial to see how it is done there (and how much simpler it is to understand).

I'll take a crude stab at describing the functionality (before I get too bored)...


This line defines a variable (in PROGMEM - EEPROM memory) named test as a 10 x 10 array of numbers (longs): e.g. there are 10 arrays and each one contains 10 numbers (in hexidecimal notation)

PROGMEM long test[10][10]={

This block calls a function (#defined at the top of the code) to set a port) and a function (at the bottom of the code) to reset the strip.

void setup() 
  STRIP_PINOUT;
  reset_strip();
}

void loop() 
{
  while (1) // i.e. do this forever
  {
    // send the test var, its length and the delay amount between each pattern
    send_pattern(test, 10, 50); 
    reset_strip();
  }
}

This function iterates through the passed var data (which is in this case the var 'test'), read the value in the array at position [i][j] using an AVR function called pgm_read_dword_near and sends that value to the function send_strip which sends it out the serial port. After each array is sent, it calls delay() to wait for the number of milliseconds defined in rate.

void send_pattern(long data[][10], int length, int rate)
{
  int i=0;
  int j=0;

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

    delay(rate);

  }
}

OTHER TIPS

The meter long LED strip has 10 segments, each segment has three LED's, so even though there are 30 total LED's you can only control the 10 segments.

The LED strip has three wires, Red (power), Black (ground) and Green (signal).

Each segment takes a 24 bit Hex number to determine what color the LED will be. When a segment gets its 24 bits, it sets its color then transmits the rest of the signal to the next segment.

The signal is either High or Low, but for the chip receiving the signal it determines if it is a 1 or a Zero by the length of time it is High then Low. The manual that comes with the strip explains this better with pictures.

The timing of the Highs and Lows is controlled in the void send_strip(uint32_t data) method. The __asm__("nop\n\t") tells the micro controller to basically waste one cycle, so it is basically a very short delay (62.5ns on a 16MHz Arduino). I had to play around with the send_strip() method to get the timing right else all of the LEDs came on full white.

void send_pattern(long data[][10], int length, int rate) sends 10 colors to 10 segments of the LED strip. For the 1M strip this should be all of the LED's.

Each row in PROGMEM long test[10][10] is a set of colors for the Strip. In this case you have 10 variations for the strip.

I am currently playing with this strip so if more examples or explanations are needed please let me know.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top