Mark Gilbert's Blog

Science and technology, served light and fluffy.

Moving back from the Cloud

Back in August I mentioned moving my critical files to the cloud so I’d have them available from both home and at work.  At the time I selected OneDrive to be my cloud storage provider, and mapped a network drive on both machines so all of my shortcuts would work.

While it solved the problem of losing a very tiny thumbdrive, it introduced some serious lag to Tasks, my custom-written task management app.  Every time I needed to create a new task, update an existing one, or reprioritize the things on my todo list, there was at least 2-3 seconds (and sometimes a lot more) delay in committing that change to OneDrive.  Very soon after I began using OneDrive like this, I started to think through how I could hide more of this lag in the background of Tasks so it would be less noticeable.

Then last week I started getting permission errors from OneDrive.  After some tinkering, I found that I could no longer even drag files into the drive letter I had mapped, or directly modify files through the drive letter, without it complaining about permission issues.  If I did everything through the browser, it was fine, but not through my drive letter.

I spent a night troubleshooting it, and then I pulled out my old thumbdrive as an interim solution.  I went a week like that, hoping that Microsoft would sort out whatever it was they had changed.  This weekend I retested it, and found it was still misbehaving.  I took another look at using Google Drive, but apparently you need some third-party software to map a drive letter to it, so I abandoned that idea.

That’s when I took a hard look at what I had in the cloud, and found that I either didn’t really need access to those files at work, or came up with alternatives (like the occasional email to myself).

Today was my first day 1) not carrying a thumbdrive, and 2) not relying on the cloud for anything relating to my todo list.  To my surprise, I barely noticed the difference.  I felt just as productive, and no longer experienced any of the lag I was seeing with saving things to OneDrive.  I still use Tasks at home, though, but the files are now stored on my local server, rather than in the cloud, so again – no thumbdrive and no lag.

Am I annoyed with OneDrive for ceasing to work?  A little, but being forced to give it up allowed me to ditch the lag at the same time, so I won’t be annoyed for long.

January 30, 2017 Posted by | Tools and Toys | Leave a comment

Dropping a mic – and picking up another

In the middle of our most recent podcast we had a major technical failure.


The microphone Katherine, Lucy, and I have used for the first 32 podcasts finally gave up the ghost.  To be fair, it had broken a couple of times before, and I had apply liberal amounts of glue to piece it back together.  This time, though, half of the audio tracks Lucy and I recorded had too much static to be usable.

So, we said goodbye to Computer Associates, and hello to Tonor.


This is a Tonor 3.5mm Cardoid Condensor Microphone.  We recorded all of the tracks for Episode 33 with the Tonor, and we think it sounds at least as good.  Let us know what you think!

January 11, 2017 Posted by | Podcast, Tools and Toys | Comments Off on Dropping a mic – and picking up another

Science & Technology Podcast, Episode 33: String Shooter

Mark and Lucy build a machine that shoots string, and lets them play with waves:

January 10, 2017 Posted by | Podcast, Science | Comments Off on Science & Technology Podcast, Episode 33: String Shooter

Science & Technology Podcast, Episode 32: Summoning Thor’s Hammer

Where we build a second prototype of a flying Thor’s Hammer that you can summon:

September 23, 2016 Posted by | Podcast | Comments Off on Science & Technology Podcast, Episode 32: Summoning Thor’s Hammer

Moving to the Cloud

For many years, I’ve carried what you might call my life’s work on a thumb drive.


This 4GB drive held sample code I put together, documents I’d written, all of the data files for Tasks, my personal log – everything.  It was getting backed up every night to the cloud, but the primary source of truth was always this drive.

Then a couple of months ago I got a new laptop at work, mostly because I found myself needing to travel more frequently – whether it was down the hall to a conference call, or out of state for an onsite.  Since this was my primary machine, I would faithfully plug this thumb drive into the side.  However, it would stick out so far I was always afraid I would snag it on something, and bend or otherwise damage it.

So I replaced it with this tiny SanDisk.


My thinking was that it would keep a low-enough profile that I wouldn’t need to worry about it catching on anything.  I wasn’t wrong there, but moving to such a small thumb drive had an unexpected consequence.  I had to pay extra attention to where the thing was when it wasn’t a) plugged into my computer, or b) zipped up in my laptop case.

In other words, it was so tiny I was in danger of losing it every time I put it in my pocket. 

