IntroductionIt has been a while but I decided that I needed to spend some time with a little single board computer that I recently purchased as part of a Kickstarter initiative but have been ignoring until now. The computer is the Onion Omega and it's mission is to enable the Internet of Things. It is smaller than either the Raspberry Pi or the Beaglebone Black that I have also messed with and it supports an onboard integrated WiFi hotspot as part of its reason for being.
|Onion in Breakout Dock Connected to Arduino Dock for Programming|
Getting the Arduino Dock SetupThe writeup in the Onion Wiki is pretty good in terms of how to get things setup and I am not going to repeat it here. The one thing that I will call out is the importance of having any sketch you download to the Arduino dock include the following code or you will be having to reprogram the dock every time you upload a sketch that does not contain this code!
Here is the note from the Wiki that should have told me that I needed to do this had I not breezed right past it:
Using I2C for Communications - Debugging Setup
My initial thought was to use serial communications between the Onion and the Arduino Dock but the architecture does not support this as an option as I2C is the recommended solution. So I went looking for a nice example to get started. I may have missed something but I could not find the example that I was looking for...which was...a matching pair of a Python application talking to an Arduino sketch! I found a Python application but not its counterpart so I wrote one.
But not until I setup a way to do some debugging using the Serial.print statements that I am used to using. I did this via the setup shown below where I connect the serial pins on the Onion Arduino Dock to the Serial2 pins on an Arduino Mega running the 'MultiSerialMega' sketch. In this manner I am able to see my debugging statements echoed on a serial console as if the Onion Arduino Dock were directly attached.
|Onion in Arduino Dock Connected to Another Arduino for Debugging|
Using I2C for Communications - Sample Scripts
As promised above, here are the sample scripts and here is a dialog of their operation with the left column being what is displayed from the Arduino and the right the output from the Python script. I think the scripts will be reasonably easy to follow once the general flow, as seen from the Arduino side is discussed. A caveat here...I don't know enough about the native I2C dialog to describe it in anything but terms that relate to what I am seeing in the examples! I would also note that these two scripts started with this one for the Arduino and this one for Python.
The Arduino Sketch:
- Included libraries: Obvious ones being the OnionLibrary and the one for Wire. The not so obvious one being the avr timing library. I honestly only really just noticed that one so am not sure whether it is actually needed!
- Setup: Setup two handler functions, one for when data is received and one for when data is requested requested.
- Loop: Nothing here for this example as all the magic happens in the two event handlers we setup above.
- The parameter passed is the number of bytes to be received (though the script does not use this data).
- The first byte will always be the register address passed from the master. For our purposes this provides a routing indicator and is stored in a global variable 'addr'.
- We then loop until we have read the data that was sent to us. We read into another global variable 'data' which will be used later. This is where we should really think about using the parameter that was passed to us but for purposes of this example I am ok with what we have done!
- Finally, the all important reset sequence! If the 'addr' was "DE" and the 'data' was "AD" then do a software reset per the Arduino Dock guidelines. If you do not do this then your will not be able to re-flash the dock from the IDE and will have to go back to the initial setup!!!
- I have setup a global variable 'seq' so we can see the number of times we have been into the default handler of the switch in the event handler (more below).
- This handler is where we use the global 'addr' as our routing indicator by virtue of the switch statement:
- '6' responds with two bytes ("QE")
- '9' responds with the last contents of 'data'
- Everything else gets the incremented value of 'seq' from above.
I think that everything in the Python script will be self explanatory given comments, the dialogs from its execution, and these notes:
- Lack of a type error on the second write of the first write test: There is a comment from the original author indicating that this should fail with a type error. It did not for me but this may be a result of different error levels in Python. I will mess with this later.
- No 'addr' on the third write of the first write test: This test sends an array of bytes using the Wire.write function. The first byte of that array will be received in my sample Arduino script as the routing indicator!
My next task will be to use I2C communications to drive a Python/Arduino integration library that I wrote a couple years ago using serial communications.