Welcome to the robot version of the Justice League. Where Rosie will team up against a band of baddies, and in general, bring much needed calm and order to the world. Justice for precisely what, you ask? Actually, we don't quite know. But as we now have a logo, let's pretend that this is all for a righteous cause.
So far, our greatest creation has been a... (semi)-autonomous moving plastic box. Good for carrying a basket of fruits. However, not so good at defeating fruit cakes, intent on taking over the world.
The master plan? As with all good plans to defend all that's precious to humanity (Guardians of the Samsung Galaxy) it begins with the requisition of more random kit that we can attach to our Pi. Then, some equally random Python code to make use of those gizmos. Yes, we'll battle unpleasant invaders one if statement at a time, and scare them away with more bits of electronics than you'd find in your local car boot sale.
Ladies and gentlemen. Let us introduce to you the greatest superhero of them all. ™Rosie™ ™Patrol™.© ™.© ™.
Electricity is dangerous. It can zap you. It can cause fires. Never tamper with any devices that are connected to, or will be connected to the mains (AC). Stick to stuff with normal household batteries. They are much more appropriate for robot use anyway.
Always ask for help from someone more qualified than you if you are unsure about any of this. And - sorry kids - always have adult supervision.
Always ask for help from someone more qualified than you if you are unsure about any of this. And - sorry kids - always have adult supervision.
All superheroes need:
- Raspberry Pi 3 (kitted out with wheels and sensors and stuff), and Raspbian running on SDHC card
- Computer from which you are connecting to the Raspberry Pi remotely
- An electrical relay. We are using a 4-channel relay by Kuman. Same principles apply to all other relays, although always check up to what current (A) and voltage (V) the relay supports in relation to the device that you are trying to control.
- A random assortment of torches to hack
- Gear for some soldering, and drill, if you are intend on doing some serious gadgetry surgery
Already completed these missions?
You'll need to have completed the Rosie series.Your mission, should you accept it, is to:
- Hack a torch, attach it to a relay, and connect it to Pi's GPIO pins
- Graduate to Python 3 (from 2) and start using IPython for the interactive Python shell
- Modify the Python code to create our own class for a light
- Create a Flask function to allow light to be switched using HTTP requests
- Create a button in Flask's HTML template for the light button
- Make Rosie cruise around at night, looking all sparkly. Defeat evil.
The brief:
Let's get straight to the point. Have you ever wanted to hack an electronic head torch? Have you? Has this always been on your bucket list? Admit it, it has! Well, even if you don't under interrogation by an evil mastermind, you've got no choice. You see, all bad things happen at night, when everyone is asleep. And in most parts of the world, it gets dark at night (something to do with the sun, rotation of the earth... blah, blah, blah). So, in order to do some patrolling past bed time, Rosie Patrol requires a light. A bright light.And Rosie would like one of those bright lights that humans use, not those titchy, embarrassing LEDs designed for remote controls and mobile phones. See, she's seen humanoids in ugly fluorescent jackets and Lycra shorts run and cycle with them at night. They look so comfortable to wear (the torch, not the Lycra). Perfect for a midnight patrol to track down delinquents in the middle of a misdemeanour.
But you can already see the problem coming. They aren't designed for a Raspberry Pi, or robots for that matter. People are expected to turn things on and off, using a very much human-friendly (but not so machine-friendly) mechanical switch. But we don't want to let Rosie down. And she needs the tools to do her job properly (you know, saving the world and stuff).
This is why we suddenly find ourselves on an urgent (but not so top secret) mission to hack apart an electronic head torch or two. Make them robot-friendly. And for this, we welcome into our team of superheroes, the Relay (yes, not a very good superhero name we realise). It's an electrical device that can be used to connect the Pi's GPIO pins to electronic stuff not normally expected to be controlled by a little red marauder of justice.
All this for a robot... with a torch.
The devil is in the detail:
We start by exploring a timeless question that philosophers have grappled with since the dawn of mankind:Thee shall not has't light, if thy head torch hast nay electricity
But thee shall has't light, if thy head torch hast electricity..?
Thankfully, we can answer this age-old mystery once and for all. Yes. Your head torch (and electrical devices generally!) works only when there is electrical current flowing through it from its batteries. It will not, when there is none. So one crude way of controlling the lightbulb in the head torch would be to start and stop the flow of electrical current to it, much like if you were plugging and unplugging batteries, manually. This is basically what a mechanical switch does. So far so good.
But we want to control this switching using simple signals from the Pi's GPIO pins. So we need a device that effectively allows us to control a small mechanical switch, using only (small) electrical signals. Meet the Relay. Relays are electrically operated switches, which allow a small electrical signal to control a larger flow of electrical current. So in short, it will allow signals from our Pi's GPIO pins to turn on and off electricity travelling through devices. Perfect for a head torch.
But this is important. Before we totally obliterate our torch to inject into it our relay, we need to understand how our particular torch works. Does it have a simple on / off switch that closes / opens the circuit? Or does it have a switch that only momentarily closes a part of the circuit, which in turn, sends a signal to a microchip. A chip that probably coordinates the change in the status of the light between on, off and other states (like beam strength, flashing, etc). In order to hack it, we need to understand what is expected. And reproduce this behaviour using our Pi and relay. After all, the less of the working parts of the torch we touch the better. If it's not broken, don't fix it. We are only interested in the switch.
You're probably bored by now. Let's whip out some examples and do this for real.
Arise our three lights in shining armour!
Name: Eric
What does it do: A classic torch. If it looks like a torch, shines a light like a torch, it's probably a torch. You turn it on, and off, using a sliding mechanical switch. Basically... like a torch.
Hack-a-bility: High. There are many potential places where we can inject a relay, because all we need to do is stop / start the flow of electrical current to the light bulb.
What does it do: A classic torch. If it looks like a torch, shines a light like a torch, it's probably a torch. You turn it on, and off, using a sliding mechanical switch. Basically... like a torch.
Hack-a-bility: High. There are many potential places where we can inject a relay, because all we need to do is stop / start the flow of electrical current to the light bulb.
Name: Electron 2000
What does it do: It's a sophisticated head torch that does different things each time you push the button. It starts with a high beam, then moves to a low beam, before turning on red LEDs and flashing them menacingly. We're not sure for what reason. But it makes a perfect accessory for robots.
Hack-a-bility: Medium. There appears to be a push to close (normally open) momentary switch which we could replace with our relay. There are also conveniently located screws that allow us access to the batteries and circuit board. Very vital, when you don't want to totally demolish the device.
What does it do: It's a sophisticated head torch that does different things each time you push the button. It starts with a high beam, then moves to a low beam, before turning on red LEDs and flashing them menacingly. We're not sure for what reason. But it makes a perfect accessory for robots.
Hack-a-bility: Medium. There appears to be a push to close (normally open) momentary switch which we could replace with our relay. There are also conveniently located screws that allow us access to the batteries and circuit board. Very vital, when you don't want to totally demolish the device.
Name: Elsa (or possibly it's Anna?)
What does it do: It's anannoying amazing wand that plays Let it Go when a button is pressed.
Hack-a-bility: Low. This wondrous invention also appears to have a push to close (normally open) momentary switch which we could replace with our relay. But the whole wand appears to be glued together, with no way to neatly inject our relay without totally dismantling the plastic. Also, we do not want to be drilling holes through princesses' faces. The manufactures at Arendelle clearly wanted to make this hack-proof. Mission abandoned.
What does it do: It's an
Hack-a-bility: Low. This wondrous invention also appears to have a push to close (normally open) momentary switch which we could replace with our relay. But the whole wand appears to be glued together, with no way to neatly inject our relay without totally dismantling the plastic. Also, we do not want to be drilling holes through princesses' faces. The manufactures at Arendelle clearly wanted to make this hack-proof. Mission abandoned.
We've spoken about it. But what does it look like? Relays look like... another piece of electronic circuitry. Why? What did you think it would look like?
...And this is how you cable it. It needs a small amount of power itself to operate the switches. For this, we can use the 5V and 0V (Ground) supplies on the Pi. Remember, this is not used to power any devices attached to it. It is simply used to operate the switches. All devices therefore need to continue to have their own power supplies (batteries).
There is also a GPIO pin assigned per channel (ours has 4). This is where we send signals to from Pi's GPIO pins, to open / close that particular switch (channel). We'll use GPIO pin 33 (BCM 13) for the test.
Relay Pin | Pi GPIO Pin | Description |
---|---|---|
Ground | Any 0V Ground (e.g. 6, 9, 14, 20, 25, 30, 34, 39) | 0V (Ground) |
Vcc | Any 5V (e.g. 2, 4) | Used to power the relay |
Vin | 33 (BCM 13) | Used to operate the relay |
Common | N/A (Torch) | For closing and opening the circuit like a switch. Connect to one end of where the circuit needs to be closed. |
Normally Open | N/A (Torch) | For closing and opening the circuit like a switch. Connect to the other end of where the circuit needs to be closed. |
And of course, there are some terminals for where you connect the actual devices. Depending on which terminals you use, you can have a normally open or normally closed setup. This is where actual current of the device is passing (or not). And this is why it's important to check that your relay's switches can handle the voltage and current that the device actually handles. You should have no problem if your devices are powered by a couple of AA or AAA batteries, unless of course, you have a Tesla motor you'd like to hook up to your relay.
The idea is to mimic the behaviour of the switch the torch is currently equipped with, using the relay. For Eric, we simply want to instruct the relay to open / close the circuit. This allows current to not flow / flow to the light-bulb, like with the mechanical sliding switch which makes two metal plates break or make contact.
There are many potential places that we can do this, with an 'old-school' torch like this. We interrupted the torch's existing circuit where the positive terminal of the battery normally makes contact with the bottom of the lightbulb, and replaced it with two cables. When the ends of the two cables meet, the circuit is complete and the light comes on. Great, because this is so easily controllable using the relay.
But our brainy friend Electron 2000 - being the sophisticated piece of tech that it is (light years ahead of Eric) - appears to have a microchip which is expecting momentary pulses of electricity to signal changes in its lights. Here, we need to reproduce the behaviour of a switch closing and opening quickly using the relay (more on this later, with Python).
Looking at the circuit board inside, the existing push to close (normally open) momentary switch is soldered to the board. This is perfect, as we can simply un-solder it, and replace it with... you should know this by now... two ominous-looking cables. Testing reveals that the two ends of these cables meeting momentarily kicks the microchip (and the torch) into action.
Once the cables are connected to the terminals on the relay, we are ready to unleash some Python code to start our very own robot disco.
Before we do, though, let's do some housekeeping we have been forgetting to do. Let's graduate to Python version 3. We've been using Python version 2 until now, as the RasPiRobot v3 libraries required it. But now that we have our very own motor controller code, we can move onto using the latest and greatest version of Python.
Python 3 should already be installed on Raspbian OS. And it can be called using python3, instead of python. Let's check that it exists, and its version. While we're at it, let's check that Pip 3 (for Python 3) is also installed, and up to date. We need Pip to install Python packages, remember?
python3 --version pip3 --version sudo pip3 install --upgrade pip...checks version of Python 3, Pip 3 and upgrades Pip 3 if out of date
You should always try to use Python 3 if you can help it*. Python 2 won't be around for much longer.
*Not always possible, as so much stuff that you'll want to use has been written in Python 2.
Then, because for testing we want to turn our lights on and off interactively, we want to use the Python shell. But quite frankly, the default Python shell you get when you type python / python3 isn't very pretty, or helpful. So we'll install a Python shell on steroids - IPython.
sudo pip3 install ipython...downloads and installs IPython using Pip 3
Once it's installed, we should now be able to launch it, using ipython in the Linux shell. Check that it is using Python 3. You don't have to look very far. It tells you. There.
IPython is exactly like the standard Python shell, except there are lots of helpful features like line numbering, colour coding, etc. We've also found that it is good at coping with code being copied and pasted in over the SSH session. Useful, when you are
Before we proceed with modifying our rosie application, let's interact with the relay (and the torch) using a new class that we'll set up.
class Light: def __init__(self, relay_pin = None, momentary = False): self.relay_pin = relay_pin self.momentary = momentary gpio.setmode(gpio.BCM) gpio.setwarnings(False) gpio.setup(relay_pin, gpio.OUT) self.switch_closed = False def switch(self): if self.momentary == False: if self.switch_closed == False: gpio.output(self.relay_pin, 0) self.switch_closed = True elif self.switch_closed == True: gpio.output(self.relay_pin, 1) self.switch_closed = False elif self.momentary == True: gpio.output(self.relay_pin, 0) self.switch_closed = True time.sleep(0.1) gpio.output(self.relay_pin, 1) self.switch_closed = False
See how it looks infinitely better in IPython now that there is some colour coding and formatting? You can also define entire blocks of code, like we are doing with our class, before submitting it. Execution is done using the 'Enter' key.
Our class Light represents our lights. It will be initialised with a specific GPIO pin that is connected to the relevant channel of the relay. We'll also have two modes: a momentary switch and one that isn't. This should allow it to interact with both Eric and Electron 2000 using this one single class.
The switch() method is there to simply allow us to send the relevant signals to the relay. When the flag is False for momentary, we simply open or close the circuit, one of those actions at a time. When it is True, we close and open quickly (with a delay of 0.1 second).
We'll use an instance variable self.switch_closed to keep track of the current state of the light's switch.
All we need to do now is instantiate a Light object, and call its method.
For Eric, we don't need the switching to be momentary:
l1 = Light(13, False)
And when we call the l1.switch() method, we see that we can turn Eric on / off! We've successfully bridged the world of code, with a physical object that we use (perhaps) every day.
l1.switch()
You know what we're now going to do. Because let's face it. That torch on Rosie? No way. We'll do the same, but with Electron 2000 connected to the relay (using the same GPIO pin). 4 channels on the relay means you could have 4 torches on the go. But that's silly.
We'll instantiate Electron 2000 as l2.
l2 = Light(13, True)
Guess what? We're now in control of the head torch. With each call to l2.switch(), we can cycle through the different light settings. Pretty chaotic, and kind of cool, at the same time.
l2.switch()
So what is there left to do? In true Rosie style, we'll return to our rosie application and call it rosie-web-lights.py. And here it is:
Besides the new Light class we need to add to the code, we will add a little Flask function to respond to HTTP POST requests on the '/light' web address by switching the lights.
def rosie_light(): _light = request.form.get("light") if _light == "l1": l1.switch() return redirect(url_for("index"))
And because - for now - we want to have our web browsers make this POST request, we'll modify Flask's Jinja2 template for 'index.html' to have a new form and button.
<form action="/light" method="post"> <button class="button-mode" type="submit" name="light" value="l1">Light 1</button> </form>
This simply makes a new HTML button appear, which when pressed, sends a HTTP POST request from the browser to Flask running on Rosie. And because that request routes through to the rosie_light() function, and ultimately leads to l1.switch() method being called, it switches through the lights, on-demand.
And of course, somewhere in the code, we've instantiated our super-duper light as l1. GPIO pin 13 has the honours here to instruct the relay.
l1 = Light(13, True)
Incidentally, we do revisit this code in a later episode, to make a little more advanced.
One little gotcha. Whenever you now run rosie-web-lights.py or use Supervisor, don't forget to use python3, not python.
python3 rosie-web-lights.py
And stop / start rosie using Supervisor's supervisorctl command.
sudo supervisorctl stop rosie sudo supervisorctl start rosie...stops and starts the rosie application using Supervisor
Clearly, in futuristic dystopia, we don't want the lights to be controlled by Rosie's clumsy human operator. We want Rosie to control the lights herself, depending on the things that she observes in the world. But that's just stuff that we can do with some logic and code, right? For now, you have permission to feel pleased with yourself that you've hacked a head-torch. All in the name of law and order...
Now... where were we with hacking that Frozen wand..?
Information overload:
Official information on iPython:Get up to speed with differences between Python 2 and 3:
We are using a 4-channel relay module from Kuman:
Comments
Post a Comment