Проект на ARDUINO - Ребят пожалуйста помогите новичку

ДД, есть проект, решил на нем изучить с++, но столкнулся с проблемой и все встала на этом.
Подсветка лестницы:
Два датчика движения на концах лестницы, при входе должны поочередно загореться ступеньки, при выходи погаснуть… На данный момент работаю с одним датчиком, второй сделаю по аналогии. Сделал через switch, но почему то в кейсах не работают таймеры! Объясните пожалуйста почему!


//подсветка ступеней леснтицы
#define PIR_UP    A3
#define PIR_DOWN  A2
#define STEP_1    A0
#define STEP_2    10
#define STEP_3    11
#define STEP_4    12
#define STEP_5    13
#define STEP_6    A1
int IO; 

uint32_t myTimer1;
uint32_t myTimer2;
uint32_t myTimer3;



void setup()

{Serial.begin(9600);

    
    pinMode(STEP_1,     OUTPUT); 
    pinMode(STEP_2,     OUTPUT); 
    pinMode(STEP_3,     OUTPUT); 
    pinMode(STEP_4,     OUTPUT); 
    pinMode(STEP_5,     OUTPUT); 
    pinMode(STEP_6,     OUTPUT);
    pinMode(PIR_UP,      INPUT);
    pinMode(PIR_DOWN,    INPUT); 
    delay (500);
    
}
void loop()
{
Serial.println("____________________");
Serial.print("myTimer1:");
Serial.println(millis()-myTimer1);
Serial.print("myTimer2:");
Serial.println(millis()- myTimer2);
Serial.print("myTimer3:");
Serial.println(millis()- myTimer3);
Serial.print("IO: ");
Serial.println(IO);
  delay(1000); 
// Если PIR_UP сработал то записываем значение 1 в IO и запускаем таймер myTimer1
  if (digitalRead(PIR_UP) == HIGH)                    
{
IO = 1; 
myTimer1=millis();
}
//Если IO == 1 и myTimer1 > 10с, то записываем значение 0 в IO
  if (IO == 1 && millis() - myTimer1 > 20000)
IO = 0; 

switch (IO)                                           
{
//Если IO == 1, то вывести на экран "case 1", однулить таймер myTimer2, выключить ступеньки и выйти из кейса
  case 1:                                                             
Serial.println("case 1"); 
myTimer2=millis(); 
  if(millis()- myTimer2 > 1000)
    digitalWrite(STEP_1, HIGH);
  if(millis()- myTimer2 > 2000)  
    digitalWrite(STEP_2, HIGH);     
  if(millis()- myTimer2 > 3000)
   digitalWrite(STEP_3, HIGH);
  if(millis()- myTimer2 > 4000)
    digitalWrite(STEP_4, HIGH);
    break;
   
 
  
 
 case 0:       
//Если IO == 0, то вывести на экран "case 0", однулить таймер myTimer3, выключить ступеньки и выйти из кейса                                         
Serial.println("case 0");
myTimer3=millis();
  if(millis()- myTimer3 > 1000)
    digitalWrite(STEP_4, LOW);
  if(millis()- myTimer3 > 2000)
    digitalWrite(STEP_3, LOW);
  if(millis()- myTimer3 > 3000)
    digitalWrite(STEP_2, LOW);
  if(millis()- myTimer3 > 4000)
    digitalWrite(STEP_1, LOW);
    break;

}

}

Даже не глядя на код, изначально подход не верен.
Если два датчика движения один на входе другой на выходе. Тогда логично реализовать счетчик вошедших\вышедших в помещении, все вышли - отключаем освещение. И не лишним будет в систему добавить датчик освещенности, для определения день\ночь и тем самым не включать свет когда он не нужен.
И вместо датчиков присутствия больше подойдут датчики пересечения ИК лучей.

так надо же не просто включать/выключать, а

Так это уже детали. Привязать направление включения можно к датчику. Получится конечный автомат (алгоритм с конечным числом состояний).

P. S.
В любом случае необходим счетчик количества шагающих по лестнице, и датчики движения в данном случае не верное решение. Такой датчик посылает множество импульсов (по каждому телодвижению).

Нет нет, это как раз важно! И я обязательно дальше наверное столкнусь с Вашим предложением про счетчик, но на данный момент мне не понятно почему не работает таймер, что именно я не так делаю!
uint32_t myTimer1; таймер вроде бы норм отрабатывает, а остальные два… я и через If и через while пробовал… буду очень благодарен если разъясните, не могу продвинутся дальше, если с азами не разобрался!

