Go Down

Topic: Neopixel and SD card (Read 5802 times) previous topic - next topic

mooop

Hi all,

I have been trying to get this code to work this whole morning with no success. It is supposed to read LED values stored in a test.txt file on a sd card. And I do get the output on the Serial monitor, but for some reason it just doesnt light up the LEDs.

I have also tried just lighting up one LED with given values rather than the ones in the file, no success. The strip does work, i have tested it with the neo pixel demo library. I just don't understand what is wrong.

Here is my code, any help will be greatly appreciated.

Code: [Select]
#include <Time.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif
#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 4;

#define PIN            6
#define NUMPIXELS      400

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

char inputString[5000];         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
boolean readarray=false;
String inString = "";
int c=0;
int cc=0;
int led=0;
int i=0;
int j=0;
int pixel_n=0;
unsigned long start;
unsigned long endd;

//char* ledd[]={"", "", ""};
int ledd[3]={0,0,0};

File myFile;

void setup() {
  Serial.begin(115200);
  SD.begin(4);

  pixels.begin(); // This initializes the NeoPixel library.

  myFile = SD.open("test.txt");

  while (myFile.available()) {
   
      char inChar = myFile.read();
     
      if (isDigit(inChar)) {
        inString += (char)inChar;
      }

      if (inChar == '(') {
      led=led+1;

    }
   
    if (inChar == ',') {
      ledd[c]=inString.toInt();
      inString="";
      c=c+1;
    }

    if (inChar == ')') {

      ledd[c]=inString.toInt();
      inString="";

      pixels.setPixelColor(led, pixels.Color(ledd[0],ledd[1],ledd[2])); // THIS DOES NOT SEEM TO WORK
      pixels.show(); // THIS EITHER. IT DOESNT LIGHT UP THE LEDS
     
      Serial.println(ledd[0]);
      Serial.println(ledd[1]);
      Serial.println(ledd[2]);
   
      Serial.println("END OF LED ");
      Serial.println(led);
      c=0;
     
    }

    if (inChar=='*') {
      Serial.write("NEXT FRAME");
     
      myFile.close();
      break;
    }   
  }
}

void loop() {

}

Grumpy_Mike

Code: [Select]
pixels.setPixelColor(led, pixels.Color(ledd[0],ledd[1],ledd[2])); // THIS DOES NOT SEEM TO WORK
      pixels.show(); // THIS EITHER. IT DOESNT LIGHT UP THE LEDS
     

Because it is not how the call works.
The first parameter is the LED number, the second is the colour. What you have written is a nonsense.

mooop

I hear you but how is this a nonsense?

the variable led is a number, and the array ledd[] contains the led rgb values as ints. How is this a nonsense?

mooop

I have tried with the following as well:

pixels.setPixelColor(i, (250,250,250));

It just doesn't work. The data LED doesn't even light up the Arduino.

Grumpy_Mike

Quote
the variable led is a number, and the array ledd[] contains the led rgb values as ints. How is this a nonsense?
Because that call expects ONE number not an array of numbers.

mooop

Yes, ledd[0], ledd[1], ledd[2] all contain an individual number, do they not?

I thought maybe the problem was in the minimal code, with my variables declarations and libraries.

I tried this:

Code: [Select]
#include <Time.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN            6
#define NUMPIXELS      400

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  Serial.begin(9600);
  pixels.begin(); // This initializes the NeoPixel library.
      for (int i=0; i<NUMPIXELS;i++) {
    pixels.setPixelColor(i, (0,0,0));
  }
  pixels.show();

  delay(2000);
}

void loop() {

  for (int i=0; i<NUMPIXELS;i++) {
    pixels.setPixelColor(i, (25,250,250));
  }

  pixels.show();

  delay(20000);
 
}


Works like a charm. But if I add this extra code at the top, it doesn't work anymore. The LEDs don't respond.

Code: [Select]
#include <Time.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif
#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 4;

#define PIN            6
#define NUMPIXELS      400

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

boolean stringComplete = false;  // whether the string is complete
boolean readarray=false;
String inString = "";
int c=0;
int cc=0;
int led=0;
int i=0;
int j=0;
int pixel_n=0;
unsigned long start;
unsigned long endd;

