Add command_read_digital_in

I would like to add support for reading an HX711 load-cell sensor to the klipper mcu firmware. It implements a serial protocol that is kind of i2c-ish, but not close enough to actually use an actual i2c peripheral. Looking at the datasheet, and the available mcu commands I think I can bit-bang the protocol from the python code if a command was added that would allow for polling of GPIO pins.

Klipper pull request #4331 implements a command_read_digital_in(...) method that looks like this:

void
command_read_digital_in(uint32_t *args)
{
    struct gpio_in n = gpio_in_setup(args[0], args[1]);
    uint8_t val = gpio_in_read(n);
    sendf("read_digital_in_value pin=%u value=%c", args[0], val);
}
DECL_COMMAND(command_read_digital_in, "read_digital_in pin=%u pull_up=%c");

Is the approach taken there sensible for frequent polling of a pin state? Is the idea of implementing a serial protocol via commands to the MCU (toggling a clock pin and read incoming data) even realistic in the course of normal printing operation?

Such a facility wouldn’t just be of use to this particular project. Any number of one-off serial protocols could be implemented in python allowing more sensor types to be integrated. Some that come to mind are the DHT22 Temp/humidity sensors or the Dallas 1Wire temperature sensors.

1 Like

See introduce load cell-based probe by mhier ¡ Pull Request #4738 ¡ Klipper3d/klipper ¡ GitHub

That is a related feature but requires an ADC chip that implements an actual i2c interface. The ubiquitous HX711 chip has a very different interface and cannot be polled by the i2c peripheral in most (any?) MCUs.

Fair enough. There is also already a 1-wire implementation. Maybe this can provide further insight: module: DS18B20, new module for 1-wire temperature sensor (WIP) by theopensourcerer ¡ Pull Request #3462 ¡ Klipper3d/klipper ¡ GitHub

That approach requires the sensor to be attached to host RaspberryPi and for the Pi to be configured as a secondary MCU. It looks like there is a kernel module available for the HX711 (linux/hx711.c at master ¡ torvalds/linux ¡ GitHub) so that might be a viable solution.

Thanks for the links.

What’s the purpose of the loadcell? Since there’s 25ms latency it might be better to implement the driver/smoothing/logic on the mcu.

The immediate itch I’m scratching is to measure extruder filament force while extruding at different temperatures/rates or through different nozzles. My searches have found other people interested in using a load cell for:

  • ABL probing
  • Axis limit switch
  • Filament spool weight sensor
  • Extruder clog/jam detection

Where is the 25ms delay you are referencing?

I’m not familiar with the specifics of the hx711. However, if the “bit banging” protocol that it uses has timing requirements then it is likely one would need to implement micro-controller code for it. See src/neopixel.c, src/pulse_counter.c, and similar as examples.

-Kevin

1 Like

If I’m reading this diagram correctly they say “typical” clock frequency is 1uSec for High and Low which = 500kHz for 50% duty cycle. Looks like some amount of clock stretching is permissable but if the clock line stays high for too long the chip will reset itself.

25 clock pulses is 50uSec at the ‘typical’ rate, and 10uSec at minimum. Is that too long to monopolize the processor for a busy loop that would be run every 12ms or so? Does the answer change if it is housed on its own MCU (pi pico, etc.) as is commonly done with the adxl345 chip? What about using a lower clock rate and do the bit twiddling and reading by scheduling timers to go off in the near future?

I was way off - I meant 25us which, if I understand correctly, is the max delay that can occur when homing sensor is activated and klippy receives it.

I have interest as well in a HX711 interface. This could go well with my load cell based probe (see PR linked above in the first reply). Is someone already actively working on this? Otherwise I would have a deeper look how to do that. It will definitively involve changing the microcontroller code. The protocol is closer to SPI than I2C, but what is definitively special is that the HX711 sends a data ready signal by lowering the data line, which needs to trigger the readout.