← index #2093Issue #2290
Related · high · value 0.947
QUERY · ISSUE

RFC: Sensor driver interface

openby pfalconopened 2016-05-21updated 2025-10-01
rfc

As one of the latest KS stretch goals, we need to implement suite of drivers for number of sensors, and it would be nice to come up with a general sensor driver model to follow.

Requirements:

  1. A general, baseline interface (userstory: "I have a hundred of sensors, how do I use them in similar manner of any MicroPython port", not: "My project is centered around capabilities of a particular sensor, how do I expose them?")
  2. The general requirement is avoiding memory allocations to perform sensor reading
  3. One of the biggest contention points is usage of floating-point vs fixed points numbers, and if the latter, then how. Given that floating-point support is optional, and may lead to memory allocation, would be strongly nice to support (allocation-free) fixed point.
  4. Should be general enough for any sensor (including sensors which measure several values).
  5. There should be balance between efficiency tricks and pythonic ease of use.
CANDIDATE · ISSUE

RFC: Additional DHT sensor support, including new I2C versions

closedby mcauseropened 2016-08-04updated 2016-10-11

I would like to improve the DHT driver and add support for an additional 14 sensors.

I have been experimenting with a number of DHT sensors (Aosong AM23xx series) and have discovered there are 4 main types:

Type 1: low-resolution digital (unique to DHT11)

  • interface: 1-wire
  • humidity resolution: 1 %RH
  • temperature resolution: 1 °C
    Sensors: DHT11

Type 2: digital (AM230x)

  • interface: 1-wire
  • humidity resolution: 0.1 %RH
  • temperature resolution: 0.1 °C
    Sensors: AM2301, DHT22 (AM2302), AM2302 (Wired), DHT33 (RHT04), AM2303, AM2305 (DHT44), AM2306

Type 3: digital and I2C (AM232x)

  • interface: 1-wire, I2C
  • humidity resolution: 0.1 %RH
  • temperature resolution: 0.1 °C
    Sensors: DHT12, AM2320, AM2321, AM2322, AM2325

Type 4: I2C (AM231x)

  • interface: I2C
  • humidity resolution: 0.1 %RH
  • temperature resolution: 0.1 °C
    Sensors: AM2311, AM2312, AM2313, AM2315

With the exception of the DHT11 sensor, all of them share the same custom 1-wire protocol (unrelated to Dallas).
All of the newer sensors which have an I2C interface, have the same device and register addresses.
They are all interchangeable, with range, accuracy, stability, current draw, speed and cost being the only differences.

All of the dual digital + I2C sensors can be put in digital mode by grounding the 4th pin (SCL).

I have compiled specifications for each sensor from various English and Chinese datasheets:
https://docs.google.com/spreadsheets/d/1jbSpU-rLXuba9aubcYI15_6hI2wM7-vmQ4iPcAV7MI4/edit

I would like to update the MicroPython ESP8266 DHT driver to support all of these sensors.
I have prototyped the I2C version and it works with my DHT12.
I can test the rest of the I2C sensors once they arrive in the mail.

I added this to /scripts/dht.py and flashed to my device:

class DHTBaseI2C:
    def __init__(self, i2c, addr):
        self.i2c = i2c
        self.addr = addr
        self.buf = bytearray(5)
    def measure(self):
        buf = self.buf
        self.i2c.readfrom_mem_into(self.addr, 0, buf)
        if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xff != buf[4]:
            raise Exception("checksum error")

class DHT12_I2C(DHTBaseI2C):
    def humidity(self):
        return self.buf[0] + self.buf[1] * 0.1
    def temperature(self):
        t = self.buf[2] + (self.buf[3] & 0x7F) * 0.1
        if self.buf[3] & 0x80:
            t = -t
        return t

It works, but it can be done better.

Here is it working with a DHT12 and a WeMos D1 Mini.

Connections:

WeMos D1 Mini    DHT12
3V3 ------------ 1 (VDD)
D2 (GPIO4) ----- 2 (SDA)
GND ------------ 3 (GND)
D1 (GPIO5) ----- 4 (SCL)
import ustruct
import time, dht, machine
from machine import I2C, Pin
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=20000)
d = DHT12_I2C(i2c, 92)
while True:
    d.measure()
    print(d.temperature(), d.humidity())
    time.sleep_ms(1000)

I am not sure of the most pythonic way to structure this as each new dual interface sensor can potentially have 2x base classes, 1-wire and I2C.
They are constructed with either a single digital pin, or an I2C object + device address.
Constructor overloading?

There is also 16 DHT sensors, with probably more on the way.
They all fall into the type categories I have detailed above.
Should we have a class per type of sensor? eg. DHT11, DHT_OneWire, DHT_I2C?
A class for each of the product ranges? eg. DHT11, DHT12, AM230x, AM231x, AM232x?

Hoping someone with a bit more Python experience can help with the structure.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied