Прошу помощи в алгоритме
- Войдите на сайт для отправки комментариев
Здравсвуйте. Пока жду детали для будущих веселий, решил поразвлечься с тем, что есть. А есть светодиоды. Я уже вдоволь намигался (в то мчисле плавно), поэтому решил написать программу, которая реализует один из любимейших моих эффектов - "бегущий огонёк". То есть 1 светодиод горит на полную, за и перед ним чуть менее ярко.
Нарисовал себе такую схему:
4 светодиода (больше у меня нет :( ), число - яркость для analogWrite(знаю, что подобраны плохо, но это прототип).
1 : 0-0-0-0 2 : 64-0-0-0 3 : 128-64-0-0 4 : 192-128-64-0 5 : 255-192-128-64 6 : 192-255-192-128 7 : 128-192-255-192 8 : 64-128-192-255 9 : 0-64-128-192 10: 0-0-64-128 11: 0-0-0-64 12: 0-0-0-0
Постепенно проходя в уме все этапы, начал писать программу:
//0 - not usable
byte leds_pin[4] = {4, 5, 6, 7};
int leds_level[4] = {64, 128, 192, 255};
byte led_now_level[4] = { 0, 0, 0, 0 };
int led_count = 4;
int levels_count = 3;
void setup() {
for (int i=0; i<4; i++) {
pinMode(leds_pin[i], OUTPUT);
}
}
void fire_run() {
//Пробегаемся по светодиодам
for (int i=0; i<led_count; i++) {
//Если ещё не горит,
if (led_now_level[i] == 0) {
//а предыдущий светодиод существует и уже горит, то зажжём
if ((i != 0) and (led_now_level[i-1] != 0)) {
led_now_level[i] = leds_level[0];
}
//Больше не повторяем
break;
}
}
//Теперь пробегаем по известным уровням
for (int i=0; i<=levels_count; i++) {
//Если светодиод не горит и перед ним тоже не горит
//(проверка в серединке нужна, что бы не выйти за границы массива)
//то грустно выходим
if ((led_now_level[i] == 0) and (i!=levels_count) and (led_now_level[i+1] == 0)) {
break;
}
//тут волшебство, которое будет правильно менять значения в led_now_level
}
}
void fire_visualiser() {
//тут просто проходим по led_now_level и зажигаем светодиоды с нужной яркостью
}
void loop() {
}
Но сразу заметил 2 недостатка:
адский фарш из if'ов
программа, несмотря на намёк на настраиваемость изначально жёстко пишется под 4 светодиода. это становится очевидно, если посмотреть на мои проверки во второй части fire_run()
Решил, что нужно остановиться и спросить совета.
Не подскажете, оптимальный алгоритм для осуществления задуманного? А может быть есть готовые примеры с реализацией такого эффекта?
Создайте один на всех массив яркостей:
#define maxLEDs 4 // число светодиодов в работе
#define maxIDX 10 // число уровней яркости в волне
int vPWM[maxIDX]={0,64,128,...}; // столько элементов, сколько нужно
запрограммируйте цикл, нечто вроде:
LED[0]=0; LED[1]=1; // ... while(1) { for(i=0;i<nLEDs;i++) { if (LED[i]<maxIDX) LED[i]++; else LED[i]=0; AnalogWrite(номер вывода, vPWM[LED[i]]); } }и начинайте его оптимизировать (те же выводы тоже просятся в массив). Подробнее писать времени нет - уезжаю. Надеюсь, помощники еще подтянутся...