20 X 40 LED Matrix project - help needed!

Status
Not open for further replies.

jrr

Member
I'm trying to make a controllable set of 20 LED strips that are 40 lights long. Planning on using the WS2812B strips for the project. These strips need to be controlled by 20 switches and I figure a 4 X 5 matrix for the switches would handle that.
What happens is each strip is controlled by a single button, and each LED advances one step per button press at first, then 1/2 along it takes two button presses, then at 3/4 it takes three button presses.

Whichever row completes first freezes the rest and lites a further LED (the winner!).

I am a bit too much of a neophyte to do this design from scratch, but can handle hardware easily. If someone can give me a bit of guidance as to scripts to use that would be great. Even one or two strips supported at first would be fine, I'm sure I can extrapolate from there.

As a further feature I would love to incorporate a simple active graphic when the system is idle...

Thanks!
 
If you haven't seen it already, you'll probably get a great deal of inspiration here:

http://pjrc.com/teensy/td_libs_OctoWS2811.html

In particular look at the VideoDisplay stuff, which should show you how to connect the LED strings end-to-end in a zigzag so you can end up with a 20x40 matrix using only 8 outputs from a single Teensy 3.x.

Cheers,
Dave
 
Hi Dave, thanks, I have looked there but am having trouble with setting up the basic test. I have a 3.1 Teensy, and modified Arduino 1.0.5 (patched with the Teensy update), however when I load and then verify BasicTest I get an error "expected contsructor, destructor, or type conversion before 'int'" and the line DMAME int displayMemory[ledsPerStrip*6]; is highlighted.
Now it may be because I don't recall how to compile the code and probably need to merge OctoW2811.h with BasicTest.ino - so I'm going to wander off and see if I can find the howto on that, but if you (or someone else) has a bright idea please feel free to let me know how I missed something really obvious. I don't mind learning!
Thanks!
 
Gah, after all that it turned out I had the Arduino.app configured for "Teensy++ 2.0" instead of 3.1! Changed to 3.1 and now the LED display is working correctly.

I hope I didn't waste too much of anyone's time!

Now to move on to controlling the LEDs individually by switches as in my first post.
 
OK, I've gone over to Sparkfun to try out their WS2812 scripts, but I have a problem - this is the script:

#include <Adafruit_NeoPixel.h>

#define PIN 2

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}

void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
rainbow(20);
rainbowCycle(20);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}


And this is the result:

Arduino: 1.0.5 (Mac OS X), Board: "Teensy 3.1"
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/arm-none-eabi/bin/arm-none-eabi-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mcpu=cortex-m4 -DF_CPU=96000000 -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -mthumb -nostdlib -D__MK20DX256__ -DTEENSYDUINO=117 -fno-rtti -felide-constructors -std=gnu++0x -DUSB_RAWHID -DLAYOUT_US_ENGLISH -I/Applications/Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy3 -I/../Arduino/libraries/Adafruit_NeoPixel /var/folders/aN/aNFmcZ3w2RWeak+8ZOYbV++++TI/-Tmp-/build1167403267062598903.tmp/strandtest.cpp -o /var/folders/aN/aNFmcZ3w2RWeak+8ZOYbV++++TI/-Tmp-/build1167403267062598903.tmp/strandtest.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/arm-none-eabi/bin/arm-none-eabi-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mcpu=cortex-m4 -DF_CPU=96000000 -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -mthumb -nostdlib -D__MK20DX256__ -DTEENSYDUINO=117 -fno-rtti -felide-constructors -std=gnu++0x -DUSB_RAWHID -DLAYOUT_US_ENGLISH -I/Applications/Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy3 -I/../Arduino/libraries/Adafruit_NeoPixel -I/../Arduino/libraries/Adafruit_NeoPixel/utility /../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp -o /var/folders/aN/aNFmcZ3w2RWeak+8ZOYbV++++TI/-Tmp-/build1167403267062598903.tmp/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp.o
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp: In member function 'void Adafruit_NeoPixel::show()':
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:773:3: error: 'Pio' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:773:19: error: 'port' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:774:12: error: 'WoReg' does not name a type
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:777:29: error: 'pmc_set_writeprotect' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:778:35: error: 'TC3_IRQn' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:778:43: error: 'pmc_enable_periph_clk' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:779:16: error: 'TC1' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:780:5: error: 'TC_CMR_WAVE' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:780:19: error: 'TC_CMR_WAVSEL_UP' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:780:38: error: 'TC_CMR_TCCLKS_TIMER_CLOCK1' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:780:64: error: 'TC_Configure' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:781:18: error: 'TC_Start' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:783:15: error: 'g_APinDescription' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:785:3: error: 'portSet' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:786:3: error: 'portClear' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:787:3: error: 'timeValue' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:788:3: error: 'timeReset' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:795:14: error: 'VARIANT_MCK' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:799:14: error: 'VARIANT_MCK' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:808:18: error: 'TC_CCR_CLKEN' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:808:33: error: 'TC_CCR_SWTRG' was not declared in this scope
/../Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp:818:17: error: 'TC_Stop' was not declared in this scope

OK, again the problem is 'simple', this script does not work with the 3.1 module, but works fine with ++2.

Interesting, but a bit frustrating as I thought that 3.1 was a superset of 2 and thus 2 code would work on 3.1 - however that is not the case.

In any case the Sparkfun does work on Teensy++ 2, so I'll play with that for now.

I need to find the differences between Teensy++ 2 and Teensy 3.1 it appears, and look for ways to work around them.
 
@JRR

A. You may want to open your own thread and not hijack another persons as your project involves different hardware ;-)

B. Maybe you want to check this Neopixel Library out. Found after 20 sec forum search on the term "neopixel" ;-)
 
@headroom

A. Not sure what you mean by hijacking as I had actually started this thread...and I am using Teensy hardware. Hmmm?

B. Thanks, however I already had loaded that library (note the script I quoted) and hadn't found any obvious way of selecting/stepping a single LED from the strip. I am not trying to make a video display, this is to be a race of single lights advancing on up to 20 parallel strips...
I am very new at coding for the Teensy or any Arduino device. Mostly I do hardware - repair equipment, do board design, etc. Software is not my area of expertise.

In any case once I changed to my Teensy++ 2.0 I could compile and run the script above, and by playing with the code I could change the colours, etc. on the WS2812 strip, but so far not able to get any single LED to turn on along the strip - say I just wanted LED #10 to light, then step to LED #11 etc. using a switch input. Switch input is straight forward, it's the code for stepping I'm lost on.

At this time I've asked a friend to help and so I'll see what we come up with and shall post notes back as I figure this out better.
 
With WS2812, you can't change just 1 LED without writing to all the ones before it.

The commonly used libraries (NeoPixel and OctoWS2811) are designed to update ALL the LEDs when you use their show() function. You first write to the pixels, which merely changes number in RAM. Then show() causes all the LEDs to be written.

That may seem very inefficient, just changing 3 bytes in RAM and then updating all the LEDs, just to change 1 of them. But that's the way it works.
 
Thanks, that is close to what we did to change one LED at a time. However it turns out that the strips are not bright enough for the application so I have to find another way to do programmable lights. Considering using the WS2811 and MOSFets to drive the heatsunk high intensity LEDs. Of course there is also the WS2803 which may be easier as the component count would go way down...
 
Status
Not open for further replies.
Back
Top