Hi
We had a lot of fun yesterday working together on MRLComm and Arduino. Four people ( Grog, kwatters, camality and me ) working on the same sourcecode, discussing different options and ways to make the software better and add some more functionallity.
Sometimes we think in different ways, and sometimes its difficult to explain in a short shoutbox. So creating a post to describe something that is a bit larger is necessary. So thats what I'm doing now to explain the way I think about the i2c interface and the device drivers. Any comments are welcome.
The nice thing with i2c is that many different devices with very different properties can be used, using the same protocol. Each device has it's own address, so up to 62 different devices can be connected to the same 2 wires. The i2c protocol is a serial protocol and it defines how you address, read and write to a device. Each device defines how the rest of the data should be used.
Examples of i2c devices in MRL are
Adafruit16CServoDriver https://learn.adafruit.com/16-channel-pwm-servo-driver
AdafruitIna219 https://www.adafruit.com/product/904
Mpu6050 http://playground.arduino.cc/Main/MPU-6050
I2CMux https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-bre…
We have three hardwares that has i2c pins. The Arduino, the Raspberry PI and Esp8266. I will leave Esp8266 out of the discussion for now.
To make it possible to connect things together in a nice way so that each device can be used on either of the hardwares, a I2CControl interface has been defined.
It's a very small set of methods that corresponds well to file IO. You can think of the methods as open, close, read and write and a combined write/read. ( createDevice, releaseDevice, i2cWrite, i2cRead and i2cWriteRead). All the i2c devices use those methods. The RasPi service implements them and I'm working on implementing them in Arduino.
The structure for the devicedrivers is simple. You connect to a service that implements the I2CControl interface. Then you write or read to the physical i2c device based on the device specifications.
When you write, it's simple. The program continues to execute the next line of code when the data has been written.
For the read it's also easy. You read and get the requested data back so that you can continue to process it. That's how it works now with the RasPi service and that's how I hope that it can be implemented in Arduino.
But how does that fit with the publish/subscribe pattern ? Imho, each device driver should publish a set of data that is highly device dependant. The Arduino service should not publish "generic" ic2 data.
The way I think about it now, the Arduino service should read the serial data from MRLComm, and if it's i2c data that gets read, it should handle to "return" that data back to the caller ( device driver ) instead of using callback methods. Then it would work the same way as on the RasPi.
That pattern has some implications. The device drivers need to execute on the same host as the service that implements the I2CControl interface. I'm not sure if that's a big problem, since all all i2c device driver services still can communicate to remote services. ( I need to test that, but it's the intention ).
The alternative is that each devicedriver has a callback method, and that Arduino / Raspi keeps track off for each i2c device, to know what service to send the callback to. I think that was the suggestion from yesterday.
That's a bit more complex, so I want to understand the pros and cons of the different alternatives better.
/Mats
Mat ! .. heh it was fun ..
Mat ! .. heh it was fun .. I've done Agile development before with 2 people at the keyboard, but 4 people modifying code simultaneously was a totally different experience. Was exciting especially when we have very similar end goals but the details we express differently - poetry !
Here are some very general statements, which I think hold true in most situations :
I don't have the answer, and can't say all the pros & cons without learning more about Arduino's Wire I2C methods...
Generally:
interresting
interresting reading
http://www.gammon.com.au/forum/?id=10896&reply=4#reply4
http://www.gammon.com.au/forum/?id=10896&reply=10#reply10
so Wire.requestFrom() is blocking until the transaction with the device ends. If this is a problem, there is other I2C library that can be implemented
Wire.requestFrom() can return either 0 (transaction failed) or the number of bytes request
Wire.available() always return the number of bytes request, not the number of bytes send by the device. If the device send less bytes than request, it gets padded with 0xFF. If the device send more, the extra bytes are juste discarded