Repository navigation
structure and naming: i2c python interface vs arduino #7
Description
Activity
I guess the true value of making it 100% compatible with arduino is the huge amount of code already out there to interface to different sensors, devices, etc. The i2c interface is really a trivial interface to understand no matter what API is wrapped around it, IMHO.
I guess these questions pop into my mind when I think about it:
The arduino libraries are C++ and are we going to add C++ code to the existing code base?
Are users going to be python programmers or C++ programmers?
How exactly are modules for different sensors going to added by the user?My guess is the goal is to add functionality at the user level in python as opposed to implementing some sort of easy method to import arduino code, which means the vast amount of arduino code really can't be used and must be ported. So there is going be some porting going on. Do we mimic or re-invent?
The motivation behind this interface was to keep the code small, leverage the built in capabilities of the stm chip, and provide enough functionality to easily test some i2c devices I have on hand with my micro python board.
I'm sure the final implementation is totally open for discussion.
I really don't want to pull in C++ code.
I don't see the need to be compatible with Arduino. Sure, it help people transition, but Python is so much different to C that you've got to change the way you think/code anyway, so learning the new function calls is not a big deal, IMHO.
I don't want to have to have people code in C to write a simple device driver. They should write drivers in Python, as much as that's possible. That's what the inline assembler is for, and the viper compiler (which still needs a bit of work to get it running device drivers!). So I don't really see the need to be compatible with Arduino C-names for functions.
I think wrapping the STM library to provide an interface to the peripherals, like I2C, is what we want to do. And then use this to make device drivers.
My 2 cents:
Low-level APIs should be as efficient and as low-overhead as possible. Consistency (including in naming) is extra plus.
For higher-level, it makes sense to follow existing Python protocols (abstract APIs). For example, any hardware interface deals with transferring data. This would fit file-object protocol with its read() and write() methods. Consequently, device address should be passed to constructor. Of course, there need to be extra methods do delineate bus transactions. start() and stop() sound good.
So, that leaves question of how to name low-level API. Unless function method signatures match some other API exactly, IMHO it will just add confusion to use the same names. For Arduino compatibility, there can be custom modules (API adapters).
My emphasis may not have been obvious - apologies.
I am referring only to naming not implementation.E.g. The arduino has a Serial class for comms on serial ports. It has several methods that do useful things. If the micro python one does the same (or similar functionality) then giving it the same name will aid understanding of users coming from that environment. I use Arduino specifically because I believe that is where a significant number of users will come from.
If the Arduino names don't make sense for us - e.g. for reasons of being global var oriented instead of class oriented - then I do not expect us to keep any similarity.
Well, as I hinted, the problem comes when uPy's implementation does "similar, but not completely" functionality. Then naming it as Arduino would make confusion then good. And using completely new platform of course gives chances to cleanup/improve APIs, which thus will differ. So, IMHO, following Arduino naming exactly should not be the top aim, rather should target for consist naming/params.
But I understand what you mean by Arduino compatibility and definitely support that! Except that IMHO it can live in separate module(s), just for folks who want such compatibility and not native (supposedly cleaner/more advanced) API. And I have to say that I did that even before it was possible to run Python on MCU - e.g.: https://github.com/pfalcon/arduino-hosted - there're few such modules, and I wrote mine exactly because all other I saw did NOT follow Arduino API exactly; also note that I no longer use it since I "grew out" of Arduino ;-).
OK. I concede :)
Lets just do "the right thing".Perhaps its still useful to look at the arduino libs to see the kinds of interfaces they found useful.
E.g. in i2c - a time out, callbacks, and Word sized args.@pfalcon I followed your link and agree with what you say about firmata - nevertheless I was considering writing a python module to communicate using this protocol. It seems like a somewhat widely used mechanism to communicate with microcontrolelrs and would allow (say) Processing or PureData users to easily add Micro python based controllers...
http://firmata.org/wiki/Download
Perhaps we should start a new thread/wiki page about that ?As I said before, Python is so much different to C/Arduino that we can basically start from scratch with conventions/naming and try to "get it right". That said, it's impossible to "get it right", so we can try to learn from Arduino, copy/change as we see appropriate, and make sure things are consistently named and have consistent functionality.
firmata - nevertheless I was considering writing a python module to communicate using this protocol.
I'm all for having as many different modules available for MicroPython as possible. My only concern is what goes into MicroPython core and what are community modules. What I'd love to see (and from communication with Damien I have a feeling he shares that idea) is really minimal core and vast and easy to get/use ecosystem of 3rd-party modules, centered around something like PyPi (well, it doesn't have to be "something like", it can be PyPi right away, we just need to be sure to not confuse CPython/JPython/IronPython people that a particular module requires MicroPython).
Of course, having that for uPy (specifically MCU ports) would take some more tools than just pip, and I guess python-flavin tool which you mention in the other ticket is the step in the right direction.
Anyway, so far we have #14 on the critical path.
See also #25 discussing using a different repo for additional modules. This keeps the micropython repo lean.
To summarise this issue:
- micropython intends to implement low level interfaces in C and all others built on top in python. The inline assembler and the viper compiler will take care of performance.
- this will mean a smaller core and optional modules.
- So using the example in the top post - there will be open,read,write,.. supplied in the main lib. All other i2c functions will be implemented in python on top of these.
- Looking at existing embedded libs (such as Arduino libraries) is a useful way to see what functionality and problems others have found the need to supply and solve.
- Due to the pythonic and class based nature of the environment its unlikely that many naming conventions will match existing libraries (such as the Arduino).
- added a commit that references this issue
on Aug 28, 2016 - added a commit that references this issue
on Jan 22, 2017 - added a commit that references this issue
on Jun 16, 2020 - added a commit that references this issue
on Feb 13, 2021 - added a commit that references this issue
on May 30, 2021 - added a commit that references this issue
on Jul 16, 2021 - added 2 commits that reference this issue
on Oct 22, 2025 - added a commit that references this issue
on May 23, 2026
The arduino interface is documented here:
keywords in here:
It uses a different set of function names than micro python currently does.
There is a small reason (existing users) to follow their lead, or to make similar wrapped interfaces to help migrating users from Arduino.
Although we clearly do not want to slavish about this. The pythonic approach suits us better but for low lying interfaces there is the advantage of familiarity where applicable.
What do we want to do ? Here and in general ?
(We could also make an arduino module which wrapped micropython calls to look similar to existing arduino libraries ?)
Notes:
Specifically micropython (current) vs arduino i2cdevlib:
(note that i2cdevlib also wraps the Wire library which inherits from Stream)
pyb_I2C
i2c_obj_print
i2c_obj_start
i2c_obj_write
i2c_obj_read
i2c_obj_readAndStop
i2c_obj_stop
vs:
from Wire:
begin([addr])
requestFrom(address, quantity, [stop])
beginTransmission(address)
endTransmission([stop])
write(value, [stop]) (where value may be byte, str, array)
available()
read()
onReceive(handler)
onRequest(handler)
From I2Cdev
readBit
readBitW
readBits
readBitsW
readByte
readBytes
readWord
readWords
writeBit
writeBitW
writeBits
writeBitsW
writeByte
writeBytes
writeWord
writeWords
Where - for example - readWords supports timeouts
int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout)
The arduino lib uses its Wire and Fastwire libraries for also supporting one wire and twowire devices and deals with requests for reads longer than the inbuilt buffer...
Limitations in Wire include only allowing 7bit i2c addresses.
Extra info - maybe I should put this on a wikipage ?
One-wire on Arduino:
Stream lib
SPI lib