возможно ли подключить два HC-SR501 к одному пину

artemon25
Offline
Зарегистрирован: 25.12.2015

люди добрые подскажите затеял включение света от датчика движения но одного мне мало надо чтобы два датчика следили за движением и включали реле и соотвественно если нет движения на обоих датчиках то выключаем реле. интересно надо подключать к разным пинам или можно как то последовательно подключить к одному пину. Заранее спасибо за любые подсказки и советы

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Вам пинов на ардуине мало?

MaksVV
Offline
Зарегистрирован: 06.08.2015

artemon25
Offline
Зарегистрирован: 25.12.2015

Пинов мало потому что это esp8266 поэтому хотелось бы к одному пину

MaksVV
Offline
Зарегистрирован: 06.08.2015

эта схема сразу усиливает сигнал с пина OUT PIR датчика (он слабый и если будут длинные провода - работать не будет). также имеется защита оптопарой. МК так живее останется. Т.к. длинные провода - антенны, могут ловить наводки. Такая схема у меня работает уже 2 года без нареканий. 

artemon25
Offline
Зарегистрирован: 25.12.2015

Интересная схема но это по-моему сложно нельзя просто соединить выходы с датчиков и подключить к спину esp8266. Не хочу сразу соединять без подсказок поэтому жду советов

artemon25
Offline
Зарегистрирован: 25.12.2015

Провода короткие не больше метра

MaksVV
Offline
Зарегистрирован: 06.08.2015

а попробовать то никак? если будет работать, можно было и тему не постить

MaksVV
Offline
Зарегистрирован: 06.08.2015

ны выводе OUT в неактивном состоянии что там? GND висит? а в активном ? лог "1"? А теперь думаем, что будет, если напрямую соединить лог 1 и GND (соединить OUT двух датчиков. Это будет происходить в момент, когда один ловит движение, а другой нет )

artemon25
Offline
Зарегистрирован: 25.12.2015

Получается надо просто пробовать. По вашей логике скорее всего не будет работать?

MaksVV
Offline
Зарегистрирован: 06.08.2015

MaksVV пишет:
ны выводе OUT в неактивном состоянии что там? GND висит? а в активном ? лог "1"?

Если на датчике всё действительно так, то пробовать нельзя. Получим КЗ. Нужно развязать диодами. А так как сигнал с OUT слабый, то эти диоды могут загасить сигнал и работать не будет скорее всего. 

Поэтому лучше делать по схеме с транзисторами 

MaksVV
Offline
Зарегистрирован: 06.08.2015

пробуйте может и заработает. 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Без резистора на землю не заработает.
Единицу то вы продаете, а где нолик брать будете?

MaksVV
Offline
Зарегистрирован: 06.08.2015

и то верно, исправил

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Кстати все равно не заработает.
Вернее заработает, но всё это неправильно.
Посмотрел на датчик - у него единица это 3.3 Вольта.
Минус ваш диод.
Какой там порог 0-1 у цифрового входа?
Я не помню.
Так что схема наверху с внешним транзистором - то что надо.
А там монтажное или делается просто соединением коллекторов

MaksVV
Offline
Зарегистрирован: 06.08.2015

trembo пишет:
Кстати все равно не заработает. Вернее заработает, но всё это неправильно. Посмотрел на датчик - у него единица это 3.3 Вольта. Минус ваш диод. Какой там порог 0-1 у цифрового входа? Я не помню. Так что схема наверху с внешним транзистором - то что надо. А там монтажное или делается просто соединением коллекторов

MaksVV пишет:
Нужно развязать диодами. А так как сигнал с OUT слабый, то эти диоды могут загасить сигнал и работать не будет скорее всего. 

Поэтому лучше делать по схеме с транзисторами 

 
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

artemon25 пишет:
нельзя просто соединить выходы с датчиков и подключить к спину esp8266.

Нет, просто повесить на пин два датчика нельзя. Т.к. если будет сработка одного из датчиков, то на один пин одновременно будет подаваться GND и VCC. Будет КЗ.

artemon25
Offline
Зарегистрирован: 25.12.2015

спасибо всем за подсказки и за отзывы я попытался освободить пин на 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);                                   //защита от помех электросети, без нее свет живет своей жизнью
}