I2C changes to get the HTU21D working.

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
User avatar
Frida
Posts: 45
Joined: Sat Jan 30, 2016 2:20 pm
Location: Middelfart, Denmark

I2C changes to get the HTU21D working.

Post by Frida » Tue Apr 12, 2016 7:21 pm

In the latest commit eec8a94 I have made some changes.

>>> i2c.scan()
[64]

Smallest scan freq is ca. 800 hz, or esp8266 resets.

To get the scan to work, I changed to write to address instead of read from address.

Code: Select all

STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
    machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
    mp_obj_t list = mp_obj_new_list(0, NULL);
    // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
    for (int addr = 0x08; addr < 0x78; ++addr) {
        mp_hal_i2c_start(self);
        //int ack = mp_hal_i2c_write_byte(self, (addr << 1) | 1);
        int ack = mp_hal_i2c_write_byte(self, (addr << 1)); // PB
        if (ack) {
            mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
        }
        mp_hal_i2c_stop(self);
    }
    return list;
}
i2c.writeto(0x40, '231') dosent work, but that does i2c.writeto(0x40, b'\xE7') # 231.

>>> i2c.writeto(0x40, '231')
>>> i2c.readfrom(0x40, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: I2C bus error

>>> i2c.writeto(0x40, b'\xE7') # 231
>>> i2c.readfrom(0x40, 1)
b'\x02'


To get clock stretching to work, I made these changes.

Code: Select all

STATIC int mp_hal_i2c_sda_read(machine_i2c_obj_t *self) {
    return mp_hal_pin_read(self->sda);
}

STATIC int mp_hal_i2c_scl_read(machine_i2c_obj_t *self) { // PB
    return mp_hal_pin_read(self->scl);
}


STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack) {
    mp_hal_i2c_delay(self);
    mp_hal_i2c_scl_low(self);
    mp_hal_i2c_delay(self);

    uint8_t data = 0;
    for (int i = 7; i >= 0; i--) {
        mp_hal_i2c_scl_release(self);
        while (mp_hal_i2c_scl_read(self) == 0) { // PB
            // clock stretching
        }
        mp_hal_i2c_delay(self);
        data = (data << 1) | mp_hal_i2c_sda_read(self);
        mp_hal_i2c_scl_low(self);
        mp_hal_i2c_delay(self);
    }
    *val = data;

    // send ack/nack bit
    if (!nack) {
        mp_hal_i2c_sda_low(self);
    }
    mp_hal_i2c_delay(self);
    mp_hal_i2c_scl_release(self);
    mp_hal_i2c_delay(self);
    mp_hal_i2c_scl_low(self);
    mp_hal_i2c_sda_release(self);

    return 1; // success
}
All done in file machine_i2c.c in /micropython/extmod


[edit]
And now temp and humidy and dewpoint comes in.

temp: 22.08019 relH: 32.7497 dew: 5.016602
temp: 22.08019 relH: 32.7497 dew: 5.016602
temp: 22.05873 relH: 32.71918 dew: 4.984558
temp: 22.06947 relH: 32.69629 dew: 4.983948
temp: 22.08019 relH: 32.69629 dew: 4.993347
Yes Frida is my watchdog!

User avatar
Frida
Posts: 45
Joined: Sat Jan 30, 2016 2:20 pm
Location: Middelfart, Denmark

Re: I2C changes to get the HTU21D working.

Post by Frida » Fri Apr 15, 2016 1:21 pm

And now with timeout

Code: Select all

        uint32_t start = mp_hal_ticks_ms(); // PB
        while (mp_hal_i2c_scl_read(self) == 0) { // PB
            // clock stretching
            if(mp_hal_ticks_ms() - start > 55) { // max 50ms/14bit/temp
              mp_hal_i2c_stop(self);
              nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error clock stretching"));
            }
        }
Yes Frida is my watchdog!

Lornioiz
Posts: 36
Joined: Wed Aug 03, 2016 11:39 am
Location: Florence, Italy

Re: I2C changes to get the HTU21D working.

Post by Lornioiz » Fri Jan 06, 2017 12:10 pm

Hi there!