That thought increasingly nagged me.  Then one morning I walked out to my car and it fell out of my pocket when I retrieved my keys.  When I got to the car, I patted my pocket to make sure it was there, and it wasn’t.  I hurriedly retraced my steps, and found it in the garage.  I never even heard it hit the ground because the noise from the garage door opener masked the impact.  I resolved then and there to find a better solution.

I took a long hard look at what was on the drive, and what I actually needed with me:

  • I was keeping several software installers and configuration files on that drive.  Those were easy to move to my home server.  If I actually needed them at work, I could always wait a day, and bring in what I needed the next morning.
  • The next batch of files comprised the bulk of the contents of the drive.  They were files I rarely dipped into, and more times than not was actually at home when I did.  Those also got moved onto my home server.
  • Then there were a handful of files that I would actually need at work.  These were rarely (if ever) needed at work, so those got left on my corporate user’s drive.

Then it came down to the files that I would needed regularly at both home and at work – the files that Tasks required, and my personal log.  I didn’t want to load those onto my phone because then I’d have to keep it jacked into my computer to access them.  I also discarded any "syncing" solution due to my previous bad experiences.

That left me with putting these files in the cloud.  Would it be possible to map a drive letter to a folder somewhere (a requirement to keep Tasks work as is), and let me access them from home or at work?  I looked at both Microsoft’s OneDrive and Google’s Drive, and as it turns out both allow me to map a local drive letter.  I ultimately went with OneDrive since I already had files up there from past projects. 

With these files in the cloud, I had completely weaned myself off of thumb drive.  I could now fire up Tasks at home or at work, and get to all of my project notes.  The biggest downside has been the lag – saving files to the cloud is substantially slower than saving them on my thumb drive.  I’ve started thinking about ways to modify Tasks to do its saving-to-the-cloud in the background, making it more responsive.

I have so far had one occasion where I lost a file update (memories of August 2009 came rushing back – see the links above).  I wasn’t sure what triggered it, but somewhere along the way one of my most critical project files got completely wiped out – a 0-byte was all that remained.  I had a relatively recent update, and only ended up losing a few hours’ worth of work, but as a result, I’ve tweaked my regular backup to pull these files down from OneDrive, nightly.

All in all, the move to the cloud seems to be working fairly well, and it certainly renders the question of "what do I do if I lose my thumb drive?" moot.

August 13, 2016 Posted by | Tools and Toys | Comments Off on Moving to the Cloud

Test-Driven Home Repair

Over the last year, our fluorescent kitchen light was starting to show signs of wear.  Some mornings it would take several minutes to fully turn on.  In January, it started turning on and off on its own.  Then it stopped working altogether.

CJ and I opted for an LED replacement light that had the same footprint as the fluorescent – that way, any unseemly holes or scars that emerged when I took the old light down would at least be covered up when I installed the new one.

Now, does everyone remember what the first step is when working on something electrical?  Make sure you don’t have power running through the lines.

Downstairs I went, to the breaker box.  I had visions of multiple trips up and down, trying to find exactly the right breaker, but incredibly, there was one marked "Kitchen Lt".  I turned it off, and went back up.  I unwrapped the electrical leads to the light – taking care to not touch any of the exposed copper – and tested them.  The indicator light on my tester stayed dark, so that meant no power.  I can proceed, right?

Not so fast.  While I’m relatively comfortable working on the electrical fixtures in my house, I’m also fairly paranoid about it.  After all, I only do something like this maybe twice a year.  How could I tell if the power was REALLY out?

I’d turn the breaker back on, see that the light on my tester actually lit up, turn the breaker off again, and see that it went out.  In other words, test-driven home repair.  I needed to write a failing test – touch the tester to the wires and see the indicator light come up.  Then I would write code to pass that test – turn off the breaker, and the indicator light should go dark.

Another trip the breaker box.  Another trip back upstairs.  Another test of the wires.

The light on my tester was STILL dark.


Do I have a bad tester?  I plugged it into the nearest electrical outlet, and the indicator light came right on.

Um.  Now what? 

With the breaker on, there should be power running through these wires.  Is it possible that I have a break somewhere in the junction box that this light hangs from?  Is there a break in the wires leading from that junction box back to the breaker?  Suddenly, I’m feeling way less confident in my ability to switch out this light.  CJ and I discussed a couple of possibilities, but we decided that if I wasn’t confident enough to finish this job, we’d just have to call in a professional electrician.  I covered up the bare ends (again, taking great care not to touch the copper), and feeling a little dejected and more than a little puzzled.


