Skip to main content

Shaken not steered

Often - it transpires - humans and robots just don't get along.  Something about one being infinitely more clever than the other.  And to make matters worse, most machines equipped with even an ounce of "advanced" intelligence supposedly like nothing more than to totally annihilate the world, and generally cause misery for humans (just like their human counterparts, on second thought).  This is all according to the seminal, and totally academic study on artificial intelligence - The Terminator.  It's been peer reviewed on Rotten Tomatoes... so it must all be irrefutably true.

And for any fledging robot, when that terrifying moment finally arrives, when a muscle-man from Austria comes at you with all kinds of blunt and sharp instruments (often found suspiciously, not to say rather conveniently, nearby), they must recognise that they are being... well... properly whacked.  With a gardener’s fork.  Or an iron pipe.  Or maybe even with an enormous sword of the barbarian variety.  And before an expensive robot limb is left ingloriously dangling, it's probably best to register the blows, so that some over-the-top response can be fashioned up.  Rapidly.  Like a deadly laser beam that defies the laws of physics (sensible).  Or - more drastically - a tactical nuke concealed up the robot's nostrils (less sensible, and probably terminal). Think: Skynet.

But none of this is possible without a way to identify physical shocks; sudden movements of the body.  And because there's always a danger of Terminator sequel #<insert random 0-65,536 integer here> being released to the unsuspecting public, let's be quick with the solution.  Let's get our robot working with a cheap and cheerful tilt / vibration sensor.

You don't want to be the tool without the tooling:

  • A Raspberry Pi 3, running Raspbian OS
  • A SW-520D tilt / vibration sensor
  • Erm, that's it.  Can't think of anything else. Nukes and lasers, not required.   For now.

Chequered history:

Building Rosie 2.0 - naturally - assumes that there is a Rosie 1.0.  For that reason, casting your eyes over the organised chaos that was Rosie and Rosie Patrol is highly recommended.

And then, there's also been the first few episodes of Rosie 2.0:
  2. Crawly creepy
  3. 2 crawly 2 creepy
  4. Balancing the books

Bit by byte:

  • Connect the SW-520D tilt / vibration sensor to the Raspberry Pi using designated GPIO pins.  Hopefully the sensor was bought as a module.  If not, you will need to solder a pull-up resistor.
  • Play around (official scientific term) with the sensor using Python.  Can we get it to recognise any movement?
  • At this point, you're likely to have experienced a bad bout of bouncing, aka Switch Bouncing.  You can attempt to tackle it in software or hardware.
  • Ah yes.  A real-life crash test.  Steer a seemingly innocuous object into something (accompanying sound effects compulsory). And see if you can detect the moment of the impact. We used a toy pram, obviously. 

You ain't seen nothing yet:

Quite frankly, our brains are still hurting from the last episode, in which we attempted to - uncharacteristically for us - make use of a sophisticated Inertial Measurement Unit (IMU) to actually measure the tilt of a device.  We had to use accelerometers, and (semi-)understand gravity and trigonometry, to build something that allowed us to measure tilt angles.  Old friend Pythagoras made a return. So did his mischievous cousin Hypotenuse.  What a rave!  What a night.

Now that's all very useful (and it really is when it comes to robot navigation) but what if we just want to detect sudden vibrations experienced by our robot hero?  A collision with a stray wall perhaps.  Or from being picked up by an oversized man in film star shades, and shaken vigorously like cheap plastic maracas bought in Poundland (yes, they're sold next to toilet plungers which are less acceptable to shake on the dance floor).  We'd definitely like to know about it when such an event unfolds (the physical shocks, not the bit about dancing with toilet plungers).  And using a sophisticated IMU for this simple task seems a little too... well... unnecessary.

Isn't there a simpler way?

Thankfully for us, there is.  It's called a tilt (or sometimes, vibration) sensor.  It's crude.  It really does sound like a pair of maracas when you shake the tube-shaped device.  It might not work terribly well in all cases, but it might just do the job here.

Put on a sombrero.  Some banda music.  It's time to get groovy with some tilt sensors.


Did we say it's crude?  Oh yes it is.  And here's some proof.

