ДД, есть проект, решил на нем изучить с++, но столкнулся с проблемой и все встала на этом.
Подсветка лестницы:
Два датчика движения на концах лестницы, при входе должны поочередно загореться ступеньки, при выходи погаснуть… На данный момент работаю с одним датчиком, второй сделаю по аналогии. Сделал через 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 пробовал… буду очень благодарен если разъясните, не могу продвинутся дальше, если с азами не разобрался!
есть похожие решения в доступе, но там сделано через адресную LED ленту, а у меня аналоговая, реализация через мосфеты, и датчики движения вроде бы норм, думаю что с помочью того же millis() и переменной можно устранить “дребезг” датчика движения, к тому же чувствительность датчика регулируется, физически он будет утомлен в балясину, чем будет максимально сужен диапазон срабатывания, фактически это будет аналог лазерного выключатель только без второго устройства.
Не получится, и это не совсем дребезг. Датчик движения отправляет импульсы по каждому телодвижению, а если он ещё и ультразвуковой то по каждому чиху. И в данном случае таймер может сбрасываться.
Вы в отладчике пробовали отследить работу таймера?
Датчик PIR инфракрасный, я тестировал сигнал с пина, вроде бы все ок… если проблема моего вопроса в этом, то объясните поподробней ,я не понимаю, а если нет, то повторюсь - дальше будут еще вопросы буду решать)))
Вот тут у меня и есть вопрос, насколько я понимаю switch - case работает так, если условия case удовлетворено то кейс запускается в режиме бесконечного цикла (поэтому и приходиться добавлять break;, я пробовал перенести break; в еще одно условие но это тоже не помогло) , поэтому все условия IF должны рано или поздно удовлетвориться, НО таймер не идет, время стоит на месте.
Начеркайте на бумажке как расположены датчики относительно объекта идентификации.
Как это поняли?
В какой среде отладка?
P. S.
Понял. В IDE ардуино. Бросайте этот лего. Осваивайте Keil or IAR or Eclipse.
Первые две платные среды, Eclipse бесплатная но есть нюансы с отладкой, не удобна для отладки в реальном МК.
И как это будет отработано В случае когда один чел спускается по лестнице, а другой в то же время подымается в противоположном направлении?
Предполагаю приведет к зависанию МК, не знаю предусмотрен ли watchdog в IDE Arduino который сбросит таймер по переполнению.
То есть с активного на неактивный переходить только когда все ушли, а на активный когда никого не было и кто-то зашел.
хз что тут за датчик, если он просто сообщает “есть ли тут сейчас кто-то”, то наверно так и будет без сложностей.
Так тогда задача усложняется. Необходимо добавить алгоритм Светофор.
Пока на лестничной площадке кто есть - не входить не выходить.
Кстати актуально на сегодняшний день в режиме карантина