问题
As of my last question on SO I'm working on an interactive 14x14 LED table which is being controlled by an Arduino Mega (for further information about the setup and code have a look here. After fixing the problem with data arriving at the Arduino in the wrong order I'm now facing this problem:
In order to control the colours of each pixel on the LED table using Adafruit's NeoPixel library I read in an array of the form int[14][14][3]. This works fine now, but when I try to set the RGB values for MORE than 7 LED strips regarding to the corresponding data nothing happens. I also have several Serial.println()
calls to check what data is read and if I'm running more than 7 LED strips 0
is printed for every possible value.
The basic functionality of controlling the LEDs works perfectly - I can also process and output the data described above correctly to the LED strips as long as I don't use more than 7 strips. The problem is that it doesn't matter if I declare more than these 7 strips alltogether in one array or split them. Also initializing them seperately doesn't work as well as creating one instance of the strip and reassigning the pin for it every time I want to use a different strip.
My code currently looks like this and I'm literally clueless what could be the reason for this problem or how I could solve it.
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PINROW0 0
#define PINROW1 1
#define PINROW2 2
#define PINROW3 3
#define PINROW4 4
#define PINROW5 5
#define PINROW6 6
#define PINROW7 7
#define PINROW8 8
#define PINROW9 26
#define PINROW10 28
#define PINROW11 30
#define PINROW12 32
#define PINROW13 34
#define NUMPIXELS 14 //Anzahl der Pixel pro Reihe
/*Adafruit_NeoPixel row0 = Adafruit_NeoPixel(NUMPIXELS, PINROW0, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row1 = Adafruit_NeoPixel(NUMPIXELS, PINROW1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row2 = Adafruit_NeoPixel(NUMPIXELS, PINROW2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row3 = Adafruit_NeoPixel(NUMPIXELS, PINROW3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row4 = Adafruit_NeoPixel(NUMPIXELS, PINROW4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row5 = Adafruit_NeoPixel(NUMPIXELS, PINROW5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row6 = Adafruit_NeoPixel(NUMPIXELS, PINROW6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row7 = Adafruit_NeoPixel(NUMPIXELS, PINROW7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row8 = Adafruit_NeoPixel(NUMPIXELS, PINROW8, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row9 = Adafruit_NeoPixel(NUMPIXELS, PINROW9, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row10 = Adafruit_NeoPixel(NUMPIXELS, PINROW10, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row11 = Adafruit_NeoPixel(NUMPIXELS, PINROW11, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row12 = Adafruit_NeoPixel(NUMPIXELS, PINROW12, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row13 = Adafruit_NeoPixel(NUMPIXELS, PINROW13, NEO_GRB + NEO_KHZ800);
*/
//Adafruit_NeoPixel currentStrip = Adafruit_NeoPixel(NUMPIXELS, pins[0], NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel row[] = { //Initialisieren des Arrays, das die addressierbaren LED Streifen im Adafruit Format enthält
Adafruit_NeoPixel(NUMPIXELS, PINROW0, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW4, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW5, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW6, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW7, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW8, NEO_GRB + NEO_KHZ800)/*,
Adafruit_NeoPixel(NUMPIXELS, PINROW9, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW10, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW11, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW12, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PINROW13, NEO_GRB + NEO_KHZ800)*/
};
#define DELAY 1000 //Refresh Zyklus auf 10 Millisekunden setzen
#define NUMSTRIPS 9/*(sizeof(row)/sizeof(row[0]))*/ //Anzahl der verbundenen LED Streifen definieren
int values[14][14][3];
String matrixAsString = "";
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
/*Seriellen Port über den der Pi sich mit dem Arduino verbindet einrichten*/
Serial.begin(115200); //setzen der Bitrate auf 115200 Bit pro Sekunde
Serial.setTimeout(100000);
/*NeoPixel Library initialisieren*/
for (int i = 0; i < NUMSTRIPS; i++) {
row[i].begin();
row[i].show();
}
}
void process(String matrixAsString) {
DynamicJsonDocument doc(4372);
Serial.println(matrixAsString);
deserializeJson(doc, matrixAsString);
Serial.println((int)(doc[2][10][0]));
Serial.println((int)(doc[2][10][0]));
Serial.println((int)(doc[5][10][0]));
Serial.println((int)(doc[0][1][2]));
Serial.println((int)(doc[0][0][1]));
for (int i = 0; i < NUMSTRIPS; i++) {
for (int j = 0; j < NUMPIXELS; j++) {
for (int k = 0; k < 3; k++) {
values[i][j][k] = (int)(doc[i][j][k]);
}
}
}
}
void paint() {
int r = 0;
int g = 0;
int b = 0;
for (int i = 0; i < NUMSTRIPS; i++) {
for (int j = 0; j < NUMPIXELS; j++) {
r = values[i][j][0];
g = values[i][j][1];
b = values[i][j][2];
row[i].setPixelColor(j, row[i].Color(r, g, b));
row[i].show();
}
}
}
//infinite loop refreshing the matrix
void loop() {
while (Serial.available()) {
char c = Serial.read();
matrixAsString += c;
if (c == '\n') {
process(matrixAsString);
paint();
matrixAsString = "";
}
}
}
As of the official Adafruit Documentation the library is designed to have as many strips connected as the Arduino is able to support so there has to be a solution.
To test my code I'm using this data which is a String representation of a randomly generated 14x14 RGB matrix:
[[[0,0,0],[1,0,0],[1,1,0],[2,1,0],[2,2,0],[3,2,0],[3,3,0],[3,3,1],[3,3,2],[3,3,3],[4,3,3],[4,4,3],[5,4,3],[5,4,4]],[[6,4,4],[7,4,4],[7,5,4],[7,6,4],[7,7,4],[7,7,5],[7,7,6],[7,7,7],[7,7,8],[8,7,8],[8,8,8],[8,9,8],[8,10,8],[8,11,8]],[[8,11,9],[8,11,10],[9,11,10],[9,11,11],[9,12,11],[9,12,12],[9,13,12],[10,13,12],[10,13,13],[10,13,14],[10,13,15],[11,13,15],[11,14,15],[11,15,15]],[[12,15,15],[12,15,16],[12,15,17],[13,15,17],[13,16,17],[13,16,18],[14,16,18],[14,17,18],[15,17,18],[15,17,19],[15,18,19],[15,18,20],[15,19,20],[15,19,21]],[[15,20,21],[15,21,21],[16,21,21],[17,21,21],[17,22,21],[18,22,21],[19,22,21],[19,23,21],[20,23,21],[20,23,22],[20,23,23],[20,24,23],[20,25,23],[20,26,23]],[[21,26,23],[22,26,23],[22,27,23],[23,27,23],[23,27,24],[24,27,24],[24,27,25],[24,28,25],[24,28,26],[24,29,26],[24,29,27],[24,29,28],[24,30,28],[25,30,28]],[[25,30,29],[25,31,29],[25,31,30],[26,31,30],[27,31,30],[27,32,30],[27,32,31],[27,33,31],[27,34,31],[27,35,31],[27,35,32],[28,35,32],[28,36,32],[29,36,32]],[[29,37,32],[29,37,33],[29,38,33],[29,38,34],[30,38,34],[31,38,34],[32,38,34],[33,38,34],[33,39,34],[33,39,35],[33,39,36],[33,40,36],[33,40,37],[33,41,37]],[[33,42,37],[33,42,38],[33,42,39],[33,42,40],[33,43,40],[33,43,41],[33,43,42],[33,44,42],[33,45,42],[33,45,43],[33,46,43],[34,46,43],[34,47,43],[35,47,43]],[[36,47,43],[37,47,43],[38,47,43],[38,47,44],[39,47,44],[39,47,45],[39,48,45],[40,48,45],[40,48,46],[40,49,46],[41,49,46],[41,50,46],[41,51,46],[41,51,47]],[[42,51,47],[42,51,48],[43,51,48],[43,51,49],[43,52,49],[43,53,49],[43,54,49],[43,54,50],[44,54,50],[44,55,50],[45,55,50],[45,55,51],[46,55,51],[47,55,51]],[[48,55,51],[48,56,51],[48,57,51],[48,58,51],[48,58,52],[48,58,53],[48,59,53],[48,59,54],[48,60,54],[48,60,55],[48,60,56],[48,60,57],[49,60,57],[49,61,57]],[[49,62,57],[49,62,58],[49,63,58],[49,63,59],[50,63,59],[50,64,59],[50,65,59],[51,65,59],[52,65,59],[53,65,59],[54,65,59],[54,66,59],[54,66,60],[54,67,60]],[[55,67,60],[56,67,60],[57,67,60],[58,67,60],[59,67,60],[59,67,61],[59,68,61],[59,69,61],[60,69,61],[61,69,61],[61,69,62],[61,69,63],[61,70,63],[61,71,63]]]
Thank you in advance for your help and I'm very grateful for any tip or suggestion provided.
回答1:
You've got only 8kB of ram and you are using:
int values[14][14][3];
=> 1176 bytes on this array (instead of half, if you'd use byte/uint8_t instead of int)- Freaking
String matrixAsString = "";
and+=
operator on it. That'd seriously messes up memory (in a terms of memory fragmentation). DynamicJsonDocument doc(4372);
allocates another huge amount of memory- not to mention, each strip has it's own pixel memory so
values
array is little bit extraneous - maybe it's possible to use the same buffer for reading and json parser? That might save a lots
So according to that, you have to be out of memory
Anyway, I'd use some decent ARM and DMA magic (for example 16 channels at once on STM32 MCUs) without much interaction of CPU for sending it out. Or existing solution like OctoWS2811 LED Library
来源:https://stackoverflow.com/questions/56370401/adafruit-neopixel-library-doesnt-work-when-addressing-more-than-7-led-strips