Go Down

Topic: LED Matrix array on SD Card (Read 756 times) previous topic - next topic

mooop

Hi all,

I am sending an array of 400 rgb values to an Arduino Uno, which cannot handle it. The purpose is to then light up a 20x20 400 WS2812B LED Matrix.

I have tried just sending the data to the Arduino live with Python, which works, except it needs some delay in between each tuple, and it takes 20 seconds to send the data for 400 LEDs.

Here is the code I use to get the array from python through serial:

Code: [Select]
void serialEvent() {
  while (Serial.available()) {
   
    char inChar = Serial.read();


    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
   
    if (inChar == '[') {
      led=led+1;
      Serial.println("BEGIN OF LED");
      Serial.println(led);
      Serial.println("With rgb values:");
    }
   
    if (inChar == ',') {
      ledd[c]=inString.toInt();
      //matrix[led]=inString.toInt();
      //Serial.println(inString);
      inString="";
      c=c+1;
    }

    if (inChar == ']') {

      ledd[c]=inString.toInt();
     
      for (j = 0; j < 3; j++) {
        Serial.println(ledd[j]);
      }

      pixels.setPixelColor(led-1, pixels.Color(ledd[0],ledd[1],ledd[2])); // Moderately bright green color.
     
      pixels.show(); // This sends the updated pixel color to the hardware.
     
      //delay(100); // Delay for a period of time (in milliseconds).
     
      //Serial.println(inString);
      inString="";
      Serial.println("END OF LED ");
      Serial.println(led);
      c=0;

     
    }


This takes too long, so I can do it like this:

Code: [Select]
void serialEvent() {
  while (Serial.available()) {
   
    char inChar = Serial.read();


    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
   
    if (inChar == '[') {
      led=led+1;
      Serial.println("BEGIN OF LED");
      Serial.println(led);
      Serial.println("With rgb values:");
    }
   
    if (inChar == ',') {
      ledd[c]=inString.toInt();
      //matrix[led]=inString.toInt();
      //Serial.println(inString);
      inString="";
      c=c+1;
    }

    if (inChar == ']') {

      ledd[c]=inString.toInt();
     
      for (j = 0; j < 3; j++) {
        Serial.println(ledd[j]);

        matrix[led][j]=inString.toInt(); // This is too heavy and I get a memory error.
      }

      pixels.setPixelColor(led-1, pixels.Color(ledd[0],ledd[1],ledd[2])); // Moderately bright green color.
     
      pixels.show(); // This sends the updated pixel color to the hardware.
     
      //delay(100); // Delay for a period of time (in milliseconds).
     
      //Serial.println(inString);
      inString="";
      Serial.println("END OF LED ");
      Serial.println(led);
      c=0;

     
    }

    if (inChar=='a') {
      readarray=true;
    }
  }
}


But the array is too heavy. Any recommendation for an easy to use cheap sd card slot for Arduino on ebay, just to store my array?

Sketch uses 6,268 bytes (19%) of program storage space. Maximum is 32,256 bytes.
Global variables use 2,721 bytes (132%) of dynamic memory, leaving -673 bytes for local variables. Maximum is 2,048 bytes.

PaulS

Quote
Any recommendation for an easy to use cheap sd card slot for Arduino on ebay, just to store my array?
Your problem is not in reading the data fast enough. It is that you use the String class and the serialEvent() method.

Get rid of that. Read the serial data in loop() and use a NULL terminated char array.

The art of getting good answers lies in asking good questions.

mooop

#2
Mar 16, 2017, 06:52 pm Last Edit: Mar 16, 2017, 06:59 pm by mooop
But isn't the serialEvent method more convenient?

How do you make sure you get the right bytes with Serial.available()?

Thanks for you help!

mooop

I have tried using this code in loop as you suggest, and I still get a memory issue.

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

#define PIN            6
#define NUMPIXELS      20

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


String inputString = "";         // 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 ledd[3]={0,0,0};

int matrix[400][3];

void setup() {
  Serial.begin(9600);
}

void loop() {
 
  while (Serial.available()) {
 
    char inChar = Serial.read();
   
    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
   
    if (inChar == '[') {
      led=led+1;
      Serial.println("BEGIN OF LED");
      Serial.println(led);
      Serial.println("With rgb values:");
    }
   
    if (inChar == ',') {
      ledd[c]=inString.toInt();
      //matrix[led]=inString.toInt();
      //Serial.println(inString);
      inString="";
      c=c+1;
    }
   
    if (inChar == ']') {
   
      ledd[c]=inString.toInt();
     
      for (j = 0; j < 3; j++) {
      Serial.println(ledd[j]);
     
      matrix[led][j]=inString.toInt(); // This is too heavy and I get a memory error.
      }
   
    //pixels.setPixelColor(led-1, pixels.Color(ledd[0],ledd[1],ledd[2])); // Moderately bright green color.
    //pixels.show(); // This sends the updated pixel color to the hardware.
   
    inString="";
    Serial.println("END OF LED ");
    Serial.println(led);
    c=0;
    }
 
  }
}

PaulS

Quote
But isn't the serialEvent method more convenient?
Aren't crutches more convenient? I don't think so.

Quote
How do you make sure you get the right bytes with Serial.available()?
That question doesn't make sense. First, because the available() method only tells you how many bytes are in the buffer, waiting to be read. Second, because you can't make the bytes that have arrived be right. You have to send the right bytes in order to receive the right bytes.

Then, of course, you have to read them faster than they can arrive, but not faster than they do arrive. That is, you must read the data before the buffer fills up, and bytes start being discarded.

Part of doing that is NOT doing dynamic memory allocation EVERY time a character arrives. Use a static char array and an index, to read and store the data quickly.
The art of getting good answers lies in asking good questions.

Go Up