SW-520D is a rudimentary tilt / vibration sensor - the kind that you could even explain to your great grandma using two biscuits and a biscuit jar (use of denture during demo is strictly optional).  It's because, the moment you Google its workings, you soon realise that despite its sophisticated-sounding alphanumerical code name, all it does is play ballgames.  Specifically, the unit houses two conductive balls that opens and closes the circuit depending on the positions the two balls end up in (basically a ballsy switch).  And clearly the balls will move around when the sensor is shaken with enough force, or tilted.

Yes, we did think this as well.  The term "tilt sensor" is slightly misleading - as it doesn't help you work out precise angles like the IMU, or even orientation.  Moving on.

And because it's basically no more sophisticated than a switch - as we'd expect - it simply supplies a HIGH or LOW logic signal as its output depending on the results of its internal ball action.  Additionally, detecting a HIGH to LOW, or LOW to HIGH change in itself might not be so useful.  It might just be that your robot has steered itself onto an incline, or onto a bank.  But if the state is repeatedly changing in a short space of time - something is probably not quite right.  There's probably a whiff of robot-killer aftershave in the air.  You will need be on red alert.

Other than the 3.3V and Ground (0V) connections to power the SW-520D, you'll only require the one GPIO pin for the sensor's logic signal output.

SW-520D PinPi GPIO PinDescription
GND (Ground)Any 0V Ground (e.g. 6, 9, 14, 20, 25, 30, 34, 39) 0V (Ground)
DO16 (BCM 23)Signal output from SW-520D
VCCAny 3.3V (e.g. 1 or 17)Used to power the sensor using 3.3V

It's worth noting that we used a sensor module... which has the pull-up resistor pre-soldered in to ensure we have the correct voltage for HIGH and LOW signals.  This means that the unit is ready to be used directly with the Pi.  If you unfortunately have just the sensor itself, you will need to get yourself a resistor.  Furthermore, some people appear to use a capacitor / resistor combination as well in their circuitry to act as a low pass filter of some sort to address the symptoms of switch bounce.  More on this later.

All cabled properly?  Some electronics aficionados like to use LEDs or buzzers to demonstrate their new sensors.  Not us.  We like to go straight into Python and see what we can do with it.  Let's use IPython - our favourite way of testing Python code interactively.


There really isn't much to interacting with simple HIGH and LOW signals that appear at a GPIO pin (especially since we've been playing around with a lot more interesting protocols like 1-Wire, SPI, and I2C lately).  But here's a reminder of what to do.

import RPi.GPIO as GPIO
GPIO.setup(23, GPIO.IN)

We've use this a million times before.  We first import the GPIO library, set mode to BCM (so that we can address the pin using BCM numbering 23), and configure it as an input pin.  Simply put: the pin should now be receiving HIGH or LOW signals depending on what the balls are doing in the sensor.

Are we interested in what the signal is?  Not particularly for this exercise.  You might be, if you are trying to detect known changes to the sensor's tilt.  For example, from moving from upright to sideways, there should - in theory - always be a change in the signal from HIGH to LOW... and the datasheet informs us that this could happen at 10 or 45 degrees depending on sensor orientation.  No, we just want to detect sudden shakes, not a gentle steer.

You could write your own routine to poll a change in the state of the signal.  But why bother when there is a wait_for_edge() method in the GPIO library that alerts you when the signal changes.  Feeding it a parameter of GPIO.BOTH means that we'll be monitoring for HIGH to LOW or LOW to HIGH changes.

while True:
    if GPIO.wait_for_edge(23, GPIO.BOTH):
        print("a shake, not a steer!")

Run this, and you'll find yourself in a horribly infinite loop, but one in which an alert is raised when the sensor is roughed up a bit.

Incidentally, wait_for_edge() is a blocking method... meaning you'll want to run this as a separate thread to ensure your code can be doing something else in the meantime.  Or you could use one of the alternative GPIO library methods, like event_detected().

If you ran the code, you're probably quite surprised by the sensitivity of the sensor.  A couple of innocuous shakes appear to lead to lots of spurious signals being generated - which is a by-product of the mechanical ball game taking place inside the sensor.  And the infamous effects of Switch / Contact Bounce. After all, no switch transitions perfectly between OPEN / CLOSE states due to the mechanical components involved.  Unfortunately, systems expecting certainty aren't great at dealing with these imperfections.

