В связи с выходом крупного обновления 5.9.х, приглашаем вас принять участие в вебинаре 09.06.2022 в 15:00. Участвовать

Подключение DHT22 на RASPBERRY PI 4 GPIO



  • Предварительно нужно выполнить следующие команды:

    1. sudo apt-get update
    2. sudo apt-get install python3-pip git
    3. sudo python3 -m pip install --upgrade pip setuptools wheel
    4. cd ~
    5. git clone https://github.com/adafruit/Adafruit_Python_DHT
    6. cd Adafruit_Python_DHT
    7. sudo python3 setup.py install

    Создаем устройство Датчик универсальный аналоговый и добавляем код сниппета, интервал запуска должен быть не меньше 30 секунд.

    module.exports = callback => {
      require('child_process')
      .exec('sudo python3 /home/pi/Adafruit_Python_DHT/examples/AdafruitDHT.py 22 21', function (error, stdout) {
        let value;
        if (!error && stdout && stdout.substr(0, 4) == 'temp') {
          value = parseFloat(stdout.split('=').pop()); 
        }
        if (error) {
          callback(null, error.message);
        } else {
          callback(null, value);
        }
      });
    };
    


  • @dimkrasiy Добрый день, не совсем ясно, в приведенных примерах код не для сниппетов, если вы хотите (напрямую) получать данные с GPIO почему вам просто не использовать Плагин Raspberry Pi GPIO скачиваете, устанавливаете, делаете привязку каналов(GPIO) к виртуальным устройствам. Если вам не понятна настройка плагина, не стесняйтесь задавайте вопросы, под каждым плагином есть описание настройки.



  • Я подключил датчик DHT22 к Raspberry pi 4 на прямую к GPIO.
    Установил библиотеку Adafruit_DHT
    Успешно скопировал плагин получения температуры процессора vcgencmd
    и изменил его для получения температуры с DHT

    dht_t_21.js

    /**
     * dht_t_21
     */
    const child = require('child_process');
    const plugin = require('ih-plugin-api')();
    plugin.params
      .get()
      .then(params => {
        let interval = params.interval > 0 ? params.interval : 5;
        setInterval(pollAndSend, interval * 1000);
      })
      .catch(e => {
        plugin.exit(1, 'ERROR! ' + JSON.stringify(e));
      });
    function pollAndSend() {
      // plugin.log('pollAndSend');
      child.exec('sudo /home/pi/adafruit_python_DHT/examples/AdafruitDHT.py 22 21', (error, stdout, stderr) => {
        let err = 1;
        let value;
        if (error) {
          plugin.log(`exec error: ${error}`);
        } else if (stderr) {
          plugin.log(`stderr: ${stderr}`);
        } else if (stdout) {
          plugin.log(`stdout: ${stdout}`);
          if (stdout && stdout.substr(0, 4) == 'temp') value = parseFloat(stdout.split('=').pop());
          err = value == undefined ? 1 : 0;
        } else {
          plugin.log(`EMPTY stdout!!`);
        }
        plugin.sendData([{ id: 'dht_t_21_TEMP', value, err }]);
      });
    }
    

    dht_t_21.ih

    {
        "id":"dht_t_21",
        "description":"dht_t_21",
        "cross":true,
    	"version":"0.1"
    }
    

    dht_t_21.json

    {
      "name": "dht_t_21",
      "description": "dht_t_21",
      "module": "dht_t_21.js",
      "single": 1,
      "hardchannels": 1,
      "params": [
        {
          "name": "interval",
          "note": "Интервал получения значений",
          "type": "number",
          "val": 60
        }
      ],
      "channels": [{ "id": "dht_t_21_TEMP", "desc": "SensorA" }],
      "genrules": {
        "SensorA": {
          "cl": "SensorA"
        }
      }
    }
    

    К сожалению все файлы одним архивом не могу загрузить
    Неудобство заключается в том, что нужно создавать такой плагин под каждый датчик. И мне не нравиться что нужно обращаться к датчику через команду sudo .
    Подскажите пожалуйста, как это реализовать более удобным и надежным способом ?



  • @dev Добрый день.
    Я не знаю как реализовать через сниппеты. Я показал свои наработки которые были до добавления сниппетов.
    Через Плагин Raspberry Pi GPIO не покажет значение датчика. Он воспринимает наличие сигнала (0/1). Хорош в случае выхода на питание кулера или реле а входящий сигнал воспринимать с датчика движения или открытия двери (геркон).



  • Если переделать на сниппет то будет выглядеть как-то так

    module.exports = callback => {
      require('child_process')
      .exec('sudo /home/pi/adafruit_python_DHT/examples/AdafruitDHT.py 22 21', function (error, stdout) {
        let value;
        if (!error && stdout && stdout.substr(0, 4) == 'temp') {
          value = parseFloat(stdout.split('=').pop()); 
        }
        if (error) {
          callback(null, error.message);
        } else {
          callback(null, value);
        }
      });
    };
    


  • Добрый день.
    Подскажите, пож-та, по данному варианту подключил датчик.
    Сделал 1 на температуру 2 на влажность.
    При условии что if (!error && stdout && stdout.substr(0, 4) == 'temp'
    Отображается влажность, а не температура.
    Если же вместо temp поставить Humidity то запрос не обрабатывается.

    сам сниплет
    /**

    • New snippet
      */

    module.exports = callback => {
    require('child_process')
    .exec('sudo /home/pi/Adafruit_Python_DHT/examples/AdafruitDHT.py 22 17', function (error, stdout) {
    let value;
    if (!error && stdout && stdout.substr(0, 4) == 'humidity') {
    value = parseFloat(stdout.split('=').pop());
    }
    if (error) {
    callback(null, error.message);
    } else {
    callback(null, value);
    }
    });
    };

    Отладчик
    28.02 23:02:35.909 Started
    28.02 23:02:35.934 Next start 28.02 23:02:55
    28.02 23:02:37.404 Result: undefined
    28.02 23:02:37.405 Set object: { SENSORA1: { aval: undefined, err: 0 } }

    В консоли все работает.



  • @alexeyalvl, добрый день
    Покажите пожалуйста вывод в консоль



  • pi@ihserver:~/Adafruit_Python_DHT/examples $ sudo ./AdafruitDHT.py 22 17
    Temp=24.3* Humidity=48.6%



  • @alexeyalvl, если порядок меняться не будет, то можно сделать так:

    Для считывания температуры (первый элемент):

    let value;
    if (!error && stdout) {
         value = parseFloat( stdout.split(' ').shift().split('=').pop() );
    }
    

    Для считывания влажности (второй элемент):

    let value;
    if (!error && stdout) {
         value = parseFloat( stdout.split(' ').pop().split('=').pop() );
    }
    

    Что тут делается:

    • stdout.split(' ') - строка разбивается на элементы, разделенные пробелом:
      [ 'Temp=24.3*', 'Humidity=48.6%' ]
    • shift() - берется первый элемент
      'Temp=24.3*'
    • split('=') - этот элемент разбивается на элементы, разделенные знаком =
      [ 'Temp', '24.3*' ]
    • pop() - берется последний элемент, то есть число
      '24.3*'
    • Результат обрабатывается функцией parseFloat, результат - 24.3

    Второе значение обрабатывается аналогично, только на втором шаге берется не первый элемент - shift(), а последний - pop()



  • @alexeyalvl Здравствуйте. Я не большой спец, в этом примере есть ошибка (как мне кажется) , когда я поменял в строке
    if (!error && stdout && stdout.substr(0, 4) == 'temp') {
    'temp' на 'Temp' у меня заработало.


Log in to reply