Tuesday 31 March 2015

IT'S ALIVE !!

Being on shifts has its drawbacks. Stupidly early starts and twelve hour days aren't everyone's cup of tea, and understandably so. But they do have some advantages, and one of those advantages is quite a lot of time off. Four days in every eight in my case.

So I spend my free days playing videogames, watching movies, playing with my dog, or just generally chilling out. And messing about with Raspberry Pi projects of course. Everyone needs a hobby, right?

In my last blog I'd actually built an RPi powered vehicle. I called it G-Bot. It didn't actually do anything, but it looked pretty cool - I thought so anyway. So now the time has come to write some test code and see if I can get this thing to work.

 G-Bot. Click to enlarge (the photo, not the bot...)

I used some of my existing code just to see if the thing would actually move, and the first thing I found out was that I was right to be worried about the weight of the battery. The bot did indeed move, or try to, but I could hear the stepper motors struggling to shift the mass. It was a combination of a tiny growling sound coming from the motors, and lots of (slow) wheelspin from the "tyres". These are really cheap motors and I wouldn't expect them to take much stick, so first thing on the agenda was to swap out the battery for a lighter power source.

Not having a micro-nuclear reactor to hand, I settled for a couple of AA battery holders from the local Maplins. These take 4 x 1.5 volt batteries each, therefor each pack gives an output of 6 volts. While this in theory would be enough to run the G-Bot, I doubled up to two battery packs because they had nowhere near the amount of Amps available that the larger lead-acid battery had. 12 Volts wasn't a problem because the voltage regulator I'm using allows a very broad input voltage range, as long as it's DC, and still gives 5V at the output.

The AA packs combined are less than half the weight of the LA battery.

So with it's new power plant installed, the bot doesn't look quite as neat, but is a lot lighter. I've only bodged the batteries in place temporarily, this is just for a test. Honestly. The battery packs are wired in series, and yes that is electrical tape wrapped around the joint. I'll do a better job once I know this works.

More cargo space available now...

Back to movement testing then! I modified some original code to do a simple straight line test. It basically runs both motors for a time, waits for a second, then runs them in reverse. I also had to reverse the pinout assignment within the code, because the motors are back-to-back now, effectively reversing the rotational direction of one of them in relation to the other. Here's the straight line test code...

Notice the reversed GPIO pin assignments at Line 9

And here's the resulting movement. YES! It moves! I am happy :)

My first ever robot trial. Next stop, global domination.

Inspired by the successful trial, I modified the code to make G-Bot rotate around it's central axis...

The modification is barely noticeable

This block of code is practically identical to the first one, except that I have put the GPIO pinout assignments back in their original order. As the motors are now mounted facing opposite directions to each other, they effectively run in opposite directions. Here's the result...

Hmm, not a full circle...

From this test, I concluded that four full revolutions of the motor wouldn't result in a 360 degree rotation of the bot. This is due to the diameter of the "tyre" in relation to it's distance from the central point of G-Bot and effect of the opposite wheel turning. Uh-oh, I sense maths are gonna be needed at some point. Not my strong point. I'd rather do some trials for now, and work out the formulas later, or ask someone clever to do it for me :)

Anyway, through trial and error, I found out that the motors need 530 signal pulses to make the bot turn 90 degrees. (Remember 512 pulses makes the wheel do one complete revolution - it's all to do with ratios and crap, it baffles me if I'm honest. But I've promised myself I'll found out about this stuff). I modified the original "quarter turns" program and this is the result...

Not perfect, but close enough for testing

Well that went pretty well I thought. The bot does have a little bit of wheelspin still, but I think I need to shave a little off the skids. That should allow the tyres to have more purchase on the ground. Too much though and G-Bot will be tilting about all over the place.

It's important to remember that while I am sending the start commands from my PC, the code that is actually running the bot is sitting on a MicroSD card in the RPi itself. It's all self-contained on board. In theory anything that can run an SSH client could connect to the bot over WiFi and issue commands. That's pretty impressive considering this whole thing has cost about £40 all-in.

So I'm going to sign off with a video of G-Bot attempting to drive in a square, and land at it's original starting position. Until next time, I bid you farewell.







Sunday 29 March 2015

The Build

