Странный артефакт при записи в последовательный порт во время выполнения цикла
Надеюсь, вы это видите.
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])» в основном цикле?
@DevilWAH, 👍0
Обсуждение1 ответ
Лучший ответ:
В вашем коде 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
- 7-сегментный дисплей с WS2312B и FastLED
- Библиотека FastLED: Как настроить яркость одного пикселя в абсолютном масштабе?
- Адресная RGB-полоса работает по отдельности, но не может настроить все светодиоды на полностью белый цвет.
- FastLED fill_rainbow - Неожиданный красный пиксель
- Какие библиотеки для часов реального времени DS1302 и светодиодной ленты WS2811 не конфликтуют?
- Как читать текстовый файл построчно
- Быстродействующий массив fill_solid
- Управление светодиодной лентой с помощью ИК-контроллера с помощью Arduino
Использование цикла
i
внутри циклаi
— очень плохая практика. Никогда не вставляйте одну и ту же переменную таким образом — невозможно понять, что вы намереваетесь сделать., @MajenkoПривет, я действительно так думал, но пошел и изменил это. Я должен признаться, что я очень хакерский программист (не уверен, что могу себя так называть, это оскорбление настоящих). Добавлю в список того, чего делать нельзя., @DevilWAH