Klipper3d / klipper

Klipper is a 3d-printer firmware
GNU General Public License v3.0
9.41k stars 5.3k forks source link

[DEVELOPER QUESTION] I2C: Set read timeout or Read without Write. #2795

Closed dianlight closed 4 years ago

dianlight commented 4 years ago

I'm implementing the python module to read the temperature from the HTU21D sensors via I2C. The problem is that from specifications the sensor responds asynchronously (with a delay of up to 30ms) to the read request. As for how the features have been implemented, there is no i2c_read without writing and it is not possible to set the timeout to i2c_read.

Is there something that escapes me or did I just read the code?

If there is no functionality, I am available to develop a PR to add this type of functionality on the i2c bus.

L.

klipper-gitissuebot commented 4 years ago

Hi @dianlight,

It did not look like there was a Klipper log file attached to this ticket. The log file has been engineered to answer common questions the Klipper developers have about the software and its environment (software version, hardware type, configuration, event timing, and hundreds of other questions).

Unfortunately, too many people have opened tickets without providing the log. That consumes developer time; time that would be better spent enhancing the software. If this ticket references an event that has occurred while running the software then the Klipper log must be attached to this ticket. Otherwise, this ticket will be automatically closed in a few days.

For information on obtaining the Klipper log file see: https://github.com/KevinOConnor/klipper/blob/master/docs/Contact.md

The log can still be attached to this ticket - just add a comment and attach the log to that comment.

Best regards, ~ Your friendly GitIssueBot

PS: I'm just an automated script, not a human being.

KevinOConnor commented 4 years ago

To be honest, the Klipper i2c code isn't particularly flexible. It was originally designed to setup stepper current via mcp4451 (and similar) dac chips. It's since been used on a few other chips, but Klipper's error handling isn't great. (Part of the problem, though, is that i2c hardware support is in general pretty fragile as well.)

That said, it should be possible to issue a Klipper i2c_read command with a zero length "reg" field. That would be a read without any write. I'm not familiar with the HTU21D so I'm not sure if that helps or not.

-Kevin

dianlight commented 4 years ago

I checked the various implementations (I ignored architectures without i2c support or without i2c_read support.) and sending a write_len of 0 doesn't seem like a managed case to me:

I don't have a hw avr or atsam to try but under linux the writing of a len 0 on at least a RPi 3B + can give problems (the i2c device become unresponsive).

Making a PR to handle the case at len ​​= 0 is quite simple and safe from regressions and would solve the problem only on linux where there is no timeout. On atsam and avr where the timeout 5000us the mcu would shutdown.From HTU21D datasheed read has variable response time in the range of 4 / 20ms. The timeout window is too small.

If this is fine for you I would like a PR to better manage the case of len = 0 and add the support of i2c_read_if_data which in case of timeout does not bring the MCU shutdown but returns no data message . So:

dianlight commented 4 years ago

PR #2803 contains the driver with a len=0 patch for Linux_mcu.

if the i2c_read_if_data implementation is of interest, I can work on it.

KevinOConnor commented 4 years ago

FWIW, I agree that all the architectures should treat a zero length write as a request for just a read.

-Kevin

KevinOConnor commented 4 years ago

I'm going to close this as it looks like the original question was answered (the handling of read_length=0 requests in some architectures could be improved).

-Kevin

NeilvdM commented 3 years ago

I'm implementing the python module to read the temperature from the HTU21D sensors via I2C. The problem is that from specifications the sensor responds asynchronously (with a delay of up to 30ms) to the read request. As for how the features have been implemented, there is no i2c_read without writing and it is not possible to set the timeout to i2c_read.

Is there something that escapes me or did I just read the code?

If there is no functionality, I am available to develop a PR to add this type of functionality on the i2c bus.

L.

Hi @dianlight , I have been searching the web for help on my issue, which I hope is similar to what you were talking about here. Im trying to connect a BME280 sensor to a RPi3B+ I have followed the examples in the Klipper documentation I keep on ending with: MCU 'mcu' shutdown: i2c timeout.

For MCU, I have this in the Config file: [mcu host] serial: /tmp/klipper_host_mcu

[mcu]

make sure this reflects your serial port you found when flashing klipper

serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0

and the BME280: [temperature_sensor my_sensor] sensor_type: BME280 gcode_id: AMB

another Example I found for the BME280, you have to include the Bus, but that gives me this error:

[temperature_sensor my_sensor] sensor_type: BME280 gcode_id: AMB i2c_address: 118 Default is 118 (0x76). Some BME280 sensors have an address of 119 (0x77). i2c_mcu: mcu i2c_bus: i2c.1 i2c_speed: 100000 See the "common I2C settings" section for a description of the above parameters.

the Error: Unknown i2c_bus 'i2c.1'