Wednesday, May 18, 2016

Python Interface Class for Onion to Arduino Integration via I2C

One of the docks available with the Omega Onion micro computer features an integrated Arduino Uno in the standard Uno form factor for use with the various shields available for the Uno.   Any needed integration between the Uno and the Onion is done using I2C.  Some time ago I had written a Python library to integrate a Rpi with an Arduino so I decided to port that interface to use I2C.

The interface is driven from the Python side as the I2C library provided by the Onion only supports slave mode for the Arduino side.   I2C is both more complex and more simple than using serial communications.   Once you understand the message flow as discussed in the previous article the actual command and response flow is quite simple:

    'DR13' -->                             from Python to Arduino
    <-- '0,1,Digital read from pin 13'     from Arduino to Python


Commands that provide two arguments would have a comma separating the first and second argument (e.g. DW13,20).  The narrative after the value is there only if debug is on.

The standard commands implemented in the first version of this library are shown below:

    (P)in mode commands
    pinModeInput(pin)
    pinModeOutput(pin)


    (D)igital commands

    setHigh(pin)
    setLow(pin)
    digitalRead(pin)
    digitalWrite(pin, value)
 

    (A)nalog commands
    analogWrite(pin, value)
    analogRead(pin)
    pwmRead(pin)
    pwmPulseLow(pin, trigger)
    pwmPulseHigh(pin, trigger)

    (S)ervo commands
    attachServo(servo, pin)
    commandServo(servo, command)
    detachServo(servo)
 

    (H)ousekeeping and debugging commands
    setDebugOn()
    setDebugOff()

    setExceptionOn()
    setExceptionOff()

The most rudimentary possible example of this library in operation is shown below:

from Onion2Arduino import interfaceClass

true = 1
false = 0

# Bring in the interface we are demo'ing!
o2a = interfaceClass()

# No debug and errors will not cause an exception
o2a.setDebugOff()
o2a.setExceptionOff()

# Pin assignments for our demo hardware
BUTTON=7

# Initialization where appropriate
o2a.pinModeInputPullup(BUTTON)

# Loop until button is pressed
running = true
while running:

    # If the button has been pressed then we end this all now!
    if int(o2a.digitalRead(BUTTON)) != 1:
        running = false


print 'Done!'

There is no error handling shown above.  There are two ways to implement error handling with one being to raise and handle exceptions on error and the second being to interrogate the interfaces status after each transaction (o2a.returnStatus in the above case).

Obviously the Arduino side of this library can do more depending on a given application.  Anything that needs real time attention would need to be handled here as the Onion is not going to be reacting in real time!

The code for the interface is located on GitHub and an example of it in operation follows.

2 comments:

  1. Hey thank you for sharing ! just tried this out :-)

    ReplyDelete
  2. Your welcome. Love to see what you do with it as I never really did anything useful with it!

    ReplyDelete