Сокращение рутинного кода neopixel
Я работал над уровнемером с полосой neopixel (WS2812).
Код очень прост: считывание потенциометра, отображение входного сигнала и отображение выходного сигнала на светодиодной ленте.
Пока все идет так хорошо. Код, который я включаю ниже, работает нормально, но, очевидно, уродливый и повторяющийся. Поскольку мои знания в программировании очень слабы, я задаюсь вопросом, есть ли какой-нибудь циклический способ сократить код. Пожалуйста, обратите внимание, что семь светодиодов имеют разные цвета. На самом деле это самый запутанный момент для меня при построении цикла. Есть идеи, ребята?
Да, я также знаю, что использование такого количества задержек не является элегантным решением mos, но это не ставит под угрозу производительность устройства, и появление светодиодной полосы довольно приятно.
void leveller () {
int millivolts;
int level;
millivolts = analogRead(A3);
level = map(millivolts, 0, 1024, 0, 7);
if (level <=0){
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
strip.show ();
}
else if ((level > 0)&&(level<1)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
}
else if ((level>= 1)&&(level<2)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
}
else if ((level>= 2)&&(level<3)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 3)&&(level<4)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 4)&&(level<5)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 5)&&(level<6)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(6, 0, 128, 32);
delay(30);
strip.show ();
}
else if (level>= 6) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(6, 0, 128, 32);
delay(30);
strip.show ();
strip.setPixelColor(7, 0, 128, 64);
delay(30);
strip.show ();
}
}
@Vidal, 👍1
Обсуждение1 ответ
Лучший ответ:
Во-первых, небольшое замечание:
if ((level > 0)&&(level<1))
уровень
- это целое число, и не существует целого числа, которое было бы одновременно строго
больше нуля и меньше единицы.
if ((level>= 1)&&(level<2))
Существует только одно целое число, которое проверяет это условие. Тогда было бы понятнее просто написать
if (level == 1)
Теперь, что касается вашего фактического вопроса: один трюк, который часто работает для сокращения повторяющегося кода, заключается в превращении кода в данные, хранении данных в массивах и прохождении через них с помощью циклов. Здесь последовательность цветов может быть сохранена в массиве:
const uint8_t colors[8][3] = {
{128, 0, 0},
{128, 32, 0},
{128, 64, 0},
{ 0, 128, 0},
{ 0, 128, 0},
{ 0, 128, 0},
{ 0, 128, 32},
{ 0, 128, 64},
};
Затем вы можете вызвать setPixelColor()
в цикле, который проходит через
массив. Поскольку конечная точка цикла зависит от измеренного уровня, ее
можно было бы записать следующим образом:
void leveller() {
int level = map(analogRead(A3), 0, 1024, 1, 9);
strip.clear();
for (int i = 0; i < level; i++) {
const uint8_t *color = colors[i];
strip.setPixelColor(i, color[0], color[1], color[2]);
strip.show();
delay(30);
}
}
Обратите внимание, что, поскольку выходной сигнал analogRead()
всегда меньше
1024, уровень переменной всегда будет меньше 9, т. Е. Он будет
принимать значения от 1 до 8 включительно. И это количество цветов
, которые будут показаны.
Великолепно! Он работал нормально с первой попытки. Большое спасибо за уроки программирования. С уважением из Испании., @Vidal
- Выход из цикла while с помощью ИК-пульта для neopixel
- Переключение между циклами Arduino ИК-пульт дистанционного управления
- Непрерывно запускайте функцию световой последовательности в операторе if
- Получить сокет в цикле arduino (прервать цикл while с помощью сокета)
- Управлять несколькими полосками WS2812B с разным количеством светодиодов.
- Мигните светодиодом 5 раз с помощью цикла for
- Чтение нескольких аналоговых входных контактов
- Как остановить цикл в последовательном мониторе?
простейшее сокращение .... не повторяйте код без необходимости .... у вас есть
if a>0 do x
...else if a>1 do x,y
...else if a>2 do x ,y,z
........ вместо этого сделайтеесли a>0 сделайте x
...если a>1 сделайте y
...если a>2 сделайте z
, @jsotola