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.

Friday, October 26, 2012

Time for some Python

I have chosen to use Python as the development language for my 'bot.   One reason being that it seems to be the 'standard' higher level language for the Raspberry Pi and is a default on the Wheezy distribution of the O/S.   A second is that it is a cool language!  I grew up with interpreted languages and really like being able to prototype code at the command line.   More importantly it is also a good OO platform and has a large eco-system of extensions.  

In any case...I am using it and liking it as well.   One thing that I do find a little bizarro is the spacing sensitive syntax.   Instead of relying on something like "{" to group code Python relies on levels of indent.   Makes sense and also enforces neat code but is still strange!

From this point in the blog posts will start to mix between the hardware, which has consumed me to date, and the software that will be driving it.

Learning Python By Lutz, Mark (Google Affiliate Ad)

Wednesday, October 24, 2012

More Compass Shenanigans

My compass continues to be possessed by evil demons.  I am pretty confident that living in the shadow of Brunel's Sounding Arch bridge outside of Maidenhead, home of one of the worlds busiest train lines, is part of the problem.  The HMC5883L is supposed to be accurate within a couple of degrees but mine varies all over the map and is convinced that east and west are not 180 degrees apart.   I have not had a chance to prove this by testing somewhere else but will at some point.

I could live with this behavior for now assuming it were reasonably stable...which it has not been.   For example, I tell the 'bot to turn 10 degrees to the right and it went into an infinite loop chasing a bearing that it never attained.  This is not good!   It turns out that my own electric motors kick up enough magnetic disturbance to freak it out (maybe in tandem with the electric train lines near us)?   I had originally mounted the device on the bread board in the center of the Explorer PCB but moved it to the rear and mounted it on a little mast.   I have now raised that mast and it seems to have helped...with at least one aspect of it's behavior!

