Avoid “byte-banging" with Lua and I2C?


I’ve been talking with @geofrancis, @ktrussell, and @BenBBB regarding the development of several device drivers. It seems there’s a longstanding desire for ArduPilot to support discrete temperature sensors like the DS18B20 or even simple resistive sensors, but there’s never much traction on the topic.

For the moment, GeoMuir and I are most interested in developing a “port expander” of sorts using a microprocessor as an I2C bridge and leveraging the new I2C Lua bindings to make use of it, such that 1-Wire sensors or even other GPIO devices could be made available to the scripting environment.

However, the read_registers() binding looks like it reads only a single byte at a time, while actual I2C devices under HAL get a transfer() function capable of serial read/write, and generic HAL devices have a read_registers() function that wraps it.

Is there a good method to bind the transfer() or read_registers() functions in a more flexible way? Would it require a Lua specific helper in the HAL library (like some of the IMU bindings), or is there a less intrusive way to avoid this “byte-banging" behavior with I2C comms in Lua?

Or could it be as simple as allowing a second argument in the read_registers() binding rather than the literal 1? Maybe that was a very intentional design choice and I’m just unaware of the reasoning.

I have to admit, the binding generator syntax isn’t always the easiest for me to comprehend…


its only one byte at a time because the binding gen cant handle doing a variable number of returns. Its quite easy as a custom binding, but we don’t have a way to mix autogenerated and manual bindings for a single object yet.

1 Like

Gotcha. I can work around it for now, but it would probably be very helpful to be able to read a few bytes at a time in a future release.

Happy to report a fair amount of success using an Arduino Pro Mini, the Wire library, a recent copy of Rover 4.2.0-dev, and a bit of the I2C example script.

It was particularly cool to see the gcs:send_named_float() binding in action and available within Mission Planner.

With a little more polish, the project will likely become a blog post in the near future.


I’d love to see Lua support for an I2C ADC and GPIO expander!!


I’m excited for this one, too! Been working on 4-5 projects simultaneously, so this development isn’t necessarily happening fast, but I have a good foundation for it and intend to get some proof of concept code out soon!

1 Like

This adds multi byte read, it puts the return in a table so you can access like a array.