Подключение двух сенсоров DHT11

Тема в разделе "Arduino & Shields", создана пользователем Vir, 20 дек 2012.

  1. Vir

    Vir Гик

    Всем привет.

    Кто-нибудь пробовал подключать два и более сенсоров DHT11 одновременно? Как их разделить в коде?
     
  2. nailxx

    nailxx Официальный Нерд Администратор

    У вас будет 2 экземпляра класса DHT. Каждый на своём пине. Не вижу абсолютно никаких проблем.
     
  3. diews

    diews Нерд

  4. diews

    diews Нерд

  5. Vir

    Vir Гик

  6. Vir

    Vir Гик

    Так к сожалению не выходит.
     
  7. nailxx

    nailxx Официальный Нерд Администратор

    Подробнее?
     
  8. Vir

    Vir Гик

    Сейчас не дома. Попробую восстановить из памяти. Смысл в том, что при наличии двух экземпляров, я к каждому из них делаю attach. К первому - первый пин, ко второму - второй. Но стартует только тот, кто первый в очереди. Грубо говоря:
    Код (Text):
    dhtFirst.attah(DHT_FIRST_SENSOR_PIN);
    dhtSecond.attah(DHT_SECOND_SENSOR_PIN);
    Первый стартанет нормально, а второй падает с ошибкой старта. Если на первое место поставить инициализацию второго сенсора, то не стартанет первый.
     
  9. nailxx

    nailxx Официальный Нерд Администратор

    Хм, хм… Странно это. А что за ошибка старта? `DHT_ERROR_START_FAILED_1` или `DHT_ERROR_START_FAILED_2` ?
     
  10. Vir

    Vir Гик

    Точно помню, что DHT_ERROR_START_FAILED_2
     
  11. nailxx

    nailxx Официальный Нерд Администратор

    Есть одна теория… Можете попробовать подключить датчики к цифровым портам, а не к аналоговым? Следите только за полярностью. Если используете Troyka, штатный кабель не подойдёт, но можно раскидать проводками или, если есть, использовать 3-проводной шлейф с зелёным проводом.
     
  12. Vir

    Vir Гик

    Ок. Прибуду домой попробую. Я использую Mega Shield, и если мне не изменяет память, они и так подключены к цифровым входам (52, 53). Провода и так перераскидывал, так как стандартное расположение не подходило под штырьки.
     
  13. nailxx

    nailxx Официальный Нерд Администратор

    Тогда моя теория скорее всего не верна… Я думал, что АЦП может мешаться. Загляните в код библиотеки. Там всё предельно просто. Ума не приложу как один датчик может мешать другому.
     
  14. Vir

    Vir Гик

    Переписал всё с нуля, чтобы гарантировать отсутствие ошибок. Разбил всё по файлам. Но результат тот же.

    Основной файл:
    Код (Text):
    #include <dht.h>
     
    #define DEBUG 1
    #define DEBUG_DELAY 500
     
    void setup()
    {
      if (DEBUG)
      {
        Serial.begin(9600);
      }
     
      DHTSensorFirstInit();
      DHTSensorSecondInit();
    }
     
    void loop()
    {
      DHTSensorFirstHandler();
      DHTSensorSecondHandler();
     
      if (DEBUG)
      {
        delay(DEBUG_DELAY);
      }
    }
    DHTSensorFirst
    Код (Text):
    #define DHT_SENSOR_FIRST_PIN 53
    DHT DHTLibFirst = DHT();
    char DHTLibFirstDbgMsg[128];
    int temperatureFirst;
    int humidityFirst;
     
    void DHTSensorFirstInit()
    {
      DHTLibFirst.attach(DHT_SENSOR_FIRST_PIN);
    }
     
    void DHTSensorFirstHandler()
    {
      DHTLibFirst.update();
     
      if (DHTLibFirst.getLastError() == DHT_ERROR_OK)
      {
        // Обработка температуры
        temperatureFirst = constrain(DHTLibFirst.getTemperatureInt(), 0, 40);
     
        // Обработка влажности
        humidityFirst  = constrain(DHTLibFirst.getHumidityInt(), 0, 100);
     
        if (DEBUG)
        {
          sprintf(
            DHTLibFirstDbgMsg,
            "DHTLibFirst: Temperature = %dC, humidity = %d%%\t",
            temperatureFirst,
            humidityFirst
          );
          Serial.println(DHTLibFirstDbgMsg);
        }
      }
      else
      {
        switch (DHTLibFirst.getLastError())
        {
            case DHT_ERROR_START_FAILED_1:
                sprintf(DHTLibFirstDbgMsg, "DHTLibFirst: Error: start failed (stage 1)");
                break;
            case DHT_ERROR_START_FAILED_2:
                sprintf(DHTLibFirstDbgMsg, "DHTLibFirst: Error: start failed (stage 2)");
                break;
            case DHT_ERROR_READ_TIMEOUT:
                sprintf(DHTLibFirstDbgMsg, "DHTLibFirst: Error: read timeout");
                break;
            case DHT_ERROR_CHECKSUM_FAILURE:
                sprintf(DHTLibFirstDbgMsg, "DHTLibFirst: Error: checksum error");
                break;
        }
     
        if (DEBUG)
        {
          Serial.println(DHTLibFirstDbgMsg);
        }
      }
    }
    DHTSensorSecond
    Код (Text):
    #define DHT_SENSOR_SECOND_PIN 52
    DHT DHTLibSecond = DHT();
    char DHTLibSecondDbgMsg[128];
    int temperatureSecond;
    int humiditySecond;
     
    void DHTSensorSecondInit()
    {
      DHTLibSecond.attach(DHT_SENSOR_SECOND_PIN);
    }
     
    void DHTSensorSecondHandler()
    {
      DHTLibSecond.update();
     
      if (DHTLibSecond.getLastError() == DHT_ERROR_OK)
      {
        // Обработка температуры
        temperatureSecond = constrain(DHTLibSecond.getTemperatureInt(), 0, 40);
     
        // Обработка влажности
        humiditySecond  = constrain(DHTLibSecond.getHumidityInt(), 0, 100);
     
        if (DEBUG)
        {
          sprintf(
            DHTLibSecondDbgMsg,
            "DHTLibSecond: Temperature = %dC, humidity = %d%%\t",
            temperatureSecond,
            humiditySecond
          );
          Serial.println(DHTLibSecondDbgMsg);
        }
      }
      else
      {
        switch (DHTLibSecond.getLastError())
        {
            case DHT_ERROR_START_FAILED_1:
                sprintf(DHTLibSecondDbgMsg, "DHTLibSecond: Error: start failed (stage 1)");
                break;
            case DHT_ERROR_START_FAILED_2:
                sprintf(DHTLibSecondDbgMsg, "DHTLibSecond: Error: start failed (stage 2)");
                break;
            case DHT_ERROR_READ_TIMEOUT:
                sprintf(DHTLibSecondDbgMsg, "DHTLibSecond: Error: read timeout");
                break;
            case DHT_ERROR_CHECKSUM_FAILURE:
                sprintf(DHTLibSecondDbgMsg, "DHTLibSecond: Error: checksum error");
                break;
        }
     
        if (DEBUG)
        {
          Serial.println(DHTLibSecondDbgMsg);
        }
      }
    }
    Результат:
    Код (Text):
    DHTLibFirst: Temperature = 22C, humidity = 33%  
    DHTLibSecond: Error: start failed (stage 2)
    DHTLibFirst: Error: read timeout
    DHTLibSecond: Error: start failed (stage 2)
    DHTLibFirst: Temperature = 22C, humidity = 33%  
    DHTLibSecond: Error: start failed (stage 2)
    DHTLibFirst: Error: read timeout
    DHTLibSecond: Error: start failed (stage 2)
    DHTLibFirst: Temperature = 22C, humidity = 33%  
     
     
  15. Vir

    Vir Гик

    Странно. Если между запросами вставляю delay(100), то бишь задержку, то всё работает. Только вот беда, мне delay не нужен =(
     
  16. Vir

    Vir Гик

    Пока вышел из ситуации следующим образом:
    Код (Text):
    #include <dht.h>
     
    #define DEBUG 1
    #define DEBUG_DELAY 1000
    int DHTSensorSelector = 1;
     
    void setup()
    {
      DHTSensorFirstInit();
      DHTSensorSecondInit();
     
      if (DEBUG)
      {
        Serial.begin(9600);
      }
    }
     
    void loop()
    {
      if (DHTSensorSelector == 1)
      {
        DHTSensorFirstHandler();
        DHTSensorSelector = 2;
      }
      else if (DHTSensorSelector == 2)
      {
        DHTSensorSecondHandler();
        DHTSensorSelector = 1;
      }
     
      if (DEBUG)
      {
        delay(DEBUG_DELAY);
      }
    }
    То есть в каждой итерации цикла меняю вызов сенсора с первого на второй, и наоборот.

    Может, у кого есть объяснение, почему сенсоры себя так ведут? Возможно есть более эстетичное решение.
     
  17. Vir

    Vir Гик

    Ещё небольшие правки:
    Код (Text):
    #include <dht.h>
     
    unsigned long workTime; // Время работы Arduino с начала старта
    int DHTSensorSelector = 1; // Флаг обозначающий, с какого сенсора DHT будут сниматься данные
     
    void setup()
    {
      DHTSensorFirstInit();
      DHTSensorSecondInit();
    }
     
    void loop()
    {
      workTime = millis();
     
      if ((workTime % 1000) == 0)
      {
        if (DHTSensorSelector == 1)
        {
          DHTSensorFirstHandler();
          DHTSensorSelector = 2;
        }
        else if (DHTSensorSelector == 2)
        {
          DHTSensorSecondHandler();
          DHTSensorSelector = 1;
        }
      }
    }
     
  18. nailxx

    nailxx Официальный Нерд Администратор

    Странно всё это. Подозрение остаётся на пины. 52-й и 53-й относится к SPI-коммуникации. Может это как-то влияет?! Попробуйте что-нибудь заведомо нейтральное. Например 40-й и 41-й.
     
  19. Vir

    Vir Гик

    На любых портах - всё тоже самое =(
     
  20. Lakomich

    Lakomich Нуб

    вот два датчика DHT22 пожалуйста:
    Код (Text):
    #include <dht.h>
    dht DHT;

    #define DHT22a_PIN 5 // первый датчик
    #define DHT22b_PIN 6 // второй датчик


    void setup()
    {
      pinMode(obogrevPin9,OUTPUT);
     
      Serial.begin(115200);
      Serial.println("DHT TEST PROGRAM ");
      Serial.print("LIBRARY VERSION: ");
      Serial.println(DHT_LIB_VERSION);
      Serial.println();
      Serial.print("tHumidity (%),\tTemperature (C)");
      Serial.println("  datchik");
    }

    void loop()
    {
      // чтение с первого датчика DHT22a

      int chk = DHT.read22(DHT22a_PIN);
      switch (chk)
      {
        case DHTLIB_OK:
                  // тут строчка была, вывода текста ОК
                    break;
        case DHTLIB_ERROR_CHECKSUM:
                    Serial.print("Checksum error,\t");
                    break;
        case DHTLIB_ERROR_TIMEOUT:
                    Serial.print("Time out error,\t");
                    break;
        default:
                    Serial.print("Unknown error,\t");
                    break;
      }
     
      // вывод значений в порт с датчика 1
      Serial.print(DHT.humidity, 1); // влажность в цифрах  
      Serial.print(",\t\t");//
      Serial.print(DHT.temperature, 1);
      Serial.println("              temp1 ");
     
     



      // читаем второй датчик!!!
      int chk2 = DHT.read22(DHT22b_PIN); // тут нужно chk2
      switch (chk)
      {
        case DHTLIB_OK:
                 
                    break;
        case DHTLIB_ERROR_CHECKSUM:
                    Serial.print("Checksum error,\t");
                    break;
        case DHTLIB_ERROR_TIMEOUT:
                    Serial.print("Time out error,\t");
                    break;
        default:
                    Serial.print("Unknown error,\t");
                    break;
      }
     
      // вывод в порт значений с датчика2 - "temp2"

      Serial.print(DHT.humidity, 1);
      Serial.print(",\t\t");
      Serial.print(DHT.temperature, 1);
      Serial.println("              temp2  ");

      delay(6000);// задержка 3сек
     
     
     

    }