Вызов функции работает только при однократном вызове

У меня есть 3 цепочки светодиодов, все из которых сопоставлены с концентрическими кольцами. Каждое кольцо имеет собственный 2D-массив с номером цепи & номер светодиода. У меня есть функция, которая передает кольцевой массив, а затем зажигает соответствующий светодиод. Я использую FastLED

void lightUp(int ring_arr[][2], int i, int col){
  
  if(ring_arr[i][0] == 0){
      L0[ring_arr[i][1]] = CHSV(col, 255, 255);
    }
    if(ring_arr[i][0] == 1){
      L1[ring_arr[i][1]] = CHSV(col, 255, 255);
    }
    if(ring_arr[i][0] == 2){
      L2[ring_arr[i][1]] = CHSV(col, 255, 255);
  }
}

Это работает нормально, НО только если он вызывается один раз в loop(), если я делаю второй вызов, ни один из светодиодов не загорается. Таким образом, я могу зажечь 1 кольцо за раз, но если я попытаюсь зажечь 2 или более, то ничего не загорится. Кто-нибудь видит что-то очевидное, что я упускаю из виду?

Полный список кодов,

#include <FastLED.h>

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))
#define DATA_0 5
#define DATA_1 6
#define DATA_2 7
#define NUM_LEDS 50 

CRGB L0[NUM_LEDS];
CRGB L1[NUM_LEDS];
CRGB L2[NUM_LEDS];

// Кольца
int ring_1[][2] = {{0,0}, {0,1},  {0,2},  {0,3},  {1,49}, 
                   {1,28}, {1,29}, {1,30}, {1,31}, {1,32},
                   {1,23}, {1,24}, {1,25}, {1,26}, {1,27},
                   {1,2},  {1,3},  {1,4},  {1,5},  {1,6},
                   {1,0},  {1,1},  {2,0},  {2,1},  {2,2}, 
                   {2,19}, {2,20}, {2,21}, {2,22}, {2,23},
                   {2,24}, {2,25}, {2,26}, {2,27}, {2,28},
                   {2,45}, {2,46}, {2,47}, {2,48}, {2,49},
                   {0,29}, {0,28}, {0,27}, {0,26}, {0,25},
                   {0,4},  {0,5},  {0,6},  {0,7},  {0,8}};
                  
int ring_2[][2] = {{1,48}, {1,33}, {1,22}, {1,7},  {2,3}, 
                   {2,18}, {2,29}, {2,44}, {0,24}, {0,9}};

int ring_3[][2] = {{1,47}, {1,34}, {1,21}, {1,8},  {2,4},
                   {2,17}, {2,30}, {2,43}, {0,23}, {0,10}};

int ring_4[][2] = {{1,46}, {1,35}, {1,20}, {1,9}, {2,5}, 
                   {2,16}, {2,31}, {2,42}, {0,22}, {0,11}};

int ring_5[][2] = {{1,45}, {1,36}, {1,19}, {1,10}, {2,6}, 
                   {2,15}, {2,32}, {2,41}, {0,21}, {0,12}};

int ring_6[][2] = {{1,44}, {1,37}, {1,18}, {1,11}, {2,7}, 
                   {2,14}, {2,33}, {2,40}, {0,20}, {0,13}};

int ring_7[][2] = {{1,43}, {1,38}, {1,17}, {1,12}, {2,8}, 
                   {2,13}, {2,34}, {2,39}, {0,19}, {0,14}};

int ring_8[][2] = {{1,42}, {1,39}, {1,16}, {1,13}, {2,9}, 
                   {2,12}, {2,35}, {2,38}, {0,18}, {0,15}};
                   
int ring_9[][2] = {{1,41}, {1,40}, {1,15}, {1,14}, {2,10}, 
                   {2,11}, {2,36}, {2,37}, {0,17}, {0,16}};
// Цвета
int col_1 = 0;
int col_2 = 160;
int col_3 = 96;


void setup(){
  
   // светодиод настроен
   FastLED.addLeds<WS2811,DATA_0,RGB>(L0, NUM_LEDS);
   FastLED.addLeds<WS2811,DATA_1,RGB>(L1, NUM_LEDS);
   FastLED.addLeds<WS2811,DATA_2,RGB>(L2, NUM_LEDS);
   FastLED.setBrightness(255); 
   clearAll();
}

void loop() 
{

  for(int i; i < NELEMS(ring_1); i++){
    lightUp(ring_1, i, col_1);
  }

  for(int i; i < NELEMS(ring_2); i++){
    
// lightUp(ring_2, i, col_2); // если я раскомментирую любой из них
// lightUp(ring_3, i, col_3); // светодиоды не горят
// lightUp(ring_4, i, col_1);
// lightUp(ring_5, i, col_2);
// lightUp(ring_6, i, col_3);
// lightUp(ring_7, i, col_1);
// lightUp(ring_8, i, col_2);
// lightUp(ring_9, i, col_3);
    
  }

  FastLED.show();
  delay(1000);
}

void clearAll(){
  for(int i; i < NUM_LEDS; i++){
    L0[i] = CHSV(0, 0, 0);
    L1[i] = CHSV(0, 0, 0);
    L2[i] = CHSV(0, 0, 0);
  }
  FastLED.show();
}

void lightUp(int ring_arr[][2], int i, int col){
  
  if(ring_arr[i][0] == 0){
      L0[ring_arr[i][1]] = CHSV(col, 255, 255);
    }
    if(ring_arr[i][0] == 1){
      L1[ring_arr[i][1]] = CHSV(col, 255, 255);
    }
    if(ring_arr[i][0] == 2){
      L2[ring_arr[i][1]] = CHSV(col, 255, 255);
  }
}

, 👍-1

Обсуждение

что произойдет, если вы запустите первый цикл for дважды?, @jsotola

@jsotola светодиоды не загораются, @DrBwts


1 ответ


Лучший ответ:

3

В ваших циклах for отсутствует инициализация. Вы должны написать

for (int i = 0; i < NELEMS(ring_1); i++)

но вы пропустили часть = 0. Это означает, что переменная i заканчивается неинициализированный и содержит все, что осталось в этой ячейке памяти что бы ни использовало эту память раньше. Поведение в такой ситуации вообще непредсказуемо. Однако можно предположить, что i второй цикл может быть размещен в том же месте, что и i первого петля. Если это происходит, то второй цикл начинается с i=3 и заканчивается пустой цикл.

В качестве побочного примечания (совершенно не связанного с этим) вы можете собрать свои три L* массивы в один двумерный массив. Это сделало бы lightUp() значительно более проще:

void lightUp(int ring_arr[][2], int i, int col) {
    L[ring_arr[i][0]][ring_arr[i][1]] = CHSV(col, 255, 255);
}

или, может быть, было бы понятнее так:

void lightUp(int *location, int col) {
    L[location[0]][location[1]] = CHSV(col, 255, 255);
}

Вызывается как lightUp(ring_1[i], col_1);.

,

Пусть это будет уроком для тех, кто слишком часто переключается между Python и C++. Кроме того, почему вопрос получил отрицательный голос?, @DrBwts