Помогите с частью кода: "выключатель освещения счетчик людей в помещении"
- Войдите на сайт для отправки комментариев
Делаю впервые на Ардуино "выключатель освещения - счетчик людей" и к тамуже на ультрозвукавых дальномерах HC-SR04 ни кто раньше на Ардуино ничего подобного не делал.
В общем счетчик выключатель устанавливается в дверном праеме и считает всех входящих и выходящих людей в помещении, когда в помещении будет 0 людей - свет гасит, если больше 0 включает.
Есть два датчика HC-SR04 которые мониторят 2 дистанции от датчика до противостоящей стены.
Светадиоды подключенные к пинам 8 и 9 сигнализируют работу датчиков. Пока я сделал если дистанция меньше 20 см, то считается что датчик сработал, в идеале нужно как то сделать что бы каждому датчику была присвоена переменная, значения для каторой берутся по начальным данным, ОДНАКРАТНО, с датчиков при включении, далее эти значения не изменяются при работе. И затем просто идет сравнение текущих значений с датчиков с значениями с переменных, если меньше этих значений - считается датчик сработал. (как это сделать однакратно я не понял).
А теперь оснавной вопрос, как указать последовательность событий:
Если выполняется сначало событие "А" потом "Б" то прибовляем +1 к переменной counts, если сначало событие "Б" потом "А", то убовляем 1 у переменной counts.
Если counts >0 то зажигаем светадиод на 7 пине, иначе тушим. как то так.
long duration_1, cm1;
long duration_2, cm2;
long counts;
long cm1_1;
long cm2_1;
int var;
void setup() {
pinMode(3, OUTPUT);// trig 1
pinMode(6, OUTPUT);// trig 2
pinMode(4, INPUT); // echo 1
pinMode(5, INPUT); // echo 2
pinMode(7, OUTPUT); // реле пин
pinMode(8, OUTPUT); // out 1
pinMode(9, OUTPUT); // out 2
}
void loop() {
digitalWrite(3, LOW);
delayMicroseconds(2);
digitalWrite(3, HIGH);
delayMicroseconds(10);
digitalWrite(3, LOW);
digitalWrite(7, LOW);
Serial.begin(115200);
duration_1 = pulseIn (4, HIGH);
cm1_1 = duration_1/29/2;
Serial.print("out_1: ");
Serial.print(cm1_1);
Serial.print("cm");
Serial.println ();
digitalWrite(6, LOW);
delayMicroseconds(2);
digitalWrite(6, HIGH);
delayMicroseconds(10);
digitalWrite(6, LOW);
duration_2 = pulseIn (5, HIGH);
cm2_1 = duration_2/29/2;
Serial.print("out_2: ");
Serial.print(cm2_1);
Serial.print("cm");
Serial.println ();
if(cm1_1 < 20)// 20 - дистанция на каторой срабатывает датчик 20 см и ниже.
{
cm1 = 1;
digitalWrite(8, HIGH);
}
else
{
//delay(100);
cm1 = 0;
digitalWrite(8, LOW);
}
if(cm2_1 < 20 )// 20 - дистанция на каторой срабатывает датчик 20 см и ниже.
{
cm2 = 1;
digitalWrite(9, HIGH);
}
else
{
//delay(100);
cm2 = 0;
digitalWrite(9, LOW);
}
/*
Здесь нужно дописать код.
*/
if(counts > 0)
{
digitalWrite(7, HIGH);
}
else
{
digitalWrite(7, LOW);
}
Serial.println (counts);
delay(10);
}
Я новичок в Ардуино, так что строго не судите, ни знаю даже С++.
Делаю впервые на Ардуино "выключатель освещения - счетчик людей" и к тамуже на ультрозвукавых дальномерах HC-SR04 ни кто раньше на Ардуино ничего подобного не делал.
Разберётесь с алгоритмом и скетчем - узнаете, почему на HC-SR04 такие устройства никто не делает.
А попробуйте самостоятельно. Вот здесь - http://arduino.ru/forum/proekty/datchik-napravleniya-dvizheniya - готовая реализация алгоритма.
Здесь это ничего не значит, было бы желание и Гугл.
В общем сам решил этих 2 задачи, код работает четко, притензий не имеею к своему коду. :)
long duration_1, cm1; long duration_2, cm2; long counts; long cm1_1; long cm2_1; int var; int State; void setup() { pinMode(3, OUTPUT);// trig 1 pinMode(6, OUTPUT);// trig 2 pinMode(4, INPUT); // echo 1 pinMode(5, INPUT); // echo 2 pinMode(7, OUTPUT); // реле пин pinMode(8, OUTPUT); // out 1 pinMode(9, OUTPUT); // out 2 var = 0; counts =0; } void loop() { digitalWrite(3, LOW); delayMicroseconds(2); digitalWrite(3, HIGH); delayMicroseconds(10); digitalWrite(3, LOW); digitalWrite(7, LOW); Serial.begin(115200); duration_1 = pulseIn (4, HIGH); cm1_1 = duration_1/29/2; Serial.print("out_1: "); Serial.print(cm1_1); Serial.print("cm"); Serial.println (); digitalWrite(6, LOW); delayMicroseconds(2); digitalWrite(6, HIGH); delayMicroseconds(10); digitalWrite(6, LOW); duration_2 = pulseIn (5, HIGH); cm2_1 = duration_2/29/2; Serial.print("out_2: "); Serial.print(cm2_1); Serial.print("cm"); Serial.println (); ///////////////////////////////////////////////////// Вариант А - автоматическая калибровка радиуса действия датчиков //////////////////////////// /* if (var == 0) { cm1 = cm1_1; cm2 = cm2_1; var = 1; } if (cm1_1 < (cm1 - 10)) // - 10 -- минимальное расстояние от проходящего человека до стены, каторая напротив от датчиков (для большей стабильности колибровки) { digitalWrite(8, HIGH); } else { digitalWrite(8, LOW); } if (cm2_1 < (cm2 - 10)) // - 10 -- минимальное расстояние от проходящего человека до стены, каторая напротив от датчиков (для большей стабильности колибровки) { digitalWrite(9, HIGH); } else { digitalWrite(9, LOW); } */ ////////////////////////////////////////////////Конец Варианта А ///////////////////////////////////////////////////////////////////////// ////////////////////////////////////////Вариант Б - ручная настройка радиуса действия датчиков ///////////////////////////////////////////////// if(cm1_1 < 100)// 100 - дистанция на которой срабатывает датчик 100 см и ниже. { cm1 = 1; digitalWrite(8, HIGH); } else { cm1 = 0; digitalWrite(8, LOW); } if(cm2_1 < 100 )// 100 - дистанция на которой срабатывает датчик 100 см и ниже. { cm2 = 1; digitalWrite(9, HIGH); } else { cm2 = 0; digitalWrite(9, LOW); } ///////////////////////////////////////////////////////////Конец Варианта Б //////////////////////////////////////////////////////////////// if(digitalRead(8) == LOW && digitalRead(9) == LOW) State = 0; if(digitalRead(8) == HIGH && digitalRead(9) == HIGH && State == 0) State = 1; if(digitalRead(8) == LOW && digitalRead(9) == HIGH && State == 1 ) State = 2; if(digitalRead(8) == HIGH && digitalRead(9) == LOW && State == 1 ) State = 3; if (State == 3) { counts = counts -1; //delay(2); State = 0; } if (State == 2) { counts = counts +1; //delay(2); State = 0; } if(counts > 0) { digitalWrite(7, HIGH); } else { digitalWrite(7, LOW); } Serial.println (counts); delay(500); }Но вот датчики это что то, 1 из их нормально работаеn, чувствительность просто супер, угол абзора чуть ли не 180 градусов, работает на все подрят: на твердые предметы, мягкие предметы (одежда), а вот со вторым беда, он савсем какой то вялый с какой то задержкой срабатывает, на мягкие предменты вообще не реагирут - сигнал угасает в майке и расстояние ввыводит до майки 3,3 км :). И дело точно не в коде, думал что в нем, но местами менял датчики в итоге все тоже менялось.
Вот как можно так делать обсалютно 2 адинаковых датчика но с разными параметрами? На вид оба идентичных, но микросхемы опрационных усилителей различаются производителями, в том где все супер работает LM324, а где хуже - SGM324ys14. Но не думаю что дело в операционниках, ведь отражающий эффект зависить от несущей частоты сомневаюсь, что она различается у обоих датчиков, должна быть 40 кГц.
Подпаялся к трансиверу (хотя хер его знает он ли это может китайцы и папутали местами) проблемного датчика, осцилогрофом и когда датчик выдает показания 3,3 км, на осцилографе исчезают пачки из 8 имульсов частатой 40 кГц, осюда собственно вопрос, а могут ли исчезать импульсы с трансивера при слишком большом расстоянии, разве что на риссивере?
Вот накидал тот же самый проект только на ИК фотоприемнике 1 шт и 2-х ИК - светодиодах находящихся на противоположной стене. Не знаю только заработает или нет.
int ledPin_1 = 4; // ИК света-диод 1 int ledPin_2 = 5;// ИК света-диод 2 int ledPin_3 = 8;// индикация сработки ик луча 1 int ledPin_4 = 9;// индикация сработки ик луча 2 long counts; int ledPin_6 = 7; // реле пин int ledPin_5 = 6; // вход ИК фото-приемника boolean LED1; boolean LED2; int State; void setup() { pinMode(ledPin_1, OUTPUT); pinMode(ledPin_2, OUTPUT); pinMode(ledPin_5, INPUT); pinMode(ledPin_3, OUTPUT); pinMode(ledPin_4, OUTPUT); pinMode(ledPin_6, OUTPUT); counts = 0; LED1 = false; LED2 = false; } void loop() { //////////////////////////////////передатчик LED1 & LED2//////////////////////////////// LED1 = true; delayMicroseconds(200); LED1 = false; delay(1); LED2 = true; delayMicroseconds(200); LED2 = false; delay(1); if(LED1 == true) tone(ledPin_1, 40000); // 40кГц частота с каторой работает ИК фота - приемник if(LED1 == false) noTone(ledPin_1); if(LED2 == true) tone(ledPin_2, 40000); // // 40кГц частота с каторой работает ИК фота - приемник if(LED2 == false) noTone(ledPin_2); //////////////////////////////// Ик приемник///////////////////////////////////////////////// if (ledPin_5 == HIGH && LED1 == true) { digitalWrite(ledPin_3, HIGH); } else { digitalWrite(ledPin_3, LOW); } if (ledPin_5 == HIGH && LED2 == true) { digitalWrite(ledPin_4, HIGH); } else { digitalWrite(ledPin_4, LOW); } if(digitalRead(ledPin_3) == LOW && digitalRead(ledPin_4) == LOW) State = 0; if(digitalRead(ledPin_3) == HIGH && digitalRead(ledPin_4) == HIGH && State == 0) State = 1; if(digitalRead(ledPin_3) == LOW && digitalRead(ledPin_4) == HIGH && State == 1 ) State = 2; if(digitalRead(ledPin_3) == HIGH && digitalRead(ledPin_4) == LOW && State == 1 ) State = 3; if (State == 3) { counts = counts -1; State = 0; } if (State == 2) { counts = counts +1; State = 0; } if(counts > 0) digitalWrite(ledPin_6, HIGH); if(counts <= 0) digitalWrite(ledPin_6, LOW); //Serial.print("count: "); //Serial.println (counts); }Вот практически рабочий код счетчика - выключателя на 2-х ИК светадиодах и 1-ом ИК фотоприемнике от систем ДУ работает с несущей частатой 38 кГц.
const int ledPin_1 = 10; // ИК света-диод 1 const int ledPin_2 = 11;// ИК света-диод 2 int ledPin_3 = 8;// индикация сработки ик луча 1 orange int ledPin_4 = 9;// индикация сработки ик луча 2 red long counts; int ledPin_6 = 7; // реле пин int ledPin_5 = 6; // вход ИК фото-приемника boolean LED1; boolean LED2; int State; long delay_PWM_LOW = 800; long delay_PWM_HIGH = 200; void setup() { pinMode(ledPin_1, OUTPUT); pinMode(ledPin_2, OUTPUT); pinMode(ledPin_5, INPUT); pinMode(ledPin_3, OUTPUT); pinMode(ledPin_4, OUTPUT); pinMode(ledPin_6, OUTPUT); counts = 0; Serial.begin(115200); } void loop() { //////////////////////////////////передатчик LED1 & LED2//////////////////////////////// tone(ledPin_1, 38000); //38кГц частота с каторой работает ИК фота - приемник delayMicroseconds(delay_PWM_HIGH); if (digitalRead(ledPin_5) == HIGH) { digitalWrite(ledPin_3, HIGH); LED1 = true; } noTone(ledPin_1); delayMicroseconds(delay_PWM_LOW); tone(ledPin_2, 38000); //38кГц частота с каторой работает ИК фота - приемник delayMicroseconds(delay_PWM_HIGH); if (digitalRead(ledPin_5) == HIGH) { digitalWrite(ledPin_4, HIGH); LED2 = true; } noTone(ledPin_2); delayMicroseconds(delay_PWM_LOW); //if(LED1 == true) tone(ledPin_1, 38000); // 38кГц частота с каторой работает ИК фота - приемник //if(LED1 == false) noTone(ledPin_1); //if(LED2 == true) tone(ledPin_2, 38000); // // 38кГц частота с каторой работает ИК фота - приемник //if(LED2 == false) noTone(ledPin_2); //////////////////////////////// Ик приемник///////////////////////////////////////////////// if(LED1 == false && LED2 == false) State = 0; //if(LED1 == true && LED2 == true && State == 0) State = 1; if(LED1 == false && LED2 == true && State == 0 ) State = 2; if(LED1 == true && LED2 == false && State == 2 ) State = 3; if(LED1 == true && LED2 == false && State == 0 ) State = 4; if(LED1 == false && LED2 == true && State == 4 ) State = 5; //if(LED1 == true && State == 0) State = 1; //if(LED2 == true && State == 1) State = 2; //if(LED1 == false && State == 2) State = 3; //if(LED2 == true && State == 0) State = 4; //if(LED1 == true && State == 4) State = 5; //if(LED2 == false && State == 5) State = 6; if (State == 3) { counts = counts -1; //delay(1); State = 6; } if (State == 5) { counts = counts +1; //delay(1); State = 6; } //if(LED1 == false && LED2 == false) { //digitalWrite(ledPin_3, LOW); //digitalWrite(ledPin_4, LOW); //} //if(LED1 == true && LED2 == true) { //вот это условие почему то ни когда не выполняется //digitalWrite(ledPin_3, HIGH); //digitalWrite(ledPin_4, HIGH); //} LED1 = false; LED2 = false; digitalWrite(ledPin_3, LOW); digitalWrite(ledPin_4, LOW); if(counts > 0) digitalWrite(ledPin_6, HIGH); if(counts <= 0) digitalWrite(ledPin_6, LOW); Serial.print("count: "); Serial.println (counts); //State = 0; }Многие параметры тут очень критичны, например: delay_PWM_LOW, и delay_PWM_HIGH методом подбора было определено что это самые оптимальные значения.
Так же имеет большое значение номиналы добавочных сопротивлений на ИК светадиоды, у меня 220 ом, подключены ИК светадиоды через транзисторы BC547 на базы сигнал подается через резисторы наминала 680 Ом.
Работает счетчик как то не стабильно, иногда пропускает счет - зависит от скорости прохождения человека. Помогите как то оптимизировать код, что бы стабильно считал.
Я думаю, что погрешность будет и при нормальной работе Ардуины, например проходят одновременно два человека, или с ребенком на руках. Может просто установить датчики движения и отключать освещение при отсутствии движения втечении определенного времени, можно и без ардуино.
Я думаю, что погрешность будет и при нормальной работе Ардуины, например проходят одновременно два человека, или с ребенком на руках. Может просто установить датчики движения и отключать освещение при отсутствии движения втечении определенного времени, можно и без ардуино.
Увы это не тот случай и не тот проект. В данном помещении работают люди и что им постояноо нужно двигатся что бы у их свет был? :)
Ладно этот проэкт видимо обречен. Папробую то же сделать но с 2 -мя ИК фота приемниками.
Все сделал на 2-х Ик фотаприемниках и 1 ИК светадиоде, убрал все delay - работает практически на постоянном токе (не преривно мониторятся 2 ИК луча на наличие пересечений человеком). Работает практически стабильно. Заказал еще дисплэй ТМ1637 для отображения количества.
const int ledPin_1 = 4; // ИК света-диод 1 const int ledPin_3 = 8;// индикация сработки ик луча 1 orange const int ledPin_4 = 9;// индикация сработки ик луча 2 red long counts; //количество людей в помещении int ledPin_6 = 7; // реле пин int IN_IR_1 = 6; // вход ИК фото-приемника 1 int IN_IR_2 = 10; // вход ИК фото-приемника 2 int State; //састоянии для алгоритма, определяющего направление движения void setup() { pinMode(ledPin_1, OUTPUT); pinMode(IN_IR_1, INPUT); pinMode(IN_IR_2, INPUT); pinMode(ledPin_3, OUTPUT); pinMode(ledPin_4, OUTPUT); pinMode(ledPin_6, OUTPUT); counts = 0; Serial.begin(9600); } void loop() { tone(ledPin_1, 36000); //36кГц частота с каторой работает ИК фота - приемник if(digitalRead(IN_IR_1) == LOW) { // индикация работы ИК луча 1, если не пересечен то светадиод ledPin_3 светит, иначе не светит digitalWrite(ledPin_3, HIGH); }else{ digitalWrite(ledPin_3, LOW); } if(digitalRead(IN_IR_2) == LOW) { // индикация работы ИК луча 2, если не пересечен то светадиод ledPin_4 светит, иначе не светит digitalWrite(ledPin_4, HIGH); }else{ digitalWrite(ledPin_4, LOW); } //////////////Алгоритм опредиляющий направление движения///////////// if(digitalRead(IN_IR_1) == LOW && digitalRead(IN_IR_2) == LOW) State = 0; if(digitalRead(IN_IR_1) == HIGH && digitalRead(IN_IR_2) == LOW && State == 0) State = 1; if(digitalRead(IN_IR_2) == HIGH && digitalRead(IN_IR_1) == LOW && State == 1) State = 2; if(digitalRead(IN_IR_1) == LOW && digitalRead(IN_IR_2) == HIGH && State == 2) State = 3; //1 человек вошел if(digitalRead(IN_IR_2) == HIGH && digitalRead(IN_IR_1) == LOW && State == 0) State = 4; if(digitalRead(IN_IR_1) == HIGH && digitalRead(IN_IR_2) == LOW && State == 4) State = 5; if(digitalRead(IN_IR_2) == LOW && digitalRead(IN_IR_1) == HIGH && State == 5) State = 6; // 1 человек вышел if (State == 3) { counts = counts +1; State = 0; } if (State == 6) { counts = counts -1; State = 0; } if(counts > 0) digitalWrite(ledPin_6, HIGH); if(counts <= 0) digitalWrite(ledPin_6, LOW); if(counts < 0) counts = 0; //обнуляем отрицательные значения количества Serial.print("counts: "); Serial.println(counts); }Оказывается чем проще, тем надежней. :)
Наконец то я его сделал, вот окончательный вариант: https://youtu.be/vbfXED8Dfuk
Поздравляю, Вы упорный человек.
Фраза "Этот проект на Ардуино уникален в своем роде, такого еще никто на Ардуино не делал." - великолепна )).
Поздравляю, Вы упорный человек.
Фраза "Этот проект на Ардуино уникален в своем роде, такого еще никто на Ардуино не делал." - великолепна )).
Ну просто показалось, что мне это по силам и решил пойти до конца. На таких ИК фотоприемниках точно ни кто еще не делал. Есть конечно проекты с точно такими ИК фотоприемниками, но не на Ардуино.