After a good night’s sleep, CJ figured out the missing piece.  She caught me this morning asked, "You turned off the breaker, but did you…" – and that was all that I needed.  This is a light, Mark.  A kitchen light… with a switch of its own.

Forehead?  Meet wall.

I toggled the power at the breaker, but the light switch on the wall had been off the entire time.  OF COURSE there wouldn’t be any power running through it.

I pulled my tools back up to the kitchen; uncovered the ends; turned on the light switch.  The indicator light on my tester lit right up.  Sigh.  10 minutes later, I had the new light mounted and working*.

While this was another in a long line of "duh" moments for me in the home-improvement space, I was very glad I insisted on getting a failing test before proceeding.  In my day job, not being that disciplined means bugs or bad assumptions can make it through.  When I’m working with 110V, though…

Yeah, you get the picture.


* For the record: 144 LEDs are bright!  CJ says without the cover, the light makes it look like Vegas in our kitchen.  🙂

March 13, 2016 Posted by | Agile | Comments Off on Test-Driven Home Repair

Building Tools

For the better part of a year, I’ve been trying to build a system to capture and analyze data points – on me.  This is part of a long-shot plan to find out what might be contributing to my headaches.  I’m pleased to say that since July of 2015, I’ve been successfully capturing over a dozen data points on myself, multiple times a day.

I started out with the easiest thing that could work: an alarm clock telling me to take a survey every 15 minutes, and a Windows desktop app called iSelfSurvey that saved its data to a text file.


Then, in mid-January, I launched an Android version of iSelfSurvey that allows me to capture data outside of the 7:30-5 that I’m at my computer at work.




Late last year, I also built a companion application called iSelfAnalysis that allows me to upload those data files, and then run a number of functions on the data, looking for patterns.


For example: is there any correlation of the severity of my headaches to the number of hours of sleep that I got the night before?  Is there any correlation to the amount of liquid I’ve been drinking?  How about if my blood sugar takes a dive 4 hours ago – does that affect my headaches now?  I’ve only begun to scratch the surface of the kinds of questions I can ask – and now answer.  I now have the tools in place to run experiments on myself – experiments where I adjust one data point and observe how my headaches react.

Is this system over the top?  Have I spent too much time sharpening my axe?  No.  Asking anyone to answer a dozen questions every 15 minutes is moderately intrusive at best.  Trying to analyze the data by hand would get old after about a day.  This system takes as much of the pain out of this process as I can manage, and makes it far more likely that I’ll continue day after day after day.

I have 127 days’ worth of data collected so far – thousands of data points.  I don’t expect to find any smoking guns, but if I can find ways to minimize my headaches, I’ll consider that a win.

January 30, 2016 Posted by | Science, Tools and Toys | Comments Off on Building Tools

Verifying the new world order

On the iSelf project, I needed to validate that lists of things were being returned in the correct order.  I knew I would have to do this over and over, and the thought of writing tests like this made me cringe:

Assert.Equals(1, ListOfSomeClass[0].SomeProperty, "SomeProperty 0 didn't match");
Assert.Equals(4, ListOfSomeClass[1].SomeProperty, "SomeProperty 1 didn't match");
Assert.Equals(9, ListOfSomeClass[2].SomeProperty, "SomeProperty 2 didn't match"); 

I decided to try my luck creating a generic function that I could pass the test values, the expected values, and a function to evaluate the two lists.  After a few iterations, here is what I came up with:

