Go Down

Topic: Flying LED matrix (Read 2738 times) previous topic - next topic



New to the forum and arduino. I have a QuadCopter that I want to modify with a round matrix of LPD8806 RGB LED strips. I have a sample now that I am playing around with to see if my concept will even work. I am also new to C programing so I need a little advice. I want to arranged the LEDs in a radial pattern around the base of the quad, see attached pic. They will be wired in a serpentine manner with the data connections going totally through the entire array and with new power connections every meter of the LED strip. A small example of the array is below. With 0 being the first spoke in the array and 11,12 and 23 being the start of the next 3 spokes.

0   1   2   3   4   5
11   10   9   8   7   6
12   13   14   15   16   17
23   22   21   20   19   18

I want to be able to address each individual spoke and be able to send the entire spoke one color. In addition I would also like to address each, what I will call a ring in the same manner. The first ring being 0,11,12,23 and the second being 1,10,13,22

That being said and since the addresses of the strip can't easily (not sure about this) produced with a regular for loop, I am at a loss as to how to start to program for this array. Can anyone point in the correct direction.... Thanks in advice that you can give this poor lost soul.




That might get you going in the right direction.

good luck, and post results.



I have seen that post before and the guy custom programs a chip not an Arduino in assembler and not c. Where I need some help is working with the arrays as I have never used them before and I want to learn using this project.



Heres the code to run a 4x4x4 LED cube. It uses a loop to cycle through each of the 4 layers, and another loop and an array to hold the data for each column in a single plane. Its not exactly what you want, but its an example of how you may do something similar.

Code: [Select]
// OCT32012 editing changes to adapt this program to work with shift registers,
// and to work with Common Cathode LED cube. hippynurd@gmail.com

#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash

#define CUBESIZE 4
#define PLANETIME 3333 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 10 // multiplies DisplayTime to get ms - why not =100?

// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation
prog_uchar PROGMEM PatternTable[] = {
// blink on and off

// NOTE: Most of the data was snipped out to fit in this forum posting

// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0

** Defining pins in array makes it easier to rearrange how cube is wired
** Adjust numbers here until LEDs flash in order - L to R, T to B
** Note that analog inputs 0-5 are also digital outputs 14-19!
** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
// Just a note to say we dont do things this way anymore. Data is serialized
// to pin 7 via 74hc595 shift registers, and the planes(layers) are controlled
// by pins 11,10,9,6. The first shift register controls the first 8 pins, the
// second shift register controls pins 9-16.
// Looking down on the cube, the column pin matrix looks like this:

// 16 15 14 13
// 12 11 10  9
//  8  7  6  5 
//  4  3  2  1

// This code is for common cathnode, meaning ground the plane(layer), and send 5 volts to
// the column to illuminate the individual led.

//int LEDPin[] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 15};
//int PlanePin[] = {16, 17, 18, 19};
int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int PlanePin[] = {11, 10, 9, 6};
int dataPin = 7; //Data  I added these for Shift Register
int clockPin = 12; // Clock
int latchPin = 13; // Latch

// initialization
void setup()
int pin; // loop counter
// set up LED pins as output (active HIGH)
for (pin=0; pin<PLANESIZE; pin++) {
pinMode( LEDPin[pin], OUTPUT );
// set up pins for serial output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

// set up plane pins as outputs (active LOW)
for (pin=0; pin<CUBESIZE; pin++) {
pinMode( PlanePin[pin], OUTPUT );

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
// declare variables
byte PatternBuf[PLANESIZE]; // saves current pattern from PatternTable
int PatternIdx;
byte DisplayTime; // time*100ms to display pattern
unsigned long EndTime;
int plane; // loop counter for cube refresh
int patbufidx; // indexes which byte from pattern buffer
int ledrow; // counts LEDs in refresh loop
int ledcol; // counts LEDs in refresh loop
int ledpin; // counts LEDs in refresh loop
int pinState; //pinState is used to send the correct bit to the data pin

// Initialize PatternIdx to beginning of pattern table
PatternIdx = 0;
// loop over entries in pattern table - while DisplayTime>0
do {
// read pattern from PROGMEM and save in array
memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
PatternIdx += PLANESIZE;
// read DisplayTime from PROGMEM and increment index
DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );
// compute EndTime from current time (ms) and DisplayTime
EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;

// loop while DisplayTime>0 and current time < EndTime
while ( millis() < EndTime ) {
patbufidx = 0; // reset index counter to beginning of buffer
// loop over planes
for (plane=0; plane<CUBESIZE; plane++) {
// turn previous plane off (low is on, high is off)
if (plane==0) {
digitalWrite( PlanePin[CUBESIZE-1], HIGH );
} else {
digitalWrite( PlanePin[plane-1], HIGH );

// load current plane pattern data into ports
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
// I used code from shiftout, to redo this to serialize the plane data
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite(clockPin, 0);
// digitalWrite( dataPin, PatternBuf[patbufidx] & (1 << ledcol) );
if (PatternBuf[patbufidx] & (1 << ledcol))
      pinState= 1;  // Flip these bits to suit your cubes common lead (cathode or anode)
      pinState= 0;  // Flip these bits to suit your cubes common lead (cathode or anode)

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState); // this is where data is sent to the shift register.
    //register shifts bits on upstroke of clock pin
    digitalWrite(clockPin, 1);

digitalWrite(latchPin, 1);

// turn current plane on (plane high for on)
digitalWrite( PlanePin[plane], HIGH );
// delay PLANETIME us
delayMicroseconds( PLANETIME );
} // for plane
} // while <EndTime
} while (DisplayTime > 0); // read patterns until time=0 which signals end



How many LEDs do you plan on having on your copter?? and what are you using to power and control them?

The best way is to just write the array as you'd like the LEDs to appear. even if they seem out of order when you call them from a 'for' command will find that they will all come up as the some color.

something like this...

Code: [Select]
   for (int i=0 ; i < 20; i++) {
    strip.setPixelColor(ARRAY1[i], 127,127,127);

im not sure if that 100% correct but it should get you started.

also look here for a good explanation of arrays http://arduino.cc/en/Reference/Array and here http://arduino.cc/en/Reference/For on For commands.

Hope this helps



Your text description suggests that you plan to use zero-based indexing, but your picture doesn't show an LED zero.  Your first LED appears to be numbered as "1."  So, your description of how you intend to address the spokes and rings doesn't match the numbering on the photograph.  I'll presume that you intend for the LED marked as "1" to be LED "0," and that the numbers shown for all the other LEDs are higher than the address that you intend to use by 1.

I don't see that an array implementation is necessary for what you want to do.  There seems to be enough symmetry for an address calculation to work:

  • Even-numbered spokes have these LED addresses:  6*n + k, for even integer 0 <= n < 64, and integer 0 <= k < 6.

  • Odd numbered spokes have these LED addresses: 6*n + 5 - k, for odd integer 0 <= n < 64, and integer 0 <= k < 6.

  • Expressed in these forms, the LED address advances outward for increasing k.  It's handy to express them in that fashion, since we'll want the addresses to progress in the same direction when we illuminate rings.

Using that information to calculate an LED's address, knowing its ring and spoke:
Code: [Select]
int LED_Address(int spoke, int ring) {
  if (spoke & 1) {
    return(6*spoke + 5 - ring);
  else {
    return(6*spoke + ring);

This project might be a bit complex as a first foray into using arrays.  Unless you're confident in your ability to address and control the LEDs, it'll be difficult to tell the difference between program issues and hardware interface problems.  Simple programming exercises using arrays are abundant on the web - google "c arrays exercises" to find a gazillion of them.  I'd recommend starting with something simpler, like outputting values to the screen, until you feel like you understand the concept and the techniques.  It won't take long.

Go Up