After working out how to control a couple of stepper motors independently, the next logical step in my experiment was to build some sort of vehicle. I had a few ideas floating around, but they were either too silly (dual-motor toothbrush bot) or too optimistic (T-1000 Terminator).

You might have to google "toothbrush bot"...

Anyway, I had plenty of bits lying around, so I eventually made a start. I'll warn you now, don't expect anything too impressive - this was my first attempt at anything like this :)

So, I took an old electrical panel cover, drilled a few holes in it and mounted a stepper motor either side. I had a couple of vacuum suckers left over from a previous work project, and I thought they might work as wheels, so after drilling out some bolts to act as axles, I mounted them to the motors. I then glued a couple of rounded nuts to the bottom of the tray to act as skids. It wasn't much, but it was a start.

As usual, click any image for a larger version.

It's upside down here...

Next step was to find a power source. The Raspberry Pi requires 5 volts, as do the stepper motors, but the more common battery voltages are 1.5V (or multiples of it), 6V or 12V. I had a 6 Volt 4 Ah battery in my drawer, but it was (a)quite heavy and (b)the wrong voltage. The voltage wasn't really an issue; simple voltage regulators are quite cheap (I picked one up from eBay for about £3) but the weight was a bit of a concern. I decided to build the vehicle around this power source, with a view to swapping it out later to a lighter one.

The next couple of pictures show me testing the battery, then testing the output voltage after passing the supply through a regulator. This particular regulator will accept 6V - 42V and give a steady output of 5V at 3A (3 Amps should be more than enough to power an RPi, a WiFi dongle and a couple of small motors). [He said, hopefully.]

6.368 Volts direct from the battery, 4.988 Volts through the regulator.

Notice also that the voltage regulator has a USB output. This wasn't ideal for this particular project (you'll find out why later in this post) but it was so cheap it was worth the extra hassle.

OK, so that's our power supply sorted, although I am still worried about the weight. Anyway, I used some self-adhesive plastic mini-trunking (that was all I had available) to stop the battery from slipping around in the tray.

Does it look like a robot yet?

I then mounted a small switch (stolen from a combi-boiler I recently had ripped out) which would act as a main power isolator. I didn't fancy the idea of pulling the connectors off the battery every time I wanted to power down. This switch just breaks the positive supply lead to the voltage regulator.

Mini cable ties are cute and awesome :)

Next up were the actual electronics. There wasn't enough space to lay everything out side by side, so after messing about with designs I decided to raise the RPi above the stepper driver boards. Aside from space saving, this also gives access to the USB ports, one of which will be used for the WiFi dongle. It also allows removal of the MicroSD card from the Rpi, should I bugger something up. Which is likely.

Stepper motor driver boards installed

The RPi itself is raised on pillars, although it doesn't look like it in this photo. The pillars are made from those little nuts either side of a VGA connector that always seem to unscrew themselves. Little bastards.

Totally wonky, but solidly mounted

OK, that was all the essential hardware in place, now for the wiring. I connected the stepper motor flying leads to the driver boards and tucked the wiring in place. Then I attached the power leads to the driver boards, and stripped the other ends. Unlike previous experiments, this time I'm not powering the stepper motors from the RPi itself, I'm powering them directly from the voltage regulator. This means there will be a lot less load on that all-important surface mounted fuse. All I intend to power from the RPi itself (at the moment) is the WiFi dongle. Finally, I connected some jumper leads to the driver boards and it looked something like this...

It's getting crowded already

It was time to wire up the power leads. To do this, I cut a USB lead in half and stripped the cables. We only need to use two of the four cores (Red and Black, the other two are for data - which we aren't using here). I plugged the large USB plug into the voltage regulator output, and ran the stripped ends into a small terminal block. I stripped the other end of the USB lead, connected those to the terminal block and plugged the small USB plug into the RPi. Why bother cutting the USB lead I hear you ask? Well, we still need power for the stepper motor driver boards. So the two jumper leads I stripped earlier also went into the terminal block. I then connected the data jumpers from the drivers boards to the RPi GPIO pins.

This is getting busy!

Almost there...

Finally, I tidied up the wiring and added the WiFi dongle to a USB port...

Well it's compact...ish

The next step will be configuration and testing, but that's for the next blog post. For now, I'll sign off with more pictures of G-Bot. Yes, I named it G-Bot. My gamer friends will know why :)