Так это ж никогда не сработает? 1000мс не успеют пройти между этими строками.

есть похожие решения в доступе, но там сделано через адресную LED ленту, а у меня аналоговая, реализация через мосфеты, и датчики движения вроде бы норм, думаю что с помочью того же millis() и переменной можно устранить “дребезг” датчика движения, к тому же чувствительность датчика регулируется, физически он будет утомлен в балясину, чем будет максимально сужен диапазон срабатывания, фактически это будет аналог лазерного выключатель только без второго устройства.

как мне видится, то что я написал - срабатывает кейс - 0, обнуляется таймер myTimer2, спустя 1 сек загорается 1 ступенька, две секунды вторая и тд.

Что вы имеете ввиду я не понял!

Не получится, и это не совсем дребезг. Датчик движения отправляет импульсы по каждому телодвижению, а если он ещё и ультразвуковой то по каждому чиху. И в данном случае таймер может сбрасываться.
Вы в отладчике пробовали отследить работу таймера?

Датчик PIR инфракрасный, я тестировал сигнал с пина, вроде бы все ок… если проблема моего вопроса в этом, то объясните поподробней ,я не понимаю, а если нет, то повторюсь - дальше будут еще вопросы буду решать)))

millis() возвращает количество мс с момента запуска.

В этом коде оно присваивается в переменную myTimer2, и тут же сразу проверяется не стало ли уже значение millis() на 1000 больше myTimer2.

Вот тут у меня и есть вопрос, насколько я понимаю switch - case работает так, если условия case удовлетворено то кейс запускается в режиме бесконечного цикла (поэтому и приходиться добавлять break;, я пробовал перенести break; в еще одно условие но это тоже не помогло) , поэтому все условия IF должны рано или поздно удовлетвориться, НО таймер не идет, время стоит на месте.

break добавляется для выхода из кейса, если его не добавить - выполнятся оба кейса.

Начеркайте на бумажке как расположены датчики относительно объекта идентификации.

Как это поняли?
В какой среде отладка?
P. S.
Понял. В IDE ардуино. Бросайте этот лего. Осваивайте Keil or IAR or Eclipse.
Первые две платные среды, Eclipse бесплатная но есть нюансы с отладкой, не удобна для отладки в реальном МК.

switch (a) {
    case 0: ...; break;
    case 1: ...; break;
}

эквивалентно

if (a == 0) {
    ...
} else if (a == 1) {
    ...
}

Тут наверно надо при входе (срабатывании датчика) сохранять текущий millis() в переменную и потом когда прошло 1000 включать первую ступеньку и т.д.

uint32_t activationTime;
int state;
int activeStepsCount;

void loop() {
    if (никого не было, а сейчас кто-то вошел) {
        state = STATE_ACTIVE;
        activationTime = millis();
        activeStepsCount = 0;
    }

    switch (state) {
    case STATE_ACTIVE: {
        if (activeStepsCount < TOTAL_STEPS_COUNT &&
                millis() - activationTime > (activeStepsCount + 1) * 1000) {
            activeStepsCount++;
            включить activeStepsCount ступенек;
       }
    }
    break;
    }
    case STATE_INACTIVE: ...
}

и аналогично при выходе.

По какому событию будет срабатывать case STATE_INACTIVE: … ?

Аналогично

кто-то был, а сейчас все ушли

Вообще это переключение с ACTIVE на INACTIVE и наоборот можно в свитч ниже засунуть. И изначальный state задать в setup.

И как это будет отработано В случае когда один чел спускается по лестнице, а другой в то же время подымается в противоположном направлении?
Предполагаю приведет к зависанию МК, не знаю предусмотрен ли watchdog в IDE Arduino который сбросит таймер по переполнению.

Ну потому и говорю “никого не было”.

То есть с активного на неактивный переходить только когда все ушли, а на активный когда никого не было и кто-то зашел.
хз что тут за датчик, если он просто сообщает “есть ли тут сейчас кто-то”, то наверно так и будет без сложностей.

Так тогда задача усложняется. Необходимо добавить алгоритм Светофор.
Пока на лестничной площадке кто есть - не входить не выходить.
Кстати актуально на сегодняшний день в режиме карантина :clkolgood: