возможно ли подключить два HC-SR501 к одному пину
- Войдите на сайт для отправки комментариев
Пнд, 05/03/2018 - 19:14
люди добрые подскажите затеял включение света от датчика движения но одного мне мало надо чтобы два датчика следили за движением и включали реле и соотвественно если нет движения на обоих датчиках то выключаем реле. интересно надо подключать к разным пинам или можно как то последовательно подключить к одному пину. Заранее спасибо за любые подсказки и советы
Вам пинов на ардуине мало?
Пинов мало потому что это esp8266 поэтому хотелось бы к одному пину
эта схема сразу усиливает сигнал с пина OUT PIR датчика (он слабый и если будут длинные провода - работать не будет). также имеется защита оптопарой. МК так живее останется. Т.к. длинные провода - антенны, могут ловить наводки. Такая схема у меня работает уже 2 года без нареканий.
Интересная схема но это по-моему сложно нельзя просто соединить выходы с датчиков и подключить к спину esp8266. Не хочу сразу соединять без подсказок поэтому жду советов
Провода короткие не больше метра
а попробовать то никак? если будет работать, можно было и тему не постить
ны выводе OUT в неактивном состоянии что там? GND висит? а в активном ? лог "1"? А теперь думаем, что будет, если напрямую соединить лог 1 и GND (соединить OUT двух датчиков. Это будет происходить в момент, когда один ловит движение, а другой нет )
Получается надо просто пробовать. По вашей логике скорее всего не будет работать?
Если на датчике всё действительно так, то пробовать нельзя. Получим КЗ. Нужно развязать диодами. А так как сигнал с OUT слабый, то эти диоды могут загасить сигнал и работать не будет скорее всего.
Поэтому лучше делать по схеме с транзисторами
пробуйте может и заработает.
Без резистора на землю не заработает.
Единицу то вы продаете, а где нолик брать будете?
и то верно, исправил
Кстати все равно не заработает.
Вернее заработает, но всё это неправильно.
Посмотрел на датчик - у него единица это 3.3 Вольта.
Минус ваш диод.
Какой там порог 0-1 у цифрового входа?
Я не помню.
Так что схема наверху с внешним транзистором - то что надо.
А там монтажное или делается просто соединением коллекторов
Поэтому лучше делать по схеме с транзисторами
https://learn.sparkfun.com/tutorials/logic-levels
Нет, просто повесить на пин два датчика нельзя. Т.к. если будет сработка одного из датчиков, то на один пин одновременно будет подаваться GND и VCC. Будет КЗ.
спасибо всем за подсказки и за отзывы я попытался освободить пин на esp8266 и повесить на него другой датчик движения теперь возникает вопрос как правильно вписать в скетч этот датчик, сразу скажу что это чужой скетч
/*датчик движения1*/ void pir1() { if (digitalRead(pirPin1) == HIGH) { //если появилось движение lockLow = false; //ставим флаг что движение обнаружено if (regim_1 == 2) { //если режим авто и при этом темно Status_1 = true; //ставим статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } if (regim_2 == 2) { //если режим авто и при этом темно Status_2 = true; //ставим статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } takeLowTime = true; //ставим флаг что необходимо запомнить время окончания движения } if (digitalRead(pirPin1) == LOW) { //если движение окончено if (takeLowTime) { //если стоит флаг что необходимо запомнить время lowIn = millis(); //запоминаем время время окончания движения takeLowTime = false; //убираем флаг что необходимо запоминать время до нового движения } if (!lockLow && millis() - lowIn > pause) {//если движение было обнаружено и прошло уже достаочно времение lockLow = true; //ставим флаг что движение окончено if (regim_1 == 2) { //если режим стоит авто Status_1 = false; //ставим статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } if (regim_2 == 2) { //если режим стоит авто Status_2 = false; //ставим статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } } } } /*датчик движения2*/ void pir2() { if (digitalRead(pirPin2) == HIGH) { //если появилось движение lockLow = false; //ставим флаг что движение обнаружено if (regim_1 == 2) { //если режим авто и при этом темно Status_1 = true; //ставим статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } if (regim_2 == 2) { //если режим авто и при этом темно Status_2 = true; //ставим статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } takeLowTime = true; //ставим флаг что необходимо запомнить время окончания движения } if (digitalRead(pirPin2) == LOW) { //если движение окончено if (takeLowTime) { //если стоит флаг что необходимо запомнить время lowIn = millis(); //запоминаем время время окончания движения takeLowTime = false; //убираем флаг что необходимо запоминать время до нового движения } if (!lockLow && millis() - lowIn > pause) {//если движение было обнаружено и прошло уже достаочно времение lockLow = true; //ставим флаг что движение окончено if (regim_1 == 2) { //если режим стоит авто Status_1 = false; //ставим статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } if (regim_2 == 2) { //если режим стоит авто Status_2 = false; //ставим статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } } } } /*датчик освещенности*/ void svet() { static unsigned long lastTime = 0; //предыдущее время проверки освещения по умолчанию 0, т.е. первая проверка static int lastligt; //предыдущее значение уровня освещенности if (millis() - lastTime >= minPeriod) { //если прошло больше чем минимальный период int ligt = analogRead(A0); //записываем значение с датчика освещенности на аналоговом пине A0 if (ligt < minligt) { //если значение меньше указанного ligtsvet = 0; //записываем что темно (0) } else { //если больше чем выше указано ligtsvet = 1; //записываем что светло (1) } if ((abs(ligt - lastligt) >= minligtThreshold) || (! lastTime)) { //проверяем разницу между текущим и предыдущим показанием освещенности чтоб не спамить в MQTT client.publish(svet_topic, String(ligt).c_str()); //публикуем уровень освещенности lastligt = ligt; //записываем текущий уровень в переменную чтоб использовать при следующей проверке } lastTime = millis(); //записываем текущее время } }я впринципе давно им пользуюсь в другой комнате с одним датчиком а вот теперь надо в другую где надо два датчика это часть кода где я добавил второй датчик правильно ли это или они тоже будут мешать друг другу.
если надо вот полный скетч который был
#include <PubSubClient.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> const char* ssid = "CT_AAN"; //Название WIFI const char* password = "123456789"; //пароль WIFI const char* mqtt_server = "192.168.1.5"; //адрес брокера MQTT const char* host = "esp8266-webupdate"; const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>"; #define ESPClient "ESP8266_kuhnya" //имя MQTT клиента, должно быть уникальным #define RELAY_1 4 //Выход на реле или светодиод #define BUTTON_1 14 //Кнопка #define relays_topic_1 "kuhnya/relay_1" //публикуемый топик #define RELAY_2 5 //Выход на реле или светодиод #define BUTTON_2 16 //Кнопка #define relays_topic_2 "kuhnya/relay_2" //публикуемый топик #define svet_topic "kuhnya/svet" #define pir_topic "kuhnya/pir" #define pirPin 13 //контакт для подключения датчика ESP8266WebServer server(80); //инициализация веб сервера на 80 порту WiFiClient espClient; //инициализация WiFi клиента PubSubClient client(espClient); //инициализация MQTT клиента /* переменные времени*/ long last_mls = millis(); //функция времени для проверки подключения long last_mls2 = millis(); //функция времени для отправки топиков /*реле*/ boolean Status_1 = false; //объявляем статус реле в 0 boolean btnPress_1 = false; //объявляем что кнопка не нажата 0 boolean lastbtnStat_1 = false; boolean Status_2 = false; //объявляем статус реле в 0 boolean btnPress_2 = false; //объявляем что кнопка не нажата 0 boolean lastbtnStat_2 = false; int regim_1 = 0; //режим по умолчанию при включении int regim_2 = 0; //режим по умолчанию при включении /*переменные датчика движения*/ long unsigned int lowIn; //Время, в которое был принят сигнал отсутствия движения(LOW) long unsigned int pause = 60000; //Пауза, после которой движение считается оконченным boolean lockLow = true; //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет boolean takeLowTime; //Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения /*переменные датчика освещенности*/ int ligtsvet = 0; //переменная для освещенности 0-темно 1 светло int val = 0; //переменная для хранения состояния датчика int ligt; //переменная для показаний с датчика освещенности int minligt = 50; //минимальный уровень освещенности const unsigned long minPeriod = 100; //минимальный период отправки освещенности const int minligtThreshold = 10; //минимальная разница освещенности /*разовый цикл*/ void setup() { pinMode(pirPin, INPUT); pinMode(RELAY_1, OUTPUT); //Выход на реле или светодиод pinMode(BUTTON_1, INPUT); //Кнопка digitalWrite(RELAY_1, Status_1); //устанавливаем на выходе статус реле pinMode(RELAY_2, OUTPUT); //Выход на реле или светодиод pinMode(BUTTON_2, INPUT); //Кнопка digitalWrite(RELAY_2, Status_2); //устанавливаем на выходе статус реле Serial.begin(115200); //инициализация монитора порта client.setServer(mqtt_server, 1883); //подключаемся к MQTT client.setCallback(callback); //функция получения топиков с брокера delay(100); //ждем 100 милисекунд WiFi.begin(ssid, password); //подключаемся к WiFi delay(5000); //ждем 5 секунд Serial.println("WiFi"); client.connect(ESPClient); //конектимся с брокером как клиент client.subscribe(relays_topic_1); //подписываемся на топик client.subscribe(relays_topic_2); //подписываемся на топик /*прошивка по воздуху*/ if (WiFi.waitForConnectResult() == WL_CONNECTED) { MDNS.begin(host); Serial.println("WiFi start"); server.on("/", HTTP_GET, []() { server.sendHeader("Connection", "close"); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/html", serverIndex); }); server.on("/update", HTTP_POST, []() { server.sendHeader("Connection", "close"); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); ESP.restart(); }, []() { HTTPUpload& upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { Serial.setDebugOutput(true); WiFiUDP::stopAll(); Serial.printf("Update: %s\n", upload.filename.c_str()); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace)) { //start with max available size Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_WRITE) { if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { //true to set the size to the current progress Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { Update.printError(Serial); } Serial.setDebugOutput(false); } yield(); }); server.begin(); MDNS.addService("http", "tcp", 80); Serial.printf("Ready! Open http://%s.local in your browser\n", host); } else { Serial.println("WiFi Failed"); } } /*датчик движения*/ void pir() { if (digitalRead(pirPin) == HIGH) { //если появилось движение lockLow = false; //ставим флаг что движение обнаружено if (regim_1 == 2 && ligtsvet == 0) { //если режим авто и при этом темно Status_1 = true; //ставим статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } if (regim_2 == 2 && ligtsvet == 0) { //если режим авто и при этом темно Status_2 = true; //ставим статус включено digitalWrite(RELAY_2, Status_2); //включаем реле } takeLowTime = true; //ставим флаг что необходимо запомнить время окончания движения } if (digitalRead(pirPin) == LOW) { //если движение окончено if (takeLowTime) { //если стоит флаг что необходимо запомнить время lowIn = millis(); //запоминаем время время окончания движения takeLowTime = false; //убираем флаг что необходимо запоминать время до нового движения } if (!lockLow && millis() - lowIn > pause) {//если движение было обнаружено и прошло уже достаочно времение lockLow = true; //ставим флаг что движение окончено if (regim_1 == 2) { //если режим стоит авто Status_1 = false; //ставим статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } if (regim_2 == 2) { //если режим стоит авто Status_2 = false; //ставим статус выключено digitalWrite(RELAY_2, Status_2); //выключаем реле } } } } /*датчик освещенности*/ void svet() { static unsigned long lastTime = 0; //предыдущее время проверки освещения по умолчанию 0, т.е. первая проверка static int lastligt; //предыдущее значение уровня освещенности if (millis() - lastTime >= minPeriod) { //если прошло больше чем минимальный период int ligt = analogRead(A0); //записываем значение с датчика освещенности на аналоговом пине A0 if (ligt < minligt) { //если значение меньше указанного ligtsvet = 0; //записываем что темно (0) } else { //если больше чем выше указано ligtsvet = 1; //записываем что светло (1) } if ((abs(ligt - lastligt) >= minligtThreshold) || (! lastTime)) { //проверяем разницу между текущим и предыдущим показанием освещенности чтоб не спамить в MQTT client.publish(svet_topic, String(ligt).c_str()); //публикуем уровень освещенности lastligt = ligt; //записываем текущий уровень в переменную чтоб использовать при следующей проверке } lastTime = millis(); //записываем текущее время } } /*чтение топиков MQTT*/ void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); // Serial.print(topic); //чисто для отладки и контроля приходящих топиков пишем в монитор порта че получили Serial.print(" "); // String strTopic = String(topic); //конвертируем в стринг полученый топик String strPayload = String((char*)payload); //конвертируем в стринг полученные данные с топика for (int i = 0; i < length; i++) { //конвертируем полученые значения топика в целые числа Serial.print((char)payload[i]); //для отладки пишем в монитор порта полученные значения с топика } Serial.println(); if (strTopic == relays_topic_1) { //если получили с нужного топика if ((char)payload[0] == '0') { //если полученное значение 0 Status_1 = false; //статус выключено regim_1 = 0; //переключаем режим в выключено } else if ((char)payload[0] == '1') { //если получена 1 Status_1 = true; //статус включено regim_1 = 1; //режим включено } else { //если любое другое значение regim_1 = 2; //режим авто } } if (strTopic == relays_topic_2) { //если получили с нужного топика if ((char)payload[0] == '0') { //если полученное значение 0 Status_2 = false; //статус выключено regim_2 = 0; //переключаем режим в выключено } else if ((char)payload[0] == '1') { //если получена 1 Status_2 = true; //статус включено regim_2 = 1; //режим включено } else { //если любое другое значение regim_2 = 2; //режим авто } } } /*кнопка 1*/ void button1() { btnPress_1 = digitalRead(BUTTON_1); //переменная кнопки Status_1 = digitalRead(RELAY_1); //переменная реле if (btnPress_1 == LOW && lastbtnStat_1 == false) { //если кнопка нажата а перед эти была отпущена delay(30); // защита от дребезга regim_1++; //прибавляем к текущему значению режим 1 lastbtnStat_1 = true; //записываем что кнопка нажата if (regim_1 > 2) { // regim_1 = 0; //ограничеваем значение режима значениями 0,1,2 } } if (btnPress_1 == HIGH && lastbtnStat_1 == true) { //если кнопка отпущена а перед эти была нажата lastbtnStat_1 = false; //записываем что кнопка отпущена client.publish(relays_topic_1, String(regim_1).c_str()); //публикуем текущий режим } if (regim_1 == 0) { //если режим выключено (0) Status_1 = false; //статус выключено digitalWrite(RELAY_1, Status_1); //выключаем реле } if (regim_1 == 1) { //если режим включено (1) Status_1 = true; //статус включено digitalWrite(RELAY_1, Status_1); //включаем реле } } /*кнопка 2*/ void button2() { btnPress_2 = digitalRead(BUTTON_2); Status_2 = digitalRead(RELAY_2); if (btnPress_2 == LOW && lastbtnStat_2 == false) { delay(30); regim_2++; lastbtnStat_2 = true; if (regim_2 > 2) { regim_2 = 0; } } if (btnPress_2 == HIGH && lastbtnStat_2 == true) { lastbtnStat_2 = false; client.publish(relays_topic_2, String(regim_2).c_str()); } if (regim_2 == 0) { Status_2 = false; digitalWrite(RELAY_2, Status_2); } if (regim_2 == 1) { Status_2 = true; digitalWrite(RELAY_2, Status_2); } } /*проверка подключений*/ void reconnect_server() { if (WiFi.status() != WL_CONNECTED) //если нет подключения с сети { WiFi.begin(ssid, password); //подключаемся по имени сети и паролю Serial.println(""); Serial.println("WiFi connect..."); //выводим в монитор порта что пытаемся подключиться } else { //если подключены Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); //выводим в монитор порта текущий ip } if (!client.connected() && WiFi.status() == WL_CONNECTED) { //если к сети подключились но к MQTT нет if (client.connect(ESPClient)) { client.subscribe(relays_topic_1); //подписываемся на топик client.subscribe(relays_topic_2); //подписываемся на топик Serial.println("Mosquitto connect..."); //выводим в монитор порта что пытаемся подключиться } else //если не получилось { Serial.print("failed connect Mosquitto, rc="); Serial.print(client.state()); Serial.println(""); } } } /*публикация топиков*/ void MQTT() { if (millis() - last_mls2 > 2000) //периодичность публикации топика { val = digitalRead(pirPin); last_mls2 = millis(); client.publish(pir_topic, String(val).c_str()); // публикуем датчик движения, можно убрать если не нужно } } /*основной цикл*/ void loop() { client.loop(); pir(); MQTT(); button1(); button2(); svet(); if (millis() - last_mls > 15000) //проверка подключений раз в 15 сек { last_mls = millis(); reconnect_server(); } server.handleClient(); delay(50); //защита от помех электросети, без нее свет живет своей жизнью }