Did I mention that I'm worried about the weight of that battery?...




Saturday 21 March 2015

Twins

In my last blog, I set myself 3 challenges..

  Get a stepper motor to run in reverse
  Demonstrate precision control of the armature position
  Get two motors running independently, from a single RPi

I did a bit of googling and found that the motors I am using draw a maximum of 92mA under full load, and that includes power used by the driver board. The theoretical maximum current draw for two motors running concurrently is therefor 184mA. Given that the RPi has a safety fuse rated at 750mA, this leaves just over half an Amp to run the RPi itself. I don't want to push my luck, so for the dual-motor experiment I'm going to use an Ethernet connection rather than WiFi (the WiFi dongle is USB powered which means more load on the fuse).

Anyway, on to challenge 1...

Get a stepper motor running in reverse

While this sounds an easy thing to do, it's not quite that straightforward when dealing with arrays, especially multi-dimensional ones. After a few tries (and fails), I worked out the simplest way of doing this is by having two separate control lists, one for forward and one for reverse. We then just run the forward control list for an amount of time, then switch to the reverse control list, then back again etc...

Here's the modified control program which now allows forward and reverse control.

click to enlarge

You can see the two lists, the second one just being a reverse of the first. It is actually possible (and more efficient) to have a single list and have the control pointer run backwards, but for the sake of simplicity, I went with two lists. However, we might need advanced control of a list position pointer for the third challenge, which is something I look forward to taking on*.
[*Not really, it's giving me cold sweats thinking about it]

You might have noticed the number 512 there in those loops. There's a reason I used that particular number and it's explained in the next section, but for now here's a video of the forward/reverse control in action...

Forward and reverse motion

Next...

Precise control of armature position

Probably the best way of demonstrating this is to have the motor stopping and starting at specific points, something a normal AC or DC motor simply couldn't do. Well it could if you used a power control inverter and some method of obtaining the shaft rotational position (a pulse counter or high resolution tachometer or something), but even then it it's not hugely accurate.

First, I did a little research to find out exactly how many steps were used to make the output shaft of our stepper motor rotate a full 360 degrees. I should mention here that the shaft sticking out of the motor unit isn't the armature. That would give a pretty awesome rotational speed, but wouldn't have enough torque to be of any use. The units are geared down internally in order to give us usable rotational power, but at the expense of speed. It turns out that 512 complete turns of the armature results in 1 single turn of the output shaft with a speed variation ratio of 1:64. That basically means the output shaft is spinning 64 times slower than the actual armature.

So now we know that if we send 512 sequential steps to the motor, the output shaft will rotate once. (Remember the number 512 from the control loops in the earlier section? That's why I used that particular number.) Breaking this down, we could send it 256 steps to make it do half a turn. It follows that sending it 128 steps will make it do a quarter of a turn - or 90 degrees. I think you get the idea.

So I modified our basic Python program to do a few things differently. Firstly, it's now looking out for when I manually stop the program running, and if I do, it "cleans up" the GPIO pins before quitting. This just means it sets all the pins to a logical low state, it's a good habit to get in to. Secondly, instead or running through a never-ending loop, the controlling part of the program actually counts up to 128 (remember 128 steps equates to a 90 degree turn of the motor output shaft). Finally, there is a delay statement which makes the program sit idle for a second before running the count to 128 again.

Quarter turn program - click to enlarge

The result of these changes can be seen in the video below. The motor shaft turns 90 degrees, waits a second, turns another 90 degrees etc... and carries on until I stop it manually. Try getting that kind of positional control out of a normal motor. Not gonna happen easily.

Quarter-turn steps

Finally...

Two stepper motors running independently, controlled by a single Raspberry Pi

OK, here's where things get tricky. I'll admit, I had a pretty decent idea of how to complete the first two challenges even before I started them, for this one I'm winging it.

Before we start, here's a drawing of how the dual driver boards are physically wired to the RPi.
GPIO wiring - click to enlarge

Each driver board is supplied power from the 5V rail (and Ground) of the RPi. I simply used an additional four GPIO pins to control the second motor. Before we get into independent motor control, we need to test the RPi can actually drive two motors, so here's the code to do that...

 Dual motors - click to enlarge

You can see that I've assigned a second set of GPIO pins as outputs, and initialised them. Later in the program, in the control loops, I've just added an extra line so the control signals are sent to the second motor as well as the first. That's the absolute simplest way to test if something works or not, send it known good control signals, and see if it mirrors the first device.

So even though that modified code will run two separate motors, they aren't being controlled independently, they are basically just receiving the exact same signals, and will do exactly the same thing. There is no way to tell one motor to do something, without the second motor doing exactly the same. Anyway, at least it worked, and here's the video to prove it...

Please ignore my water bill in the background...

So now we know the hardware is physically capable of driving two motors, and those motors are controlled from two separate sets of GPIO pins, it's "just" a case of writing some Python code to allow them to be individually controlled. Here goes...

Code to control 2 motors independently

Well, after a bit of head scratching and some trial and error, some code finally emerged that allows the two motors to run independently of each other. I decided early in the process that it's a lot simpler to stick with separate sequence lists for forward and reverse rather than having a bidirectional program pointer. I know that time is coming, it's just not yet. I've commented the code itself, so I won't go into detail about what each line does, but this is the general idea...

The RPi picks two random numbers for each motor. The first of these numbers will define how many steps the motor will take. Remembering that with these particular motors 512 steps equals one complete revolution of the output shaft, I limited the number to be no more than 256. This is purely for demonstration purposes, so we have to wait less time before a potential direction change. Which brings me on to the second random number. This can only be one of two possible values, and it decides which direction the motor will run in. Basically, there is an "if" statement in the motor control loop that can take one of two paths, depending on which number was chosen.

I'd like to thank my friend David Somers for explaining to me how the random number generator works in Python :)

Finally, a (very dodgy quality) video of the motors running.

Random...

As you can see, they run for a random time in a random direction. I apologise if you can hear my daughter laughing in the background, she's recently discovered the wonders of red wine.

So, now I know the RPi is capable of running two motors, and I am capable of writing code to control them independently of each other. Whatever next, a robot?..


Saturday 28 February 2015

Stepping out

Wow!, has it really been more than a year since my last blog post?! Time really does seem to fly! So if I'm honest, I haven't really been doing too many experiments with the RPi. Real life has a habit of getting in the way, as I'm sure everyone is aware. However, I haven't been totally idle.

My original Raspberry Pi (Model B) is now acting as an awesome media centre downstairs on the main TV, streaming 1080p HD movies across my home network via an amazing piece of (free) software called RaspBMC. This is basically a heavily modified version of XBox Media Centre which has been adapted to run on the RPi, and it runs really well (on a Model B Rev 2 at least). The RaspBMC software is about to have a major overhaul to a completely new framework called OSMC which should provide an even more awesome experience, but for now RaspBMC works perfectly.

My Raspberry Pi 2 is currently running something called RetroPie, which is a nifty bit of software that runs in conjunction with the Emulation Station front end to provide a superb little emulator of vintage games. I'm currently running this on a 42" TV using an Xbox 360 controller but I plan to acquire a 3.5" tft and cram it all into an old handheld system, to make a portable games machine that can emulate all the old classics such as ZX Spectrum, Commodore 64, Amiga, SNES, etc.. But that's for a different project (and a different blog post).

So that just leaves the Raspberry Pi Model B+. This is the unit I now use for messing about with. I haven't been doing much lately, so rather that let my hobby fade, I decided to try something new. I'd heard of stepper motors, used them in work in fact, but I had no real idea of how they functioned or were controlled. So off I trotted to eBay and blagged a few small stepper motors for experimentation. They weren't too expensive, so it's not the end of the world if I blow them up. These are the ones I bought, but that link might not last forever, so for reference they are "5V 28BYJ-48 4-Phase Stepper Motor with ULN2003 Driver Board". They were just under £4 each with free delivery.

Stepper motor and driver board

The above picture shows what you get. How they can make something like that, offer free delivery, sell it for £4 and still make a profit is beyond me, but I digress.

Anyway, how to get this thing working? And more importantly, how to get it controlled via the RPi?

After some research (you don't get instructions with the motor) I found that there are a few different types of stepper motor, and also a few different ways of controlling them. For the sake of reference (and to keep this post relatively short) I'm only going to explain how I did it with this particular model.

So the driver board needs a permanent 5V supply. Perfect, we have a 5V rail on the RPi, so we can use that as long as the required current isn't too high. The 5V rail is protected by a 750mA fuse, but that fuse also protects everything else on the board, so we have to be careful not to overload it.

As for actual motor directional control, this is where things get interesting. Unlike a normal motor where you just apply power and off it goes, stepper motors are built with a series of coils that need to be activated in a certain sequence to generate the magnetic field needed in order to turn the armature. (The armature is the actual part that spins). Having control over these individual coils means we can have very accurate control of the angular position of the armature. In fact, we can move it in tiny little steps - hence the term 'Stepper Motor'.

The driver board (the square bit with the microchip on in the above picture) allows us to send a low voltage signal which is in turn used to activate a gate which allows a higher voltage through the chip to energise a coil in the motor. Notice I said coil, not coils. This particular motor has four coils, so we have four inputs on the driver board, one for each coil.

Half-stepping and Full-stepping

Before I go any further, take a quick look at this diagram...


As you can see, there are four coils, each with an input (A, B, C & D) and they all have a common return. These 5 wires are the 5 you can see running from the driver board to the motor in the first picture. The armature in the middle is the part that spins. Without going into the theory of how electric motors work, here is the (very) basic premise of what makes this motor spin...

The armature is a permanent magnet, and as you know, magnets attract each other if the polarity is opposing. Also, when you pass an electric current through a coil which is wrapped around a ferrous bar (or torus, or any shape really) a magnetic field is generated in that medium. So, referring to the above diagram, if we generate a magnetic field in coil 1, then the armature will spin around and align itself with that coil. Then, if we turn the power off coil 1 and energise coil 2, the armature spins around and aligns with that one. I think you get the picture.

Please note that this is a very simple representation of how a stepper motor works. In reality, the armature has a a number of magnetised areas (16 in the case of our motors) which align with "teeth" that are magnetised on the stator (the part that houses the coils), but that's way beyond the scope of this blog. Plus I need a cuppa just now.

Anyway, energising the coils in the correct order causes the armature to spin. Now there is a slight twist on this. (See what I did there?) We can energise the coils in the order A > B > C > D and the motor would indeed work. It does, I've tried it. As you can probably guess, this is called "Full Stepping" and it means the armature "points" to one coil, then the next, then the next etc.. This gives us a reasonable output speed, but not much turning force (Torque). We can get much better torque, at the expense of rotor speed, by using a method called "Half Stepping".

"Half Stepping" is where we energise coil 1, then coils 1 AND 2, then coil 2, then coils 2 AND 3, then coil 3 etc... Basically creating an extra point between coils for the armature to align with. This works because of the way a magnet will align itself mid-way between two identical fields. Physics, or something.

So now obviously we need eight steps instead of four, to make our armature complete a revolution. This won't be a problem as we are going to use the Raspberry Pi to energise the coils in the right order, by means of a Python program controlling our old friends, the GPIO pins. We connect 4 GPIO pins to the 4 inputs on the stepper motor driver board and we're ready to do some coding. Note in the following picture, I've massively over-complicated things by using a piece of breadboard as a junction box. I didn't have any female to female jumper leads, so had to join some female to males. Anyhow, trust me there are only 6 wires between the RPi and the stepper driver; 2 power and 4 control.

As usual, click for a larger image

So onto the code. The easiest (although not only) way to apply power to certain GPIO pins in a specific order is by use of a list. We just scroll through the values of a list, if it's a 0 we turn the GPIO pin (and therefor the motor coil) off, if it's a 1 we turn the GPIO pin (and motor coil) on. When we get to the end of the list, we just jump to the top and start again. This will keep our motor rotating indefinitely. Here's the code...

Click for a larger view
So for those interested, a breakdown of the code..

The #import libraries section just grabs the required libraries to save us having to write code which has already been written by someone a lot cleverer than me. We need the 'time' library because we use a delay to control how fast our motor will run.

The next three sections set up the RPi, telling it we want to use the BCM standard for addressing the GPIO pins, set up a small list to tell our program which physical pins to use in this case, sets them all up for output rather than input, and then sets all their values low.

The #define sequence area of the program is the main coil control list I was talking about. If you look at the columns of 0's and 1's, imagine the leftmost column representing coil A on the motor, the second column represents coil B and so on. If you look carefully, you'll see it's actually a list inside another list. Hmm, hard to explain. The main list (called Seq) has 8 items. Each of those items contains 4 further items which are the 0's and 1's. This is known in most programming languages as a multi-dimensional array, but I might start sounding like I know what I'm on about, so I'll stop there.

Anyway, the #main loop part is, strangely enough, the main loop of the program that actually causes stuff to happen. More on that in a sec.

Finally, the #cleanup when done part just resets all the GPIO's and is good practice when using input/output of any kind on a microcontroller. Having said that, eagle-eyed readers will notice that this part never actually gets executed as the main loop is set to run continuously. The reason for this is because I only wrote this program to demonstrate this single blog post, it will be expanded as time goes on to incorporate more functions etc.

So that main loop eh? Complex? Not really. The "while True" line just means "keep going forever".

Next we run a 'for' loop using a variable called 'halfstep' that counts up from 1 to 8.

Within that loop, we run another 'for' loop using a variable called 'pin' that counts up from 1 to 4.

This next line is the meat and potatoes of it all...

GPIO.output(ControlPin[pin], Seq[halfstep][pin])

...that just basically sets the right GPIO pin to the right value, depending on what point in the loops the program is. Remember 'pin' is counting from 1 up to 4, for each iteration of 'halfstep' which itself is counting from 1 up to 8. Sounds complicated to the uninitiated but nested loops are common practice in any programming language.

The 'time.sleep' line is just used to put a small delay between activating the GPIO pins. If you send the signals too fast, then cheap motors can't react in time and all hell breaks loose.

Here's a short video of it actually running...


...and one of it slowed down so you can see the LED's on the driver board representing the outputs from the RPi GPIO pins. Each LED is connected to one coil on the motor stator. The armature doesn't appear to be spinning at all in this video, but trust me it is. I had to slow the video down so much (to show the LED sequence) that the rotor appears stationary.


So that's probably one of the most complex blog posts I've made in a while. Next time I'll be making the stepper motor run in reverse, showing how we have precise control over armature position, and if all goes well and I don't burn the house down, getting two steppers to run independently on one Raspberry Pi.

I hope.








Monday 23 December 2013

Woooo colours!

I'm venturing into the unknown once again here, using my view that "the best way to learn is by experimenting" as an excuse for spending an hour or two with the RPi. With my ongoing mission of expanding my knowledge of interfacing software to hardware, I bought some RGB LED's from eBay (99p for a pack of 4, bargain!). Although I already know the theory behind these components, I've never actually used them before, so what better time than now to start.

An RGB LED is basically an LED (Light Emitting Diode) which has multiple anodes, each capable of outputting a different colour, in this case Red, Green or Blue,  hence the 'RGB'. There are different types of RGB LED's, but I went for the 5mm 'water clear' type, with 4 legs and a common cathode. A "common cathode" just means one of the legs acts as a single cathode for all the anodes, of which there are 3. One anode controls the Red output of the LED, another controls the Green, and the third controls the Blue. It's easiest to imagine this type of RGB LED as three separate coloured LED's rolled into one, and all the cathodes twisted together to form a single leg. Sticking with this analogy, it's worth mentioning that just like single LED's, each portion of this LED requires it's own current limiting resistor. There was no information included with the ones I bought, so I took a 'guesstimate' that a 330 ohm resistor should do the trick. It's common for the different elements of RGB LED's to require different value resistors to maintain a consistent brightness across the colour range, but that's way beyond the scope of this experiment.

It's also worth noting that 'common anode' versions are available, in which a single leg provides the power to the LED, and the user switches each cathode to ground in order to receive an output. I am assuming a single current limiting resistor is required for that type, but I could be wrong, so it's something I've made a note of to research at some point in the future. Anyway, onto the circuit...


As you can see, it's super-simple. The cathode leg is connected straight to the RPi ground, and each anode is connected directly to a GPIO pin, through a 330 ohm resistor. (Note: a 58 ohm resistor found it's way into my 330 ohm tray, and the LED didn't like it. At all. In fact, it paid the ultimate price in the name of science).

So, I wrote a very basic routine to make sure all three colours worked...


...and then embarked on a journey to make some kind of user-controllable action happen from within a Python program.

After a while, I had a basic program running which let the user choose which colour was output from the LED, with the ability to choose between Red, Green, Blue and a number of combinations of the three. Some of the colours were more overpowering than others - for example, Red and Green together created a darker Green, rather than the Yellow/Brown it should have. This relates to the resistor values and brightness intensity I talked about earlier. I could have spent some time changing resistance values to achieve better results (and I might do that one day), but this exercise was more about program control than colour accuracy. As expected, setting all three outputs on resulted in a 'white' output. Sort of.

Here is a short video of the experiment in action...


It's worth mentioning here that the output brightness of the LED can also be affected by varying the input voltage. So for example, feeding the Red anode with 3 volts will yield a much stronger Red glow than if you fed it with 1.5 volts. This is usually how you obtain a much wider range of colours - by varying the voltages supplied to each pin of the LED. Unfortunately, the GPIO pins of the RPi are either on or off (3.3V or 0V), so controlling the voltage fed to the LED isn't possible without third party hardware, or a complicated hack of components. So my next experiment will involve rapidly turning the RPi outputs on and off, hopefully simulating the effect of feeding the LED with a lower voltage. I don't expect it to be effective (or even work for that matter), but it's the finding out that counts.

For science, right?

Friday 6 December 2013

Combining input and output.

So in my previous blog, I discovered how to get an external signal into the RPi, and read it via software. The post before that talked about sending a software driven output to external hardware. It stands to reason that this blog post should be about combining the two.

I could just use the external button to turn an LED on and off, but that doesn't really demonstrate the versatility of software to hardware interfacing. In fact, I wouldn't even need software to do that at all, I could do it all with physical wiring. So this project is about creating a 4-bit binary counter, using the button as an increment trigger and 4 separate LED's to indicate the output state, with each LED acting as a single bit in the binary number.

First, a quick rundown on how binary works. In binary, a bit (binary digit) can only be one of two states. Whether you call it "On/Off", "True/False", "One/Zero", it doesn't really matter. The point is you only get two states. This is why binary is usually thought of as Zero's and One's. The first bit (rightmost) of a binary number is "worth" 1 in decimal, the second bit is worth 2, the third is worth 4, the fourth is worth 8 etc.., so with each additional bit, the value is doubling. I've drawn this dodgy table to help explain..


As you can see, looking at the values of the columns starting on the right, they go 1,2,4,8; doubling each time. If we were playing with 8-bit binary, our sequence would read 1,2,4,8,16,32,64,128, but with the smallest number on the right of course.

Take for example from that table, the decimal number 6, and start with bit4. The value of bit4 is 8, and because that is larger than the 6 we are after, we put a 0 in that column and move onto bit3. This is worth 4. 4 is less than 6 so we put a 1 in that column, and subtract 4 from the 6 which leaves 2, and move on to the next column which is bit2. Bit2 is worth 2, which we are looking for, so we put a 1 in that column, subtract the 2, and finally move on to bit1. But after subtracting that last 2, we are left with 0. Bit1 is worth 1, so we put a 0 in that column. So we have deduced using that method, that the 4-bit binary form of the decimal number 6, is 0110; that is to say (0 x 8) + (1 x 4) + (1 x 2) + (0 x 1).

In 4-bit binary, the largest number possible is 15. Work it out. If we put a 1 in every column, we would get (1 x 8) + (1 x 4) + (1 x 2) + (1 x 1) = 15. If we need higher numbers, we need more bits, so the next generally accepted step, is 8-bit binary. The biggest decimal number possible using 8-bit binary is 255.

Okay, so you know how binary works now. Sort of. We will need 4 LED's, one to display each binary digit (bit) of our 4-bit number. Here's the circuit diagram, and it's real-world wiring to the RPi. As usual, you can click on it to see the full-size image.



So basically, the button part is exactly the same as what I discussed in the previous blog, and I've just added 4 LED's, wired each of them to a GPIO pin on the RPi, and returned each of them to the Ground (GND) rail through a 330 Ohm resistor. If you remember from a couple of posts back, the resistor is there to protect the 1.7 Volt LED from the 3.3 Volts provided by the RPi. All we need now is some Python code to control our GPIO pins, and I've done this in 3 sections...


This code just initialises the GPIO pins as an input and multiple outputs, and also has a little function which converts any given decimal number into a binary number with a user-chosen number of bits.

The middle section of code is as follows...


That part basically sets the output pins to a high value (3.3V) or low value (0V) depending on the value of a string. That string is a single bit of our 4-bit binary number. If bit1 is a "1" it sets the associated GPIO pin to 3.3V, otherwise it sets it to 0V, etc... As we are dealing with binary, there are no other options, it's either "1" or "0", "High" or "Low". No middle ground.

Finally...


This is the actual meat and potatoes of the program, the bit that does the work. It's basically a modified version of the code from my previous blog, but instead of just detecting the button presses and incrementing a counter, it converts that number to 4-bit binary (using the function I mentioned earlier), then tells the RPi to activate the appropriate GPIO pins as outputs, using the second function. Finally, if the counter exceeds the value 15, it resets it to 0.

So the idea is to show the value of the counter in decimal and binary on the monitor, and at the same time light some LED's on the breadboard, with each LED representing a single bit of our 4-bit binary number. As usual, here's the video of it in action...


For my next project, I want to learn a little more about program flow and function control, but I also want to carry on with the hardware/software interfacing, so I'm thinking of some sort of program where the user is given options, and something happens in the real world depending on the choice they make.

Either way, I'm sure it'll involve flashing lights of some description :)

Friday 22 November 2013

From output to input...

With my very first hardware experiment completed successfully, I felt compelled to continue... for science!

So having 'mastered' the art of software-to-hardware output, the next logical step for me was hardware-to-software input. This would involve some sort of switch or button, presumably making the PC do something when I pressed it. After many hours of study through ancient tomes of historical text by candlelight (read that last sentence as 'a quick bout of google-fu'), I felt ready to start on my next project - the 'click a button and make something happen' experiment.
The circuit.

As you can see from my awesome graphic skills there, it's quite a simple circuit again. Basically, I'm connecting Pin11 of the RPi (which is GPIO17) to Pin1 (3.3V) through a large resistor. By large I mean high resistance, not physically big. I'll explain why I need the resistor in a minute, but back to the circuit...

You can also see a normally open, momentary switch which leads to Pin6 (Ground) on the RPi. So when the switch is open, it's getting a small voltage to Pin11 from Pin1. But if I push the switch, the circuit is closed and Pin11 is effectively shorted to Pin6 - the Ground. These differing states should be all we need to let the Python program know whether or not the switch has been pressed.

Now back to that resistor. If you can imagine the circuit without that resistor in there for a minute, it's obvious that if I was to press the switch, I would be shorting 3.3V directly to Ground. A dead short. Not really a clever thing to do. So the large (10K) resistor ensures that only the tiniest amount of current is drawn when the switch is pressed, thus protecting the RPi. I hope.

The code.




So the code starts with the same lines as last time, basically using existing libraries coded by some clever person somewhere, sometime. Once again, thanks, whoever you are.

I have commented the code to try and explain what each line does. The reason I needed the variable called "last_state" is because the little RPi is so quick that without it, a single button press would be read many times, and that isn't what I was trying to do. Er, how can I explain that?... I wanted to pick up one click of the button, no matter how long I kept my finger on it. Without that variable being used as a flag, holding my finger on the button would cause the program to read it as many, many clicks instead of one long one.

After a bit of tweaking and a cup of tea which seemed to go cold quicker than usual, here is a picture of the resulting output...



Here, have a video, it might make more sense...



  So there we have it. Experiment number 2 successfully completed :)

Just one more thing, the technically astute viewer might notice that I have no mouse, keyboard, or video output attached to the RPi now - just power and Ethernet. Well to be honest, I got fed up of having two mice, two keyboards, and a third monitor on my desk (I use two monitors usually), so I am now connecting to the RPi over my local network using SSH. It's like a remote desktop kind of thing, very clever and extremely handy. It also performs very, very well on this tiny little device.

Anyway, I digress. I'm cooking up ideas for experiment number 3 which will no doubt be the marriage of the two experiments completed so far. Probably, a physical input to the RPi, which is read by the Python program, processed in some way, then output physically somehow via the RPi. 

It might be time to break out the LED's again, perhaps a different colour this time as I'm feeling adventurous!

Stay tuned for the next epic adventure. Or something.