Странный артефакт при записи в последовательный порт во время выполнения цикла

Надеюсь, вы это видите.

https://gist.github.com/DevilWAH/60ad144d2858f53845ac2e80f84bb070

Основным файлом в этом случае является «morse-led-rfid», который считывает данные считывания RFID-метки, а затем отображает текст в виде азбуки Морзе на светодиодной ленте APA102 / Dotstar.

Проблема заключается в том, что функция updatestrip(tempbuffer[i]); называется.

Serial.println(F("\n**Start Reading**\n"));

  for (uint8_t i = 1; i < 15; i++)
  {
   if (i != 3 && i!= 7 && i != 11 && i != 15 ) // Пропускаем блоки без данных
    {
     readblock (i, key);
       for (uint8_t i = 0; i < 16; i++)
         {
      updatestrip(tempbuffer[i]);
      Serial.write(tempbuffer[i]);
        }
    }
  }

Это я призываю прокрутить светодиодную ленту и написать букву Морзе. если в приведенном выше фрагменте кода я закомментирую «updatestrip...», то я получу текстовый файл с принтера RFID-тегов на последовательный порт, как и ожидал.

как только я удаляю комментарий, полоска отображает азбуку Морзе, но последовательный вывод искажается, пропускает буквы, печатает перевернутые «?» и повторяется?

Хороший результат = «Мой кролик — лучший» Неверный вывод = «?Банни — это ?t» (вопросительные знаки перевернуты)

Дальнейшее исследование, которое я обнаружил, если я оставлю его без комментариев, но дойду до конца листа «more-strip» и закомментирую «оператор else в функцииshiftLED», серийный номер снова отобразится правильно, но, конечно, светодиод нет :)

void shiftLED() // shift all LED up 1 
  {
    for(uint16_t i = ledCount; i > 0; i--)
    {


      if ((colors[i - 1].red == 0 ) && (colors[i - 1].green == 0 ))
       {
          colors[i] = cblack;
        }
      else if (i > 19 && i < 40)
      {
        colors[i] = cred;
      }  
     // else 
     // {
     //   colors[i] = cgreen;
     // }
     // }


 }

Может ли кто-нибудь подсказать, почему оператор else, находящийся в нескольких функциях ниже, влияет на «serial.write(tempbuffer[i])» в основном цикле?

, 👍0

Обсуждение

Использование цикла i внутри цикла i — очень плохая практика. Никогда не вставляйте одну и ту же переменную таким образом — невозможно понять, что вы намереваетесь сделать., @Majenko

Привет, я действительно так думал, но пошел и изменил это. Я должен признаться, что я очень хакерский программист (не уверен, что могу себя так называть, это оскорбление настоящих). Добавлю в список того, чего делать нельзя., @DevilWAH


1 ответ


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

2

В вашем коде colors объявлен как

rgb_color colors[ledCount];

Это означает, что самая первая итерация этого цикла в shiftLED

for (uint16_t i = ledCount; i > 0; i--)
{
  // доступ к colors[i]
}

получит доступ к ledCount[ledCount], который явно выходит за пределы (и фактически запишет в это место!). После этого поведение не определено.

Использование беззнаковых типов для «обратной» итерации массива требует определенных навыков. Распространенные идиомы

for (uint16_t i = ledCount; i > 0;)
{
  --i; // делаем это как можно скорее

  // доступ к colors[i]
}

или

for (uint16_t i = ledCount; i-- > 0;)
{
  // access colors[i]
}

или

// Осторожно: этот метод нельзя использовать с беззнаковыми типами.
// уже, чем `unsigned int`
for (uint16_t i = ledCount - 1; i != -1; --i)
{
  // доступ к colors[i]
}

Предполагается, что вы хотите перебрать весь массив: от [ledCount - 1] до [0].

Но если вы намеревались вернуться к [1] и остановиться на [0] (что, по-видимому, так и есть), тогда простое решение для вашего цикла было бы

for (uint16_t i = ledCount - 1; i > 0; i--)
{
  // доступ к colors[i]
}

Т.е. просто начните с ledCount - 1, а не с ledCount.

,

ОЙ! поправьте меня, я ошибаюсь, но вы имеете в виду, что когда LEDCount = 60 действительные значения массива составляют от 0 до 59? поэтому доступ к цветам доступа [i] при i = LEDCount означает, что я пишу в позицию массива 60, а не 59! Что-то вроде буфера над потоком?, @DevilWAH

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

@DevilWAH Да, если LEDCount равен 60, то допустимые индексы для массива colors составляют от 0 до 59. Индекс 60 выходит за пределы., @AnT

Просто чтобы подтвердить, что во всем разобрались :) спасибо, что нашли время помочь и объяснить., @DevilWAH