I was trying to make a simple HTU21D driver but I got stuck very early because it does seems that I can't find the peripheral address.
When I execute i2c.scan() this is what I get back:

[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119]

I then found your post and I'm wondering if this is the problem that made you create the fix.
If so, can you explain me how to implement it? where should put this code?

thanks an regards

User avatar
Frida
Posts: 45
Joined: Sat Jan 30, 2016 2:20 pm
Location: Middelfart, Denmark

Re: I2C changes to get the HTU21D working.

Post by Frida » Fri Jan 06, 2017 1:06 pm

I haven't looked at it for a long time.
I put the code in: 'machine_i2c.c in /micropython/extmod'
But are you using pullup on SCL and SDA?

And the HTU21D was part of stretch goal, but I don't know of it is implementet yet?
Yes Frida is my watchdog!

Lornioiz
Posts: 36
Joined: Wed Aug 03, 2016 11:39 am
Location: Florence, Italy

Re: I2C changes to get the HTU21D working.

Post by Lornioiz » Fri Jan 06, 2017 3:52 pm

Frida wrote: But are you using pullup on SCL and SDA?

And the HTU21D was part of stretch goal, but I don't know of it is implementet yet?
The breakout I'm using as already pullups so I don't think that's the problem.
I Think I'm gonna try the fixes you wrote, thanks alot!

P.S.

I don't think the driver is implemented yet (but I'm not sure).

joeheart
Posts: 1
Joined: Sat Sep 30, 2017 3:28 pm

Re: I2C changes to get the HTU21D working.

Post by joeheart » Sat Sep 30, 2017 3:37 pm

in the neweast esp8266 firmware , i2c.scan() still can't found the address

>>>i2c.scan()
>>>[]

same htu21d connect in esp32 board ,use micropython,works good.

please someone help me.thanks a lot

dentex
Posts: 9
Joined: Wed Oct 25, 2017 4:49 pm
Contact:

Re: I2C changes to get the HTU21D working.

Post by dentex » Mon Jan 14, 2019 10:02 am

Hello,
I'm having the same problem with no results from I2C scan. Do you have now a solution? Thanks.

Running esp8266-20190113-v1.9.4-779-g5064df207

EDIT: Changing pins to D5 and D6 makes `i2c.scan()` to work: I have the right address [64], which is 0x40.
Now the error is `OSError: [Errno 19] ENODEV` ...
Other I2C peripherals on the same pins work (a BMP280 barometer and a SSD1306 oled).

dentex
Posts: 9
Joined: Wed Oct 25, 2017 4:49 pm
Contact:

Re: I2C changes to get the HTU21D working.

Post by dentex » Mon Jan 21, 2019 10:58 am

Preceding post edited...
Any hints?

Thanks.

raulmazda
Posts: 1
Joined: Thu Jan 09, 2020 7:40 am

Re: I2C changes to get the HTU21D working.

Post by raulmazda » Fri Jan 10, 2020 3:12 pm

dentex wrote:
Mon Jan 21, 2019 10:58 am
Any hints?
I found this post as I was trying to get the htu21d working on my board. I now have a working recipe on a d1 mini.

The code in main is:

Code: Select all

scl = machine.Pin(5, machine.Pin.OPEN_DRAIN, machine.Pin.PULL_UP)
sda = machine.Pin(4, machine.Pin.OPEN_DRAIN, machine.Pin.PULL_UP)
htu = htu21d.HTU21D(scl, sda)
while True:
    print('temp %f humid %f' % (htu.temperature, htu.humidity))
    time.sleep(2)
I had to slightly modify an old htu21d.py found on github. See https://github.com/laz-/htu21d-esp8266 for the working version.

Maybe some of this will help?

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: I2C changes to get the HTU21D working.

Post by kevinkk525 » Fri Jan 10, 2020 5:17 pm

There are actually quite a few HTU21D libraries and they work fine with ESP8266.
This is the one I use on my esp8266: https://github.com/kevinkk525/htu21d-esp8266


There's also one from Peter Hinch that works slightly different: https://github.com/peterhinch/micropyth ... ter/htu21d
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

Post Reply