I'm doing a project driving a large amount (144) LEDs using Adafruit's NeoPixel library with FFT data and the wanted to use an external ATMega 2560-based board to drive them (there's enough memory on the 2560 to drive the project where the Teensy seems to have some trouble and it has 5V power). It seems to miscommunicate with the LED strip in the same configuration once I use the FFT function--it displays "copies" of the strip object another across the LED strip (for example, if I set the strip to be 3 pixels, the LED strip will display around 10 copies the same three-pixel pattern with synced time-dependent behavior right next to one another and three white pixels at the end). In projects without the FFT (i.e. Adafruit's strandtest), it handles a reasonable number of pixels just fine without the copying issue.
The strange thing is that when I use a different LED strip with fewer LEDs per inch, the same code works just like it's supposed to and doesn't do that odd repetition of the data on the strip. That strip is powered completely by the Teensy, though, and this one has external 5V power (and is also grounded to the 3.3V Teensy).
I feel that using an external board with 5V logic and more memory to drive the LEDs would solve the issue, but I may be wrong.
Is it possible to use a 3.3V Teensy and a 5V Arduino in a slave/master configuration, where I'd send the important numbers from Teensy's FFT to the Arduino Mega and send data to the strip from the latter? Any advice on how I could connect them?
Source code below:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Adafruit_NeoPixel.h>
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
#define LEDPin 8
AudioPlaySdWav wavPlayer;
AudioAnalyzeFFT1024 myFFT;
AudioAnalyzePeak peak;
AudioMixer4 mixer;
AudioOutputI2S audioOutput;
AudioConnection patchCord1(wavPlayer, 0, mixer, 0);
AudioConnection patchCord2(wavPlayer, 0, audioOutput, 0);
AudioConnection patchCord3(wavPlayer, 1, mixer, 1);
AudioConnection patchCord4(wavPlayer, 1, audioOutput, 1);
AudioConnection patchCord5(mixer, peak);
AudioConnection patchCord6(mixer, myFFT);
AudioControlSGTL5000 sgtl5000_1;
boolean isPlaying = false;
float currentPeak = 0.0;
float frequencyBands[3];
int numPeaks = 2;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPeaks, LEDPin, NEO_GRB + NEO_KHZ800);
void setup() {
AudioMemory(12);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
strip.begin();
strip.show();
}
void playFile(char *filename){
Serial.print("Playing file: ");
Serial.println(filename);
wavPlayer.play(filename);
}
elapsedMillis rms;
elapsedMillis fps;
void checkAudio(){
if(rms > 30){
if(peak.available()){
rms=0;
currentPeak = peak.read();
}
}
if(myFFT.available()){
frequencyBands[0] = myFFT.read(0, 10)*255;
frequencyBands[1] = myFFT.read(6, 32)*180;
frequencyBands[2] = myFFT.read(16, 360)*20;
}
int rOut = (int) frequencyBands[0];
rOut = min(rOut, 255);
int gOut = (int) frequencyBands[1];
gOut = min(gOut, 255);
int bOut = (int) frequencyBands[2];
bOut = min(bOut, 255);
pushToLEDs(currentPeak, strip.Color(rOut,gOut,bOut));
}
void pushToLEDs(float currentPeak, uint32_t color){
int numberOfLEDs = (int) (currentPeak*(strip.numPixels()+.1));
for(int i=0; i<strip.numPixels(); i++){
strip.setPixelColor(i, color);
if(i>=numberOfLEDs){
strip.setPixelColor(i, strip.Color(0,0,0));
}
strip.show();
}
}
void loop() {
if(!isPlaying){
delay(1000);
playFile("MOON.wav");
isPlaying = true;
}
checkAudio();
}
The strange thing is that when I use a different LED strip with fewer LEDs per inch, the same code works just like it's supposed to and doesn't do that odd repetition of the data on the strip. That strip is powered completely by the Teensy, though, and this one has external 5V power (and is also grounded to the 3.3V Teensy).
I feel that using an external board with 5V logic and more memory to drive the LEDs would solve the issue, but I may be wrong.
Is it possible to use a 3.3V Teensy and a 5V Arduino in a slave/master configuration, where I'd send the important numbers from Teensy's FFT to the Arduino Mega and send data to the strip from the latter? Any advice on how I could connect them?
Source code below:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Adafruit_NeoPixel.h>
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
#define LEDPin 8
AudioPlaySdWav wavPlayer;
AudioAnalyzeFFT1024 myFFT;
AudioAnalyzePeak peak;
AudioMixer4 mixer;
AudioOutputI2S audioOutput;
AudioConnection patchCord1(wavPlayer, 0, mixer, 0);
AudioConnection patchCord2(wavPlayer, 0, audioOutput, 0);
AudioConnection patchCord3(wavPlayer, 1, mixer, 1);
AudioConnection patchCord4(wavPlayer, 1, audioOutput, 1);
AudioConnection patchCord5(mixer, peak);
AudioConnection patchCord6(mixer, myFFT);
AudioControlSGTL5000 sgtl5000_1;
boolean isPlaying = false;
float currentPeak = 0.0;
float frequencyBands[3];
int numPeaks = 2;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPeaks, LEDPin, NEO_GRB + NEO_KHZ800);
void setup() {
AudioMemory(12);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
strip.begin();
strip.show();
}
void playFile(char *filename){
Serial.print("Playing file: ");
Serial.println(filename);
wavPlayer.play(filename);
}
elapsedMillis rms;
elapsedMillis fps;
void checkAudio(){
if(rms > 30){
if(peak.available()){
rms=0;
currentPeak = peak.read();
}
}
if(myFFT.available()){
frequencyBands[0] = myFFT.read(0, 10)*255;
frequencyBands[1] = myFFT.read(6, 32)*180;
frequencyBands[2] = myFFT.read(16, 360)*20;
}
int rOut = (int) frequencyBands[0];
rOut = min(rOut, 255);
int gOut = (int) frequencyBands[1];
gOut = min(gOut, 255);
int bOut = (int) frequencyBands[2];
bOut = min(bOut, 255);
pushToLEDs(currentPeak, strip.Color(rOut,gOut,bOut));
}
void pushToLEDs(float currentPeak, uint32_t color){
int numberOfLEDs = (int) (currentPeak*(strip.numPixels()+.1));
for(int i=0; i<strip.numPixels(); i++){
strip.setPixelColor(i, color);
if(i>=numberOfLEDs){
strip.setPixelColor(i, strip.Color(0,0,0));
}
strip.show();
}
}
void loop() {
if(!isPlaying){
delay(1000);
playFile("MOON.wav");
isPlaying = true;
}
checkAudio();
}