Библиотека Adafruit NeoPixel не работает при адресации более 7 светодиодных лент

Что касается моего последнего вопроса о SO, я работаю над интерактивным светодиодным столом 14x14, которым управляет Arduino Mega (дополнительную информацию о настройке и коде см. здесь. После устранения проблемы с поступлением данных в Arduino в неправильном порядке я столкнулся с этой проблемой:

Чтобы управлять цветами каждого пикселя на светодиодной таблице с помощью библиотеки Adafruit NeoPixel, я читал массив вида int[14][14][3]. Теперь это работает нормально, но когда я пытаюсь установить значения RGB для БОЛЕЕ 7 светодиодных лент относительно соответствующих данных, ничего не происходит. У меня также есть несколько вызовов Serial.println(), чтобы проверить, какие данные считываются, и если я использую более 7 светодиодных лент, 0 печатается для каждого возможного значения.

Базовая функциональность управления светодиодами работает отлично — я также могу правильно обрабатывать и выводить данные, описанные выше, на светодиодные ленты, если я не использую более 7 лент. Проблема в том, что не имеет значения, объявляю ли я больше этих 7 полос вместе в одном массиве или разделяю их. Также не работает их инициализация по отдельности, а также создание одного экземпляра полосы и переназначение для него вывода каждый раз, когда я хочу использовать другую полосу.

Мой код в настоящее время выглядит так, и я буквально не знаю, что может быть причиной этой проблемы или как я могу ее решить.

#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 = "";
    }

  }

}

Согласно официальной документации Adafruit, библиотека рассчитана на то, чтобы подключить столько полос, сколько Arduino может поддерживать, поэтому должно быть решение.

Чтобы проверить свой код, я использую эти данные, которые представляют собой строковое представление случайно сгенерированной матрицы RGB 14x14:

[[[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]]]

Заранее благодарю вас за вашу помощь, и я очень благодарен за любой совет или предложение.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
357
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас всего 8 КБ оперативной памяти, и вы используете:

  • int values[14][14][3]; => 1176 байт в этом массиве (вместо половины, если бы вы использовали byte/uint8_t вместо int)
  • Чёртовы String matrixAsString = ""; и += операторы на нём. Это серьезно испортит память (с точки зрения фрагментации памяти).
  • DynamicJsonDocument doc(4372); выделяет еще один огромный объем памяти
  • не говоря уже о том, что каждая полоса имеет свою собственную память пикселей, поэтому массив values немного посторонний
  • может быть, можно использовать один и тот же буфер для чтения и анализатора json? Это может сэкономить много

Итак, согласно этому, у вас должна быть нехватка памяти

В любом случае, я бы использовал приличную магию ARM и DMA (например, 16 каналов одновременно на микроконтроллерах STM32) без особого взаимодействия с ЦП для его отправки. Или существующее решение, такое как Светодиодная библиотека OctoWS2811

Большое спасибо за ваши предложения и усилия. Вы совершенно правы, причиной испорченного поведения были проблемы с памятью. К счастью, вчера утром (К вашему сведению, смотрите здесь) мне уже удалось решить проблему с помощью команды Adafruit. Окончательное решение заключалось в том, чтобы полностью отказаться от подхода с использованием JSON, поскольку из-за его компонентов-оболочек он разворачивался примерно до ~ 11-18 КБ во время десериализации. Теперь я отправляю и читаю байты, пока на Arduino не будет получено достаточно данных для одной полной матрицы.

Samaranth 01.06.2019 12:59

Другие вопросы по теме