//char* ledd[]={"", "", ""};
int ledd[3]={0,0,0};

File myFile;


void setup() {
  Serial.begin(9600);
  pixels.begin(); // This initializes the NeoPixel library.
      for (int i=0; i<NUMPIXELS;i++) {
    pixels.setPixelColor(i, (0,0,0));
  }
  pixels.show();

  delay(2000);
}

void loop() {

  for (int i=0; i<NUMPIXELS;i++) {
    pixels.setPixelColor(i, (25,250,250));
  }

  pixels.show();

  delay(20000);
 
}


Can it be a library/variable conflict?




mooop

I have tried the following simple code and it works, so it's not that @Grumpy_Mike:

Code: [Select]
  for (int i=0; i<NUMPIXELS;i++) {
    pixels.setPixelColor(i, (ledd[0],ledd[1],ledd[2]));
  }


It's when I include the SD libraries that it doesn't respond anymore. This is driving me crazy.

mooop

Maybe the Arduino cannot communicate with the SD card and the LED strip at the same time. So I tried storing each frame in a frame array matrix[400][3], then go through the array and light up the leds, and then flush the array at the end of each frame, but I get a memory error of course.


mooop

My problem seems related to this issue here:

https://arduino.stackexchange.com/questions/13698/use-led-on-pin-13-again-after-using-the-sd-library



The SPI bus apparently messes with the pins. So I need to close it after reading, except I need to send data to the strip while reading on the sd card.

Grumpy_Mike

But your code is not using pin 13 is it?

mooop

It's not, but it is clearly affecting my code. I am using pin 4 for SD card reading, and pin 6 for LED strip data line. When I do not include the libraries or initiate the SD card, everything is smooth. When I do include the SD libraries or try to interact with the SD card, I cannot send data to the LED strip anymore.

So it is the SD library for sure.


If at least I could first read the array on the SD card, close the SPI, store the array temporarily and use it, but I can't, my matrix is 400 x 3 rgb values.

This is really problematic. I have read about SDFat.h which apparently contains update for better SPI behavior. Any info on that? This is extremely inconvenient and problematic.

Grumpy_Mike

Just try and read one LEDs worth of data in, then shut down the SD card and try and write to the LEDs. It will tell you if that is the possibility of a fix.

mooop

Ok, thank you for your help again Grumpy_Mike,

I will try that tomorrow morning, for now I'm working on my animations!

mooop

I just tried. No luck. Even with SPI.end(). I just cannot access the strip anymore.

Code: [Select]
#include <Time.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif
#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 4;

#define PIN            6
#define NUMPIXELS      400

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

boolean stringComplete = false;  // whether the string is complete
boolean readarray=false;
String inString = "";
int c=0;
int cc=0;
int led=0;
int i=0;
int j=0;
int pixel_n=0;
unsigned long start;
unsigned long endd;

//char* ledd[]={"", "", ""};
int ledd[3]={0,0,0};

File myFile;

void setup() {


  pixels.begin(); // This initializes the NeoPixel library.
  pixels.show();

    Serial.begin(9600);
  SD.begin(4);


  myFile = SD.open("test.txt");

  while (myFile.available()) {
   
      char inChar = myFile.read();
     
      if (isDigit(inChar)) {
        inString += (char)inChar;
      }

      if (inChar == '(') {
      led=led+1;

    }
   
    if (inChar == ',') {
      ledd[c]=inString.toInt();
      inString="";
      c=c+1;
    }

    if (inChar == ')') {

      ledd[c]=inString.toInt();
      inString="";
     
      Serial.println(ledd[0]);
      Serial.println(ledd[1]);
      Serial.println(ledd[2]);
   
      Serial.println("END OF LED ");
      Serial.println(led);
      c=0;
     
    }

    if (inChar=='*') {
      Serial.write("NEXT FRAME");

      myFile.close();
      SPI.end();
      Serial.println("Ok we're done");
      delay(2000);

      pixels.setPixelColor(5, (200,200,200));
      pixels.show();
      break;
    }   
  }
 
}

void loop() {

}

mooop

Tried with the SdFat.h, no luck either.

It's really odd, this is a very common way of doing. I'm trying to find animation scripts.

Go Up