public void VerifyPropertyValuesInThisOrder<TTestValues, TExpectedValues>(List<TTestValues> ValuesToTest, 
                                      Func<TTestValues, TExpectedValues, Boolean> EvaluationFunction, 
                                      params TExpectedValues[] ExpectedValues)
    if (ValuesToTest == null && ExpectedValues == null) { return; }
    if (ValuesToTest == null) { Assert.Fail("ValuesToTest was null while ExpectedValues was not."); }

    Assert.AreEqual(ExpectedValues.Count(), ValuesToTest.Count, "ValuesToTest and ExpectedValues didn't have the same number");

    for (int i = 0; i < ValuesToTest.Count; i++)
        Assert.IsTrue(EvaluationFunction(ValuesToTest[i], ExpectedValues[i]), 
                        String.Format("Answer[{0}] was wrong.  Expected: '{1}'", 

This allows me to check entire lists of things – either lists of simple values, or properties of more complex objects – with a single call.

this.VerifyPropertyValuesInThisOrder<int, int>(TestValues,
                                               (a, b) => (a == b),
                                               1, 3, 5, 2);


this.VerifyPropertyValuesInThisOrder<TestClass, Boolean>(TestValues,
                                                         (a, b) => (a.BooleanMember == b),
                                                         true, false, false, true);

For most of my tests, the order that the values appeared in the list were important.  However, if you need to verify that all of the expected values appear in the list, without regard to their order, simply sort both lists before you pass them in.

this.VerifyPropertyValuesInThisOrder<int, int>(TestValues.OrderBy(i=>i).ToList(),
                                               (a, b) => (a == b),
                                               1, 2, 3, 5);   

Here is a complete working example program showing VerifyPropertyValuesInThisOrder.  This sample requires NUnit 3.0.1, easily available through NuGet.

January 18, 2016 Posted by | Visual Studio/.NET | Comments Off on Verifying the new world order

Getting Traction

In July, I showed the nearly feature-complete version of a project I’ve been tentatively called "iSelf".  In August I managed to get all of the components you saw on the breadboard stuffed into a wearable case:


In the last full week of August, I took iSelf out for the first official test drive – wearing it on my belt while I was at work, and then downloaded the data in the evenings.  About halfway through that week, though, I found that the download application I wrote wasn’t always able to finish correctly.  In fact, there were times it wouldn’t even start downloading correctly.  On those nights, I opened the case, popped the micro SD card out, and manually pulled the data off.

What I thought was a minor glitch turned into three solid weeks of troubleshooting, debugging, and refinement of both iSelf’s onboard program as well as the app I wrote to download the data.  I finally got everything working this past Wednesday, so on Thursday the 17th I again wore it to work.

Everything was proceeding normally until it stopped recording about mid-day.  I tried rebooting it several times, again thinking it was just a glitch.  Nothing worked.

Between Thursday night and last night, I wrote a suite of diagnostic programs, testing each component until I found the problem.  As it turns out, I had two.  The micro SD card logger, OpenLog, stopped responding correctly to the initialization routine I wrote.  I found through trial and error that it would still accept data in "write" mode, and would accept commands in "command" mode, so I modified the initialization routine to work around this issue.

Then I tested the BMP085 temperature/pressure sensor.  I found it wasn’t sending any data any more, even after a reset.

With all of the components soldered onto the motherboard now, it was going to be extremely difficult to replace those components.  Starting over from scratch would mean buying replacements for the Arduino Micro, the PowerBoost, the OpenLog, and a temperature/pressure sensor.  It would mean at least another 10 hours of work to cut out new pieces of protoboard, and solder everything together again.

I left things last night depressed and a little angry.  I had just gotten it working, after weeks of solving problem after problem, and had collected four hours of real data – only to have it fail.  This project was 9 months of work – after my day job is done, after the house chores are done, after my kids are in bed.  

9 months – lost.


Well – perhaps not completely lost. 

I’m reminded of the story of a Foursquare-like check-in startup called "Burbn".  In 2010, the founders got together to talk about its future.  Burbn was having problems getting traction – problems of the sort that would shutter them permanently if they didn’t do something.  They took a hard look at what they had built so far, and found that one particular piece of their service was actually being well-received.  They decided to focus on that one piece and let the rest die.  Years later, their photo-sharing application – called Instagram – was sold to Mark Zuckerberg for $1 billion.

One of the components I built for iSelf was a twice-an-hour survey that I give myself.  This survey collects a number of data points about my mental or physiological state, or other topics that would be difficult to collect any other way:


This application has consistently worked well, and as a result I now have nearly 2 full months of data from it.  I’m still collecting 11 different data points from it every day.  Hmm…

After 8 hours of relatively good sleep last night, I remembered what my focus in this project really was: finding things that contribute to my headaches.  The focus was not "to build a wearable".  The analogy between Burbn and iSelf is clear – focus on what I’m getting traction with.  (And if the analogy extends to me selling this down the road for a billion dollars – hey, all the better.)

My next task, then, is to get the raw data I’ve been collecting from the survey into a system where I can start formulating questions.  Stay tuned.

September 20, 2015 Posted by | Embedded/Wearable, Science | Comments Off on Getting Traction

Rover v2: Technical Breakdown

In Episode 31, Lucy and I show off the new Raspberry Pi-powered rover that we built.  In this post, I’ll go into the technical details of how we did it.

Parts List

The GPIO Overlay is a simply piece of thick paper with holes punched so that it can sit over the pins on the RPi, and has labels for all of them.  It was a minor indulgence, but it made hooking up the wires so much faster.

Up to this point, I only had male-to-male hookup wire, which worked great going from an Arduino’s female pins to a breadboard.  The RPi, however, comes with male pins, so I had to buy some different hookup wires.  This particular set worked extremely well, even when placed on consecutive pins on the RPi.

Each of the TN6612FNG motor drivers could control 2 motors, and since the chassis was a four-wheel drive, I purchased two of these boards.  So far, the rover only moves its motors in pairs (the left wheels always move in the same direction as each other; ditto for the right wheels), so I probably could have gotten away with a single motor driver.

Prepping the Motor Drivers

The first thing I did was solder some straight headers onto the two motor drivers.  That allowed me to place the drivers onto the breadboard, and wire them up with the hookup cables.  It also means we can completely tear the rover’s components down, and re-use these drivers with other projects.

On the podcast I mentioned that I soldered the headers in upside down.  That was so I could read the pinouts printed on the underside of the board.  That saved me having to think about which pin was which when I was wiring it up.

Raspberry Pi

We wanted to be able to upload programs to the Rover remotely, without a tether.  While it is possible to wirelessly reprogram an Arduino, I thought it would be simpler and a little less expensive to do so with the Raspberry Pi 2 (RPi) and a wireless USB dongle.  The RPi would appear on our home network as just another device, which means we could remote into it from any of our other machines.  I had also never worked with an RPi, and this project gave me the perfect excuse to learn.

So, the first task was to get the Raspberry Pi configured so that it could boot "headless" – without a keyboard, mouse, or monitor connected.

But before I could do any of that, I found I had to get an operating system for it.  I mistakenly assumed that the RPi would come with Linux pre-installed, and I could just boot it up.  When I got the unpacking instructions, and Step 2 was "Insert your microSD card", I had to stop and re-evaluate that assumption.

I started by temporarily appropriating the microSD card I’ve been using for my wearable, and formatted it using the SD Association’s Formatting Tool.  Next, I downloaded the basic, and appropriately-named, OS package called "noobs", for "New Out-Of-The-Box Software".  This was actually Debian Linux optimized for the Raspberry Pi (hence its proper name "Raspbian").  I extracted the contents from the ZIP file, and copied them to the root of the microSD card.

When that was done, I put the card into the RPi, and booted it up.  The RPi provides onboard HDMI output for video.  Luckily we had a male-to-male HDMI cable, but the only "monitors" we own with an HDMI input are actually our TVs.  I set up a card-table in front of one, and ran extension cords for power, plugged in a mouse and keyboard, and fired up the RPi.  It allowed me to select which operating system to boot into – my choices were Rasbian Linux, or direct to Scratch.  If you’ve never seen or used Scratch, it’s worth it to check it out.  It’s a visual programming language, where all of the statements like "if then" or "while" are actually blocks that you can snap together.  Only compatible blocks will fit, so it’s very easy for kids to learn what makes up a valid statement.  This was at the top of my list for the programming language for the Rover, so seeing a "boot straight to Scratch" was a nice bonus.

For now, though, I focused on just trying to get the RPi running Raspbian on our network.  Having relatively little experience with Linux compared to Windows, this was harder than I had anticipated.  I spent three nights playing settings-roulette, trying to get the RPi to be visible on the network, with a static IP, so I could remote into it.  (For the record, this had nothing to do with the Raspberry Pi – this was purely me being a noob when it comes to Linux.)

My network is WEP-secured, so I had to find a way to pass the network ID and key from the RPi.  I read several posts talking about modifying the /etc/network/interfaces, and ultimately that is what I ended up doing.  Here is my final interfaces file:

    # The loopback network interface
    auto lo
    iface lo inet loopback

    # The wired network interface (using dhcp)
    iface eth0 inet dhcp

    # The wifi network interface (static IP)
    auto wlan0
    allow-hotplug wlan0
    iface wlan0 inet static
        wireless-essid ID_Here
        wireless-key Key_Here

    iface defalt inet dhcp

Obviously, the "ID_Here" and "Key_Here" portions were replaced with my actual ID and Key.  One of the issues I had was how these appeared in the file, specifically with or without being surrounded by double-quotes.  The configuration that worked was without – the ID and Key just appear inline.

Additionally, the DNS Server IP Addresses shown here are fake – I filled those in with my provider’s actual IPs.  I ended up downloading a package directly to the RPi (see below), which meant the RPi needed to be able to get to more than just my home network.

With this setup, I could boot the RPi up on my desk, wait a minute or so, and then remote into it using PuTTY.  The RPi was now officially headless.

FTP Server

The next piece of the puzzle was an easy way to upload our programs to the RPi.  For that we needed an FTP server.  I looked at a couple of FTP servers for Linux, and settled on vsftpd.  I followed this procedure for setting it up (minus the initial step of changing the permission on the /var/www folder, since that’s not where I wanted things to be uploaded to).  It took me about 5 minutes to get installed and configured, and works like a champ.

Programming Language

Now it was time to decide what language would we be programming in.  As I mentioned before, I favored Scratch for its simplicity.  However, I also wanted to be able to define custom blocks to represent the commands MoveForward, MoveBackward, TurnLeft and TurnRight.  I found that Scratch 2.0 allows you to do exactly that.

Unfortunately, Scratch 2.0 requires Adobe Air, which does not run on the RPi.  The latest version of Scratch that does run on the RPi – version 1.4 – doesn’t allow us to define custom blocks.  So, scratch Scratch.

The next easiest language was Python, which also came bundled with Raspbian, so we went with that.  Now the question became how do we control the general purpose input/output (GPIO) pins on the RPi using Python?  For that, we turned to a Python module called RPi.GPIO which does exactly that, and which also came bundled on the OS image.

To control our motors, we simply needed to set the correct GPIO pins either high or low.  Doing that using the RPi.GPIO module is trivial:

    import RPi.GPIO as GPIO


    GPIO.setup(18, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)

    GPIO.output(18, True)
    GPIO.output(23, False)


Let’s break this down:

    import RPi.GPIO as GPIO

This simply imports the RPi.GPIO module, and gives it a local name of "GPIO".


This sets up the board in "BCM", or "Broadcom SOC channel" mode.  The other available option is "GPIO.BOARD", which simply numbers all of the GPIO pins from 1-40.  You can find out more information about these two modes, and what the numbering is, from this post on StackOverflow.

    GPIO.setup(18, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)

Like with an Arduino, you need to configure which pins you will be using, and whether they are going to be inputs ("GPIO.IN") or outputs ("GPIO.OUT").  In this example, I’ve configured pins 18 and 23 to be outputs.

    GPIO.output(18, True)
    GPIO.output(23, False)

Each pin can be set high ("True") or low ("False").  In this example, I’ve set pin 18 high and pin 23 low.


I found that if I didn’t reset the pins after each execution of the program, it would throw a bunch of warnings the next time I ran it, to the effect of "that channel is already in use".  So, I needed to be a good little Boy Scout, and clean up after myself.

Another interesting things I learned about the RPi is that all of the channels are digital.  The RPi doesn’t do analog at all – at least not natively.  I did find a post on the Raspberry Pi forums that described building a "poor man’s analog" circuit from a resistor and a capacitor in parallel, but for our first attempt I figured "on" and "off" for the motors would be sufficient.

Getting the wheels moving

Now it was time to put everything together, and actually get the rover moving.  Using this hookup guide, I wired up one set of wheels with the first motor driver, the battery pack that came with the rover chassis (which held 4 AA batteries) and the RPi.

Each motor required 5 pins on the motor driver – 2 that would lead to the motors themselves, and 3 that would be connected to the RPi: IN1, IN2, and PWM.  Form the RPi’s perspective, IN1 and IN2 were always set to be opposite to each other – one high and one low.  Setting IN1 high would drive the motor in one direction, and setting IN2 high would drive it in the other.  The PWM channel was basically the speed at which the motor would turn.  If I were using an analog signal, I could send a number from 0 to 255, where 0 is "stop" and 255 is "ramming speed".  Since I could only generate a digital signal, I just set this channel high (True, or the equivalent to 255) when I wanted the motor to turn, and low (False, or the equivalent to 0) when I wanted it to stop.

Once it was all wired up, it was just a matter of setting the correct pins high or low.  I started by creating my basic control functions:


Where "direction" is one of two constants (also defined in the script) – FORWARD or BACKWARD.  The wheels would keep turning until I explicitly told them to stop, which meant something like "MoveForward" was really a combination of "move all the wheels forward, wait a moment, and then stop all the wheels":

    def MoveForward(distance):

        time.sleep(.1 * distance)



We wanted to be able to control how far the rover moved with each step, so this function takes a parameter called "distance", which gets converted into the number of seconds to run the motors.  I wanted to be able to have the numbers represent the number of centimeters to move the rover.  However, these aren’t stepper motors, so we couldn’t get very precise with them.  The basic idea holds, though: pass a larger number to MoveForward, and the rover will move further (or at least, the wheels will turn for a longer time).

The "time" module is actually another Python module, and is included in the script by simply adding "import time" at the top.  The "sleep" function takes a parameter in seconds, or fractions of a second.  The RPi doesn’t go to sleep like a laptop goes into hibernation, though.  Whatever GPIO pins I set high and low would retain their settings while the RPi was "sleeping", which meant the motors would keep running.  Basically the MoveFoward function says "Run the motors forward while I snooze, and when I wake up I’ll tell you to stop."

Once I had this working, I wired up the second motor driver and the other two motors, and wrote the other three functions:

  • MoveBackward looks just like MoveForward, except it moves the wheels backward (the parameter passed to MoveLeftWheels and MoveRightWheels is BACKWARD instead of FORWARD).
  • TurnLeft() involves running one set of wheels (either left or right) in one direction, and the other set in the other direction.  These functions don’t currently take a parameter (for degrees of arc, for example), but they could be easily modified to do so.  With our current setup, though, turning will be just as imprecise as movement is.
  • TurnRight() does the same thing as TurnLeft(), but reverses the direction of all of the wheels.

I also created functions that would set the board up (SetUpBoard), and shut it down cleanly (CleanUp).  All of the commands that you want to send to the rover are made between these two calls.

The complete program, configured for use with the GPIO pins we used for our rover, can be found here.

Buttoning everything up

So far we have the hardware in place, the operating system configured, we can write programs in Python to run our motor, and we can upload them via FTP.  Now it was time to put something in place that would kick off the programs we uploaded.

My original intention was to be able to upload files to the RPi, and then have the RPi automatically run it.  That posed a couple of challenges:

  • Detect when a new program was present and run it in a timely manner.
  • Don’t try to run two programs, or two copies of the same program, at the same time.

My first thought was to set up a cron job (an automated scheduler for Linux) that would run a small shell script.  The shell script would look for new Python programs in a pre-defined folder, start them if found, and remove the program when it was done.  However, cron jobs can only be scheduled for at most once every minute.  That seemed like a long time to wait for the program to start once we uploaded it, and it would complicate debugging.  If the rover didn’t move, was it because we didn’t wait long enough, or was there actually a bug in our program? 

This approach also didn’t address the second challenge – if I managed to get the RPi looking for and running programs every 3 seconds (for example), but the current running program requires 15 seconds to complete, how do I prevent it from spinning up a second copy of the same program 3 seconds from now?

In the end, because I wanted to get the thing working quickly, I decided to just kick off the programs manually, via PuTTY.  We write our program on our laptop, upload it to the rover via FTP, then execute the program from the command line like so:

sudo python

It would not surprise me at all to learn that someone has built a better cron for Linux, so we can revisit this piece later.

What’s next?

We’d like to add a digital camera and transmit back pictures (or rough video) of what the rover was seeing.  That would add to the illusion that this little rover is on another planet, and we’re Mission Control.  The RPi actually has a dedicated camera slot onboard, and we’ve considered getting this camera for it sometime in the future.

The impreciseness of the motors in moving and turning can get a little frustrating.  Short of getting a different chassis with more precise motors, I’ve wondered if we could add a gyroscope or an IMU to the RPi to improve at least the turning.  We would send a TurnLeft or TurnRight signal to the RPi, and instead of simply running the motors for a certain number of seconds, the RPi would read the input from the gyroscope to determine when it had completed a 90 degree turn.

It occurred to me after the fact that having the entire operating system on the SD card meant that I could configure other operating systems, and swap them in when I needed.  Windows 10 IoT Core, for example, will run on the Raspberry Pi 2, so that may be something for us to explore later.


All in all, this was a fun project, and I’m still amazed at how quickly it came together.  I think we’ve put together a great platform for experimentation.

August 7, 2015 Posted by | Engineering, Raspberry Pi | Comments Off on Rover v2: Technical Breakdown