There could be both a hardware and software solution.  More electronic circuitry (such as a low-pass filter created using an additional resistor and capacitor) could be used to mask the effects of these spurious signals... or you could do it programmatically in Python.  Let's do the latter, and use the set of non-blocking event_detected() methods instead, and provide it with the bouncetime parameter of 250ms.  This should now ignore further signals for 250ms.  It's probably not the most sophisticated way of de-bouncing the switch, but it'll do for now.

GPIO.add_event_detect(23, GPIO.BOTH, bouncetime=250)
while True:
    while not GPIO.event_detected(23):
    print("a shake, not a steer!")
GPIO.remove_event_detect(23) # Manually remove event detection when finished

This will desensitise the output somewhat; as there should now be a minimum of 250ms between the signal changes register.  It does also mean any legitimate "shakes" of an extremely vigorous nature will now not be registered so representatively.   We have effectively created a low-pass filter - similar to what a RC Filter with a resistor / capacitor combo would have done.

Moment of truth.

Mount the unspectacular rig onto anything that moves, and you can now steer the creation into an immovable, impassable obstruction of death and destruction. Or failing that, use a toy pram and a sofa.

Here's our Pi and sensor positioned inside this particular research vehicle.  Watch as it dramatically crashes into the furniture like a trailer from Fast and the Furious 65.

If you are planning to recreate this monumental footage, you might need to adjust the orientation of the sensor... as the way it is facing appears to make it more responsive to forces encountered from specific directions.

Sorry to disappoint.  We did say this wasn't going to be epic as the one on the IMU.

Nonetheless hopefully you've become acquainted with yet another sensor that does something different.  And this one might just save your robot from total destruction.

Go and see the doc:

The SW-520D datasheet can be found here:


Popular posts from this blog

Tea minus 30

We're fast approaching Christmas time.  And if robots were to make one simple observation about the human species during the Christmas festivities, it's that they watch a lot of TV.  A LOT.  Often, accompanied by an inappropriate amount of greenhouse gas-producing food.  Stuff you don't normally eat during the remainder of the year - for good reason.

And most so-called shows on TV are boring to robots like Rosie.  After all, why watch a minor subspecies of the human race - celebrities - stumble awkwardly around the dance floor, dressed like a faulty, sparking circuit board?  Such branch of entertainment doesn't require robots to engage any of their proud circuitry.  Their processors remain idle.  Memory under-utilised.

But if robots are to be part of people's homes (and blend in), they need to look at least a little interested in some of this irrational nonsense.  Nobody likes a party pooper.  A killjoy.  And this is where a certain subgenre of TV entertainment co…

Beam me up, Rosie!

How do you get from A to B?

You can't, as As and Bs are just letters in the alphabet. But if A is your house, and B is a meerkat village at your favourite safari park, you'd probably use a device equipped with GPS.  Not to be confused with UPS, who will deliver you your chosen meerkat through the post. And why on Earth would Rosie Patrol need one? Precisely, it's because she is on Earth that she needs one. Because our planet is rather big. Big enough to get lost in. And we don't want to lose our friendly plastic boxes on wheels. And maybe, eventually when she's clever enough, she'll go and defeat baddies on her own. And return home afterwards for a well deserved Earl Grey tea.

Besides, why wouldn't we want to add another three letter acronym to Rosie Patrol's repertoire?
All superheroes need:One Raspberry Pi 3, running Raspbian OSComputer from which you are connecting to the Raspberry Pi Probably the most important bit: a GPS receiver thingmy. …

Code: read

Humans are said to have 5 senses in total.  Common, clearly isn't one of them.

But - jokes aside - computers all around us are growing ever more intelligent (so we hear).  They can play chess.  Drive cars.  Some might even do these things at the same time.  Without crashing (quite literally).

Likewise, we've been making steady progress equipping Rosie Patrol with some useful skills.  Skills needed to bring much needed law and order to the world.  She can move.  She can see.  She can sense.  And in our last episode, she began to read.  With a little helping hand from some (considerably) bigger computers at the mothership that is Google.

But can she really read?  You know.  Read out aloud?

True to our style, there is only one way to find out.  It's time to invoke Code: Red Read.  And take the power of reading to the next level (or page).
All superheroes need:One Raspberry Pi 3, running Raspbian OS.  Connected to the Internet. Computer from which you are connecting to the R…