Прошу помощи в алгоритме
- Войдите на сайт для отправки комментариев
Здравсвуйте. Пока жду детали для будущих веселий, решил поразвлечься с тем, что есть. А есть светодиоды. Я уже вдоволь намигался (в то мчисле плавно), поэтому решил написать программу, которая реализует один из любимейших моих эффектов - "бегущий огонёк". То есть 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,...}; // столько элементов, сколько нужно
запрограммируйте цикл, нечто вроде:
и начинайте его оптимизировать (те же выводы тоже просятся в массив). Подробнее писать времени нет - уезжаю. Надеюсь, помощники еще подтянутся...