# Работа с DHT11 и DHT22 на Wemos D1 Mini (и других)

## Подготовка платы и прошивка

### Предисловие о файле прошивки

По состоянию на 21 мая 2024 года на сайте
[MicroPython](https://micropython.org/download/?vendor=Wemos)
в разделе загрузок прошивка для **D1 Mini** отсутствовала.

По первой ссылке в поисковике увидел название файла прошивки
`esp8266-20190125-v1.10.bin` по следующей ссылке
http://micropython.org/resources/firmware/esp8266-20190125-v1.10.bin
(http://micropython.org/download#esp8266).

Я не стал скачивать предлооженный старый бинарник
и скачал слежую версию для [ESP8266 GENERIC](https://micropython.org/download/ESP8266_GENERIC/):
https://micropython.org/resources/firmware/ESP8266_GENERIC-20240222-v1.22.2.bin

### Прошивка платы

Для манупуляций необходима утилита `esptool.py`.
В репозиториях Arch Linux она имеется.

```shell
pacman -Qi esptool
```

```text
Name            : esptool
Version         : 4.7.0-3
Description     : A cute Python utility to communicate with the ROM bootloader in Espressif ESP8266
Architecture    : any
URL             : https://github.com/espressif/esptool
Licenses        : GPL-2.0-only
...
```

`esptool` также можно установить с помощью **pip**.

```shell
pip3 install esptool
```

Перед прошивкой новой прошивки необходиимо очистить память устройста,
выполнив следующую команду (`/dev/ttyUSB0` <- порт устройства).

```shell
esptool.py --port /dev/ttyUSB0 erase_flash
```

По окончанию зашиваем новую прошивку.

```shell
esptool.py \
  --port /dev/ttyUSB0 \
  --baud 115200 write_flash \
  --flash_size=detect 0 \
  /home/user/Downloads/ESP8266_GENERIC-20240222-v1.22.2.bin
```

## Обеспечиваем удобство взаимодействия

D1 Mini имеет на борту UART преобразователь на чипе `CH34x`.

Подключиться к устройству можно с помощью утилит `screen` или `minicon` (и ещё сотню других),
но более удобней будет работать с помощью `mpremote`.

```shell
pip3 install mpremote
```

### mpremote

`mpremote` - это специальная утилита для взаимодействия с платой на MicroPython.

Вот неполный листинг справки.

```text
premote --help
mpremote -- MicroPython remote control
See https://docs.micropython.org/en/latest/reference/mpremote.html

List of commands:
  connect     connect to given device
  disconnect  disconnect current device
  edit        edit files on the device
  eval        evaluate and print the string
  exec        execute the string
  fs          execute filesystem commands on the device
  help        print help and exit
  mip         install packages from micropython-lib or third-party sources
  mount       mount local directory on device
  repl        connect to given device
  resume      resume a previous mpremote session (will not auto soft-reset)
  rtc         get (default) or set the device RTC
  run         run the given local script
  sleep       sleep before executing next command
  soft-reset  perform a soft-reset of the device
  umount      unmount the local directory
  version     print version and exit
```

Сочетание клавиш `Ctrl+D` вызывает мягкую перезагрузку (`MPY: soft reboot`).  
Сочетание клавиш `Ctrl+X` закрывает соединение.

### rshell

Советую ещё установить `rshell`.

```shell
pip3 install rshell
```

С помощью `rshell` можно работать с платой через привычные команды,
такие как `ls`, `cat`, `cp` и так далее.

Небольшой пример

```shell
rshell --port /dev/ttyUSB0 # команда для подключения к плате
ls /pyboard/               # вывести список файлов на плате

boot.py                    # непосредственно сами файлы
```

`/pyboard/` - это путь к памяти устройста. **Автодополнение работает**.

## Проверка работоспособности

Подключимся к плате и проверим некоторые детали.

```shell
mpremote
```

Откроется REPL.

```python
import esp
esp.check_fw()

# size: 642064
# md5: b5c0246d25a48de7dcd4cd4d29a7830f
# True

import os
print(os.listdir())

# ['boot.py']

import network
import ubinascii

mac = ubinascii.hexlify(network.WLAN().config('mac'), ':').decode()

print(mac) # 48:55:19:e1:35:04 <- у вас соответственно будет другой MAC адрес
```

### Синхронизация времени

P.S. Не уверен, но кажется `mpremote` самостоятельно синхронизирует время при подключении.

Проверить можно вызвав `rtc.datetime()`.

```python
from machine import RTC

rtc = RTC()
rtc.datetime() # (2024, 5, 21, 1, 21, 50, 6, 824)
```

## Работаем с датчиками DHT

Документация находится по следующему адресу
https://docs.micropython.org/en/latest/esp8266/quickref.html#dht-driver.

### Схема Wemos D1 Mini

![Схема Wemos D1 Mini](https://cdn.a2s.su/blog/2024/Wemos-D1-Mini.png)

Есть ещё один вариант на сайте
[Wemos](https://www.wemos.cc/en/latest/d1/d1_mini.html).

### Подключение

В [технической документации](https://image.dfrobot.com/image/data/KIT0003/DHT11%20datasheet.pdf)
указано, что датчик питается от 3.3 до 5 вольт.

```text
3. Technical Specification:
Model DHT11
Power supply 3-5.5V DC
```

Я подключил датчик к **3.3V** и к пину **D3** (`GPIO0`).

### Получениие показаний

Вот скрипт, который опрашывает датчик каждые 5 секунд.

```python
import dht
from machine import Pin
import time

sensor = dht.DHT11(Pin(0)) # D3

while True:
    print('Measuring', end = '')

    retry = 0
    while retry < 3:
        try:
            sensor.measure()
            break
        except:
            retry = retry + 1
            print('.', end = '')

    print('')

    if retry < 3:
        print('Temperature: %3.1f °C' % sensor.temperature())
        print('   Humidity: %3.1f %% RH' % sensor.humidity())

    time.sleep(5)
```

Для тестрования достаточно выполнить команду:

```shell
mpremote run ./<script_name>.py
```

Чтобы загрузить код на плату, необходимо выполнить команду:

```shell
rshell --port /dev/ttyUSB0 cp main.py /pyboard/
```

Стоит обратить внимание, что платы на **MicroPython**
пр старте выполняют код из файла `boot.py`,
а уже после из файла `main.py`.

## Питание и глубокий сон

### Глубокий сон

Ниже представлен полный листинг программы,
которая выполняет считывание и вывод информации с сенсора DHT11,
после чегго переходит в режим глубокого сна,
пробуждаясь каждые 5 секунд.

```python
import dht
import machine
import time

WAKE_TIME = 5 # Период в секундах пробуждения устройства

sensor = dht.DHT11(machine.Pin(0)) # Пин датчика DHT11

# Настравает RTC.ALARM0 для пробуждения устройства
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)

# Проверка пробуждение устройства от глуюокого сна
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    time.sleep(2)
    print('Measuring', end = '')

    retry = 0
    while retry < 3:
        try:
            sensor.measure()
            break
        except:
            retry = retry + 1
            print('.', end = '')

    print('')

    if retry < 3:
        print('Temperature: %3.1f °C' % sensor.temperature())
        print('   Humidity: %3.1f %% RH' % sensor.humidity())

    # Задержка, чтобы успеть подключиться к REPL
    # и обновить скрипт, если что-то пойдёт не так!
    time.sleep(5)

# Устанавливает RTC.ALARM0 для активации через указанный период (пробуждение устройства)
rtc.alarm(rtc.ALARM0, WAKE_TIME * 1000)

# Переводиит устройство в спящий режим
machine.deepsleep()
```

### Питание

...

## Подключениие к Wi-Fi сети

...

## Передача данных

...
