Evolution of a Blog

This blog has evolved as I have as a maker. It starts at the beginning of my journey where I began to re-tread my tires in the useful lore of micro electronics and the open-source software that can drive them. While building solutions around micro-electronics are still an occasional topic my more recent focus has been on the 3D Printing side of making.

Thursday, May 19, 2016

Demo for the Python Interface Class for Onion to Arduino Integration

The code for this demo (Demo.py) is on GitHub with the interface itself.  Below is an illustration of the demo breadboard with pictures of the individual components:


But where, you ask, is the Onion Arduino dock?  For some reason mine has stopped accepting a flash so I substituted a China Clone Nano instead.  The Onion library still works as if it were on the Uno and I was able to complete the demo!

The point of the demo is to provide an example of each interface function in operation.   In thinking about how to do this I came up with the above:
  • Range finder to illustrate pwmPulseHigh
  • Buzzer that sounds when a distance threshold has been breached to illustrate pwmWrite (though I am not taking advantage of different volumes that are possible with PWM)
  • Potentiometer, or variable resistor, as part of a voltage divider illustrating the reading of voltage using an analog pin.  The voltage reading is used to adjust the sensitivity of threshold where the alarm sounds
  • Servo to illustrate the servo control capability of the interface.  It moves to show the position of the above variable resistor.
  • Push button to illustrate the internal pull-up capability of the Arduino as well as a digitalRead.  Pushing the button ends our demo script.
And finally, a video clip of the demo in operation!


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.

Saturday, May 14, 2016

Back to Playing with Some Micro-Electronics

Introduction

It 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 Setup

The 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:


What this translates to from a code perspective can be found in the sample sketch that will be found later in this article.

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.
  • receiveEvent:  
    • 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!!!
  • requestEvent:
    • 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.

3D Print Technologies - Three Tanks from Three Technologies - The End

I finally got around to painting the three Jagdpanthers from my test of different 3D Printing technologies.  This is the final article in this series!  The first article in the series is here.

FDM, SLS, SLA

FDM

SLS

SLA


Friday, April 22, 2016

Another 3D Printed Diorama

I wanted an "in-situ" scene for pictures of painted AFVs and had used a city scape diorama...
 ...and one based around my Bailey Bridge model...
...but they both relied on backdrop photographs and I wanted something stand alone.  Not to mention that a T-34 is not really going to be seen crossing many Bailey Bridges?

In any case I came up with the below which does what I ask of it but still needs a lot of help with the road!

The Diorama
View from Spot Hiding Across the Fence
Ariel View
This is, of course, a couple of 3D Prints.   The surface and the cliff are two prints that could have been done as one had I been thinking.  The trees are prints, as is the fence.  Finally, obviously, the tank is a print.

Yes, the road is a mess and needs a redo!  I am rather pleased with the cliff though.

Wednesday, April 20, 2016

Pushing the 3D Printing Resolution Boundary

For my Ultimaker 2+ anyway!  

My last, honest, post of a 3D Printed AFV just for the sake of showing print quality. Namely because I can not do much better. This was printed on an Ultimaker 2+ at a resolution (layer height) of 40 microns using a 250 micron nozzle (for sharp details). The print took almost 14 hours. My printer is capable of 20 micron resolution but as you would expect that would take over a day!
Even at this resolution you can see artifacts of the printing process though they are pretty tiny. With a naked eye, and looking from 12 inches away, you can just make out some layering, and I mean just.
My conclusion would be that a consumer 3D printer can produce an amazingly detailed print if you have the right printer and a lot of patience. Still not something that you are going to buy, plug in, and press a button to make work by any means though!
I am now printing an Archer to go with this tank as I was informed that the Valentine XI is a command tank for an Archer AT unit (and the Archer looks like a cool print as well).  


Sunday, April 17, 2016

The "Patience Required" Aspect of 3D Printing

3D Printing is not foolproof and because it takes so long to do a print you may not even know that you have an issue for hours.  Hence the patience.  Additionally, as you chase higher and higher quality the threshold between success and failure also narrows.  In this case I was trying to do a print using a 250 micron nozzle at 100 micron resolution.



First Attempt - Scuppered by Human Error

I use Simplify3D as my slicer and it usually does a particularly good job of handling support material.   In this case it did not and I did not check the slicing rendering as I should have done.  This resulted in the brake plate printing really poorly.  I could have caught this earlier but don't usually observe a print once it has gotten off to a good start.  Four hours later I see that I am going to be doing another print.


Second Attempt - Scuppered by an Under Extrusion Issue

The first couple layers of this print went down well so I left it on its own to print...and did not come back to it until the build platform came down.  At that point I realize that something went south.  A 250 micron nozzle has a lower tolerance for issues than does a 400 micron nozzle and obviously something had pushed this one over the edge.  I did an atomic clean and wrote off another four hour print!

Third Attempt - Finally we Have a Good Print

Very happy with the quality of this last print and especially with the detail of the controls...which are hard to see given the white filament!  The brake plates are still not great but the geometry of that part of the model is really challenging for my printer.