My original thought was that I could use the compass when doing mapping (a function that I envisioned for my 'bot).   At this point I am not convinced that I am going to be able to do this given the required accuracy.   This leaves me with the quandary of how to know the bot's position.   I was hoping to have a bearing and use the range finder for distance.   Hmmmm.

For an update on this issue see this post.

Monday, October 22, 2012

Crude FTP Update in Python

I have been keeping the code for my 'bot on my Ubuntu laptop, updating it from my iMac, and then running a Python script to FTP it to the RPi.   Once major problem with this is that sometimes I will make a change and forget to run the update and then wonder at the abstinence of the 'bot to have changed it's behavior!  

I could simply cron the script to run every how often but this didn't feel very eloquent especially as the copy includes everything whether it has changed or not.  So not that my solution is terribly eloquent but I decided to write a quick script to only move code that has been changed and then put this inside a 15 second iteration loop.

I have one big try statement as my assumption is that a failure means the RPi is not online and that I should try later.

Code for "Crude FTP Update"


Wednesday, October 17, 2012

Arduino - Voltmeter

The following code illustrates both the reading of a voltage with the Arduino and then adjusting it using the code from the Secret Arduino Voltmeter article by Scott Daniels:

Do some initialization stuff (obviously this is not Arduino code as I am using my interface library):

    import time
    from Py2Ard import interfaceClass
    my_board = interfaceClass('/dev/ttyACM0')


Get the reference voltage and use it to calculate an adjustment from 5 volts:

    if my_board.referenceVoltage() != 0:
        print "Error"
    else:
        print
        print "--------------------------------------"
        refVoltage = float(my_board.returnValue) / 1000
        print "Reference................. {0:.3f} volts".format(refVoltage)
       
        adjustToRef = 1 + (refVoltage - 5) / refVoltage
        print "Adjust to Reference....... {0:.3f}".format(adjustToRef)
        print "--------------------------------------"
       

Get the voltage we are trying to measure and adjust it using the above factor.  Note that the '* .0049' converts the analog return from reading the voltage to a five volt scale.  The '* 2' then doubles that value to compensate for the voltage divider factor of 50%:

    if my_board.pinModeInput(5) != 0:
        print "Error"
    if my_board.analogRead(5) != 0:
        print "Error"
    else:
        mainVoltage = float(my_board.returnValue) *.0049 * 2
        print "Input - As Read........... {0:.3f} volts".format(mainVoltage)
       
        mainVoltage = mainVoltage * adjustToRef
        print "Input - Adjusted.......... {0:.3f} volts".format(mainVoltage)
   
    
The actual voltage at this point in time is 7.82 as read from our meter so calculate an error percentage:
    
        actualVoltage = 7.82
        error = (actualVoltage - mainVoltage) / actualVoltage * 100
        print "Error from Actual......... {0:.1f}%".format(error)
        print "--------------------------------------"
        print
   
    
The output from the above script is shown below.   Note that I have also adjusted the Arduino referenceVoltage script provided by Scott Daniels as he suggests in his article (adjusting for the inaccuracy of the 1.1v reference by actually measuring the 5v Arduino output and adjusting for the difference).

    --------------------------------------
    Reference................. 4.910 volts 
    Adjust to Reference....... 0.982
    --------------------------------------
    Input - As Read........... 8.026 volts 
    Input - Adjusted.......... 7.879 volts
    Error from Actual......... -0.8% 
    --------------------------------------


Caveat comes here...it feels like I am double adjusting things to arrive at the answer that I want rather than the right answer...  I may post this on Scott's page and ask him if my not electronically oriented brain has miss interpreted things badly!


Tuesday, October 16, 2012

Raspberry Pi Wireless Network Drops

My Belkin N150 network connection had been dropping on a regular basis. The RPi is still humming along (it is connected to an Arduino and is still commanding it happily) but no network.

I logged this problem on the Arduino Forum and got a number of suggestions with the ever present check of power high among the suggestions.   In fact, when I am on battery power I do have more problems as I am having power regulation issues.  This said, the problem does not go away when on wall power.

The thing that has most seemed to help was suggested by "Pluggy" and that was to add the following to the bottom of "/etc/network/interfaces":

    wireless-power off

I could not find a lot of documentation about this entry on the web though what I read implied that it disabled a standby power down.   This would make sense in terms of it helping if my drops were during periods of inactivity...but they are not...and it helped!

Not sure why but I guess one should not look gift horses in the mouth as my connection is very much more stable!?!?

Here is the whole thread on the Arduino Forum (which is a very useful place).

Arduino and Voltage Measurement - Voltage Divider

Every good 'bot should measure it's power levels and beam them home in a telemetry stream.   I really did want to keep track of my main batteries but I might have gone a little overboard when I tossed in measurement of power within the RPi and on the 5v Bus of the Explorer PCB.   There are a number of really good articles on the web that I used for this endeavor so I will start with them:

Voltage Divider - The Arduino can only measure a range to 5v so dividing a larger source is a must and this article is a good one for some help. 

Secret Arduino Voltmeter - Describes how to use the Arduino's reference voltage to adjust to variations in the input voltage that is driving your board.   The code provided by this example is now behind the method referenceVoltage in my interface library.  I will talk about this in my next post.


VOLTAGE DIVIDER

My main battery pack is six AA cells so my input voltage will be somewhere around 7.2 volts (1.2v x 6 cells).   This is clearly above the 5v maximum for the Arduino so we need this voltage divider!

For this demo I am using two resistors of 4.6k each.   This will divide the voltage in half (for more on how this works please see the article referenced above. I am not sure where the break points are but two low and you burn more power than you should and two high your accuracy suffers to the point of the Arduino not being able to get a reading.

The batteries are connected to the breadboard power bus outside of the camera frame.

The two resistors bridge the power bus to where I am taking my reading of the divided power.  

The input is 7.92 and the output is 3.96.  As near as I can tell that is a pretty good division by two!

The Explorer PCB has an area intended for soldered in additions but my 'bot has a breadboard mounted there so I can easily mess with things.   That is where the same division happens for the 'bot.

Sunday, October 14, 2012

Python to Arduino Interface - Part 2

This is the second part of a topic introduced a while ago here but not finished until now.  Note that Part 3 of this series of posts, including an updated library, is now available here.

One of the files packaged with the Python to Arduino Interface download is a short sample illustrating basic functionality.   Here is that sample with some additional commentary and a screen shot of it in operation:

Import the library

    import time     
    from Py2Ard import interfaceClass

The only argument the class needs is the port on which to find the Arduino

    # Specify the port as an argument     
    my_board = interfaceClass('/dev/ttyUSB0')

The two options below are useful for debugging.   Setting TraceOn will result in both sides of the interface making a log of what they are asked to do.   On the Python side this means writing to Py2Ard.log.   On the Arduino side it means caching the last 50 commands and then dumping them on command to the Python side.    Setting DebugOn causes the Python side of the interface to echo what is being done and the Arduino side to return long responses.    Obviously both of these options slow things down!

    print "---------------------------"
    my_board.setTraceOn()
    print "---------------------------"
    my_board.setDebugOn()
    print "---------------------------"

The following code causes the onboard LED to blink.    It is 1-1 analogous to what you would do in Arduino code directly.  Note that a -1 is returned from the Python side of the interface if there has been an error with the "returnDebug" attribute having the reason for the error.

    print "Pin Mode to Output" 
    if my_board.pinModeOutput(13) == -1: 
        print "Error:" + my_board.returnDebug
    print "Set High" 
    if my_board.setHigh(13) == -1:
         print "Error:" + my_board.returnDebug 
    time.sleep(1)
    print "Set Low" 
    if my_board.setLow(13) == -1:
         print "Error:" + my_board.returnDebug
    time.sleep(2)

Finally we dump the trace stuff that the Arduino side of the interface has been collecting.   if debug is currently on, as it is in this case, the dump will be shown on the screen as well as written to the log file.

    print "---------------------------"
    my_board.dumpTrace()
    print "---------------------------"

The screen shot of this sample running:

    ---------------------------
    ---------------------------
    returned False value Debug set to 1
    ---------------------------
    Pin Mode to Output
    @setLastTime
    returned False value Set last time for trace
    @pinModeOutput for pin 13
    returned False value Pin 13 set to Output
    Set High
    @setLastTime
    returned False value Set last time for trace
    @setHigh for pin 13
    returned False value Pin 13 set HIGH
    Set Low
    @setLastTime
    returned False value Set last time for trace
    @setLow for pin 13
    returned False value Pin 13 set LOW
    ---------------------------
    @setLastTime:09:25:26
    returned False value Set last time for trace
    @dumpTrace
    returned False value Trace dump follows
    Arduino -  - 0,Trace set to 1 - 12718 (12718)
    Arduino -  - 0,Set last time for trace - 12726 (8)
    Arduino - 09:25:23 - 0,Debug set to 1 - 12734 (8)
    Arduino - 09:25:23 - 0,Set last time for trace - 12742 (8)
    Arduino - 09:25:23 - 0,Pin 13 set to Output - 12750 (8)
    Arduino - 09:25:23 - 0,Set last time for trace - 12761 (11)
    Arduino - 09:25:23 - 0,Pin 13 set HIGH - 12770 (9)
    Arduino - 09:25:23 - 0,Set last time for trace - 13779 (1009)
    Arduino - 09:25:24 - 0,Pin 13 set LOW - 13788 (9)
    Arduino - 09:25:24 - 0,Set last time for trace - 15799 (2011)
    Arduino - 09:25:26 - 0,Trace dump follows - 15808 (9)
    Arduino -
    Arduino - #EOD#
    ---------------------------
 

The bottom of the screen shot (between the dashed lines) is the trace dump returned from the Arduino.   The second column is a time stamp set from the Python side to help you sync up what was happening.   The five digit number followed by the number in parenthesis is the execution time on the Arduino with the parenthesis being the time between the previous command and the one in parenthesis.

The trace functionality is a large part of the reason that I wrote my own interface.   If you are adding your own functionality to the Arduino side the ability to log stuff can be very useful.   Just call traceEntry with your own message for the trace log.