Бегущий Светодиод

Sanart

✩✩✩✩✩✩✩
10 Окт 2021
12
0
Начал изучать Arduino. Поставил цель сделать бегущий светодиод с регулируемой паузой.
БЕЗ delay(). Использую библиотеку GyverTimer.
Уже день идёт мозговой штурм.(но ничего не выходит)
//*
Светодиоды подключены на D2 - D11, с общей землёй.
Огонёк должен бежать туда и обратно N количество раз, с определённой скоростью.
(Скетч того что есть на данный момент ниже)
//*
При работе моего кода загораются светодиоды на пирах D4,D5,D6,D9,D10,D11(в половину яркости), и больше ничего не происходит.

Прошу помочь с кодом.
 

Вложения

poty

★★★★★★✩
19 Фев 2020
3,261
948
@Sanart, @kDn на Вас нет! Он бы Вам объяснил, что такое state-aware код и атомарные операции...
В целом, давайте исправим сначала очевидное: оператор for имеет другой синтаксис, предполагающий, что первым внутри скобок будет стоять инициализация, потом - сравнение на окончание, потом - изменение на шаг. Вы как-то совсем по инициализации забили... led_pin у Вас - глобальная переменная. Подумайте, какое значение она будет иметь после setup?
Второе - то, что у Вас находится внутри цикла for: давайте подумаем, что произойдёт, даже если led_pin будет инициализирована?
1. led_pin = 2; digitalWrite(2, HIGH); tm.isReady = false (от tm.setInterval установлен в 5 секунд, значит "сработать" не успеет") - всё, что внутри if выполняться не будет. Загорится LED, подключенный к "ноге" 2.
2. led_pin = 3; digitalWrite(3, HIGH); tm.isReady = false (от tm.setInterval установлен в 5 секунд, значит "сработать" не успеет") - всё, что внутри if выполняться не будет. Загорится LED, подключенный к "ноге" 3. Будет гореть 2.
3. led_pin = 4; digitalWrite(4, HIGH); tm.isReady = false (от tm.setInterval установлен в 5 секунд, значит "сработать" не успеет") - всё, что внутри if выполняться не будет. Загорится LED, подключенный к "ноге" 4. Будут гореть 2-3.
4. led_pin = 5; digitalWrite(5, HIGH); tm.isReady = false (от tm.setInterval установлен в 5 секунд, значит "сработать" не успеет") - всё, что внутри if выполняться не будет. Загорится LED, подключенный к "ноге" 5. Будут гореть 2-4.
...
Через 5 секунд, на одном из циклов один из светодиодов выключится, но через несколько микросекунд включится снова....
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
3,261
948
А всего-то и надо - избавиться от for! Для глобальных таймеров цикл должен быть только loop()! Точно должен быть определён "статус" того, что выполняется сейчас. У Вас - это включенный в настоящее время светодиод (такой параметр есть, это - led_pin) и направление его перемещения (этого - нет, поэтому стоит в область глобальных переменных добавить:
int8_t direction = 1;
Я бы также уменьшил размерность led_pin - учитесь экономить адресное пространство:
int8_t led_pin;
В первый момент времени все выходы, кроме второго должны быть выключены, поэтому в setup должно быть:
C++:
for (led_pin = 2; led_pin <= 11; led_pin++) {
    pinMode(led_pin, OUTPUT);
    digitalWrite(led_pin, LOW);
  }
led_pin = 2;
digitalWrite(led_pin, HIGH);
Собственно в loop() должно быть то, что написано внутри тела for, что-то вроде:
C++:
if(tm.isReady()) {
    digitalWrite(led_pin, LOW);
    led_pin += direction;
    if (led_pin == 1 || led_pin == 12) {
        direction = -direction;
        led_pin += direction*2;
    }
    digitalWrite(led_pin, HIGH);
}
 
  • Лойс +1
Реакции: Sanart