SHT21 i2c sensor gives 'list index out of range'

Basic Information:

Printer Model: Voron Switchwire
MCU / Printerboard: BTT SKR Mini
Host / SBC: r-pi 4
klippy(1).log (129.7 KB)

Fill out above information and in all cases attach your klippy.log file (use zip to compress it, if too big). Pasting your printer.cfg is not needed
Be sure to check our “Knowledge Base” Category first. Most relevant items, e.g. error messages, are covered there

Describe your issue:

Hi,

I have added a SHT21 sensor to my printer, and added this to my printer.cfg:

[mcu pihost]
serial: /tmp/klipper_host_mcu

[temperature_sensor Pi]
sensor_type: temperature_host
min_temp: 10
max_temp: 100


# [htu21d]

[temperature_sensor chamber]
sensor_type: SHT21
i2c_mcu: pihost
i2c_bus: i2c.1
# i2c_address: 64
# htu21d_resolution: TEMP11_HUM11
# htu21d_report_time: 20

i2cdetect works, and sees the sensor

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

I have tried a lot of different iterations of the config, but I always get:

htu21d: Unknown Device ID 0x1 
Unhandled exception during connect
Traceback (most recent call last):
  File "/nix/store/h0v1gcg8dzpjwlz7jw2x5y3slqbxqp6n-klipper-0.12.0-unstable-2024-10-26/lib/klipper/klippy.py", line 135, in _connect
    cb()
  File "/nix/store/h0v1gcg8dzpjwlz7jw2x5y3slqbxqp6n-klipper-0.12.0-unstable-2024-10-26/lib/klipper/extras/htu21d.py", line 102, in handle_connect
    self._init_htu21d()
  File "/nix/store/h0v1gcg8dzpjwlz7jw2x5y3slqbxqp6n-klipper-0.12.0-unstable-2024-10-26/lib/klipper/extras/htu21d.py", line 140, in _init_htu21d
    if self.deviceId != deviceId_list[0]:
                        ~~~~~~~~~~~~~^^^
IndexError: list index out of range

I’m out of ideas, any help would be appreciated

Thanks!

Discord discussion on the same problem, if anyone wants that context.

Hello @cnf !

[temperature_sensor chamber]
sensor_type: SHT21
i2c_mcu: pihost
i2c_bus: i2c.1
# i2c_address: 64
# htu21d_resolution: TEMP11_HUM11
# htu21d_report_time: 20

What’s about the i2c address in line 5 ?

Hi, 64 is the default (0x40), uncommented or commented makes no difference.
All commented fields make no difference uncommented, i just left them to show I have tried them.

The setups via the Linux host are always a bit fiddly. It usually has a lot of quirks, starting from the correct setup in the OS with its device tree overlays, through the userspace GPIO control libraries, up to Klipper.

I’d rather recommend using a small RP2040 board and hooking up your sensors there. Often, it’s a lot less problematic. For an example see Klipperize IFD-175 AP (prototype)

Why is it fiddly, though? The sensor works on the host, it’s just a weird python error in klipper for some reason. I don’t see why i’d expect to see anything different going through another intermediary?

[root@vs99:~]#  echo sht21 0x40 > /sys/bus/i2c/devices/i2c-1/new_device

[root@vs99:~]# sensors                                                 
sht21-i2c-1-40
Adapter: bcm2835 (i2c@7e804000)
temp1:        +23.9°C  
humidity1:     40.8 %RH

I get correct values from it, if I initialize it. So I’d say it’s probably a klipper issue, not a host issue.

Of course if I do that, I get Unable to open i2c device which makes sense.

Klipper still gives me ‘list index out of range’

htu21d: Unknown Device ID 0x1 
diff --git a/klippy/extras/htu21d.py b/klippy/extras/htu21d.py
index ec44da633..c9325ac74 100644
--- a/klippy/extras/htu21d.py
+++ b/klippy/extras/htu21d.py
@@ -136,6 +136,8 @@ class HTU21D:
             logging.info("htu21d: Found Device Type %s" % deviceId_list[0])
         else:
             logging.warning("htu21d: Unknown Device ID %#x " % rdevId)
+            # List is empty, it is required to forcing the type
+            deviceId_list = [rdevId]
 
         if self.deviceId != deviceId_list[0]:
             logging.warning(

IDK, if it is a real one STH21 and if that behavior is normal.
There is an issue in the code, so this is a duct tape patch here.

Hope that helps.

That did, in fact, do the trick!

Thanks!

Not sure how to get that into klipper / or report this, as the issue tracker is closed now…

You have already defined an issue here, it is enough, thank you.
If you are willing to write a full-fledged patch, you can do that.
And send it as a PR.

If you can show the macro photo of the SHT21, that probably helps.

Because technically, that allows us to assume 0x1 as SHT21 in the code.

You can show us the fresh/patched log, so I can see the actual log output.

Probably lambda code, should be rewritten to totally avoid the situation with an empty ID.
Instead of my duct tape solution, where I know it is empty, I set it to “something”.

If you don’t do that, I can probably do that myself, and later will ask to test PR.

Thanks.

1 Like

Isn’t the device ID effectively this: https://www.sos.sk/a_info/resource/c/sensirion/Sensirion_Humidity_SHT2x_Electronic_Identification_Code_V1.1.pdf?

1 Like

That explains something,
Technically, we are already doing that:

>>> hex(0b11111010),hex(0b00001111)
('0xfa', '0xf')
>>> hex(0b11111100),hex(0b11001001)
('0xfc', '0xc9')

...
    'SERIAL'            :[0xFA,0x0F,0xFC,0xC9],
...
        # Read ChipId
        params = self.i2c.i2c_read([HTU21D_COMMANDS['SERIAL'][2],
                                    HTU21D_COMMANDS['SERIAL'][3]], 3)
        response = bytearray(params['response'])
        rdevId = response[0] << 8
        rdevId |= response[1]
        checksum = response[2]

Hmmm…

Maybe it is just a meaningless number here :smiley:
idk

Like there is no specific information in the above document, so it seems like there could be any numbers.

This was my thinking as well, and thanks for confirming that I did not totally misread the code.

Maybe the only reason for this could be differentiating various sensors of the same kind. However, this would still require different I2C addresses or buses to serve as a means of differentiation.

Edit:
The same seems true for the SHT3x series: https://sensirion.com/media/documents/E5762713/63D103C2/Sensirion_electronic_identification_code_SHT3x.pdf

1 Like

Simplify to (not empty && CRC OK) as general sanity?

idk, seems like this code worked for others and for all clones of SHT21.
So, I would suggest just not to break anything.

But technically, yes, it seems that we can simply use the provided config value (which is actually happening already).
And just check that DevID is reading correctly, without direct verification of content.