Опытные пользователи, данного форума, отправили с моим вопросом в этот раздел форума.
С ардуино только начинается знакомство и моих знаний не хватает, чтобы понять что нужно изменить и добавить в ранее выложенном, пользователе Andycat ( Fade. Плавное разгорание и затухание светодиода. (analogWrite, PWM/ШИМ) - #2 от пользователя andycat ), коде плавного разгорания и затухания двух светодиодных лент.
Нужно сделать плавное включение и выключение лент не друг за другом, а включение и выключение второй ленты на середине яркости первой ленты.
Подскажите пожалуйста, что нужно подправить в этом коде.
static constexpr unsigned char pin_PWM_1out = 9; // Nano PB1 OC1A // пин 9 подключения драйвера светодиодной ленты 1
static constexpr unsigned char pin_PWM_2out = 11; // Nano PB3 OC2A // пин 11 подключения драйвера светодиодной ленты 2
static constexpr unsigned long stepChange = 10; // период изменения яркости, миллисекунд, фактически скорость повышения/понижения яркости, чем меньше число - тем быстрее
static constexpr unsigned long periodWait = 10000; // время ожидания движения при максимальной яркости лент, миллисекунд
enum tStatusWork { lStart = 0 /*начало*/, lToUP /*повышение яркости*/,
lToDOWN /*понижение яркости*/, lWaitMove /*ожидание движения при макс.яркости*/ }; // режимы работы
void setPWMout(unsigned char out1 /*яркость ленты 1*/, unsigned char out2 /*яркость ленты 2*/) { // функция установки яркости лент
analogWrite(pin_PWM_1out, out1); // установца ШИМ ленты 1
analogWrite(pin_PWM_2out, out2); // установца ШИМ ленты 2
}
void initPins(void) { // начальная инициализации пина датчика движения
pinMode(pin_RIP_in, INPUT); // режим пина - вход (по умолчанию, при включении МК, все пины и так в режиме входа)
digitalWrite(pin_RIP_in, LOW); // отключаем подтягивающий резистор (по умолчанию он и так отключен)
}
unsigned char readRIP(void) { // чтение пина датчика движения
static unsigned char lastLevel = 0; // хранение предыдущего значения пина - нет движения
unsigned char currLevel = digitalRead(pin_RIP_in); // читаем текущее состояние пина
if (currLevel != lastLevel) { // если прочитанное состояние пина не равно предыдущему
Serial.println(currLevel); // выведем в монитор порта (для отладки) текущее значение пина
digitalWrite(LED_BUILTIN, currLevel); // установим встроенный светодиод МК в состояние пина датчика движенния (удобно при отладке на реальном устройстве - видно работает датчик движения или нет)
lastLevel = currLevel; // присваиваем предыдущему значению пина текущее
}
return currLevel; // функция возвращает текущее значение пина датчика движения HC-SR501
}
// the setup function runs once when you press reset or power the board
void setup() { // стартовая функция при включении или сбросе МК
Serial.begin(115200); // инициализируем HW UART МК
pinMode(LED_BUILTIN, OUTPUT); // установка режима пина встроенного МК - выход
initPins(); // инициализируем пин датчика движения
setPWMout(0, 0); // гасим обе ленты
}
void workKitchenL(void) { // основная рабочая функция
static tStatusWork currentMode = lStart; // храним текущее значение режима работы
static unsigned char pwm1 = 0, pwm2 = 0; // текущая яркость лент
static unsigned long timerLastChange = 0; // таймер изменения яркости
static unsigned long timerWaitMove = 0; // таймер ожидания движения при максимальной яркости
switch (currentMode) { // работаем с логикой в зависимости от текущего режима
case lToUP: { // режим повышение ярккости
if ((millis() - timerLastChange) >= stepChange) { // если прошел шаг изменения яркости
timerLastChange = millis(); // обновим таймер изменения яркости
if (pwm1 < 255) { // если яркость первой ленты меньше максимальной
++pwm1; // увеличиваем яркость первой ленты
} else { // если яркость первой ленты максимальная - начинаем увеличивать яркость второй ленты
if (pwm2 < 255) { // если яркость второй ленты меньше максимальной
++pwm2; // увеличиваем яркость второй ленты
} else { // если яркость второй ленты максимальная
timerWaitMove = millis(); // обновляем таймер ожидания движения при максимальной яркости
currentMode = lWaitMove; // переходим в режим ожидания движения при максимальной яркости
}
}
setPWMout(pwm1, pwm2); // устанавливаем яркость лент
}
break;
}
case lToDOWN: { // режим понижения аркости
if (readRIP()) { // если есть движенние
currentMode = lToUP; // переходим в режим повышения аркости
} else { // если нет движения
if ((millis() - timerLastChange) >= stepChange) { // если прошел шаг изменения яркости
timerLastChange = millis(); // обновим таймер изменения яркости
if (pwm2) { // если яркость второй ленты больше нуля
--pwm2; // уменьшаем яркость второй ленты
} else { // если вторя лента не светится
if (pwm1) { // если яркость первой ленты больше нуля
--pwm1; // уменьшаем яркость первой ленты
} else { // если первая лента не светится
currentMode = lStart; // переходим в начальный режим
}
}
setPWMout(pwm1, pwm2); // устанавливаем яркость лент
}
}
break;
}
case lWaitMove: { // режим ожидания движения при максимальной яркости лент
if (readRIP()) { // если есть движение
timerWaitMove = millis(); // обновляем таймер ожидания
} else { // если нет движения
if ((millis() - timerWaitMove) >= periodWait) currentMode = lToDOWN; // если вышло время ожидания движения - переходим в режим уменьшения яркости лент
}
break;
}
default: { // lStart // начальный режим
if (readRIP()) { // если произошло движение
currentMode = lToUP; // переходим в режим повышения яркости лент
}
}
}
}
// the loop function runs over and over again until power down or reset
void loop() { // бесконечный цикл
workKitchenL(); // работаем
}