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.


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.

Monday, 18 November 2013

20 months later, a new project..

So er, it's been 20 months since my last blog post. Where the hell did that go? A few LAN parties, many new game releases, a few books read etc, but more recently a new project!..

You may or may not have heard about something called the Raspberry Pi . A bit of a daft name, yes. But the Raspberry Pi, or RPi as it's known, is a complete computer on a credit card sized circuit board. And it's cheap. Like £30 cheap. Not bad for a fully functional computer!

This little device is very capable, given it's price. People are using it as a media centre running a version of XBMC (it can render 1080p video over HDMI) , a lot of people are using it as an aid to learning to code, some for gaming - this thing even runs Quake 3 Arena!, and some are using it to tinker around with "other" things. And I fall into that group.

Having delved into various forms of coding over the years, from Assembler(Yuck!) to BASIC to C++ to DarkBASIC to JAVA (omg NO THANKS!) I believe the time has come for me to have a play with the hardware side of things. The RPi doesn't come with a pre-installed operating system as such, but is based on LINUX, and a number of tools are freely available for it. One language that looks easy enough to learn is Python , and this apparently works very well with the RPi. So I headed over to Codecademy and worked my way through a few basic Python lessons. Sure enough it is quite simple. At least the first few lessons are, I haven't got very far yet :)

As I said, I want to learn a little about hardware, and more specifically how it interacts and interfaces with software. The fact that a program can run within a computer and directly control real-world tangible devices fascinates me. So armed with my RPi and a few electronic bits and bobs gleaned from ebay, I set my sights on intergalactic robotic domination. But I thought I'd better start off small, so I present to you my "Python-based RPi controlled Flashing LED" project..

The bits.

Here we have the RPi itself, a 'breadboard' (for easy circuit prototyping), a few random electronic components, and a selection of 'male to female' jumper leads. As you can see, the RPi has an SD Card plugged in one end (this holds the software). Also connected here are two USB devices (mouse and keyboard), a HDMI device (monitor) and the Ethernet for Internet/Network access. If you enlarge the image (by clicking on it) you will see a row of pins to the bottom-right of the board. These are the GPIO pins (General Purpose Input Output) and these are what we use to interface to external hardware.

The circuit.

This is about as basic as an electronic circuit will get.The brown jumper is linking a GPIO pin on the RPi to the Positive leg (otherwise known as the Anode) on the LED. I have then connected a resistor to the Negative leg (Cathode) in series (more about electronic circuits in future posts unless I burn the house down first) and then close the circuit back to the RPi by connecting the black jumper to the Ground GPIO pin. The resistor is there to protect the LED because the RPi logic runs at 3.3Volts, and the LED is only 1.7V, but that's a bit technical and not for this particular post :)

So that's the hardware wired up, now onto the software. Using the free Python editor that comes with the RPi software suite, I created this program...

Apologies for the picture, I haven't learned how to do screen grabs on the RPi yet.

I've commented every line to explain what the program is doing. The part before the 'While' loop is a bit geeky, but basically I have imported a pre-defined library so that I have direct access to the GPIO pins on the board. Thank you to whoever wrote that library :)

So after some administration rights issues which I won't bore you with here, I ran the program and here's what happened...

Not exactly mind blowing I agree, but it's the first experiment of what I hope to be many. In future blogs I intend to include circuit diagrams and better screen captures. Unless something else comes along in the meantime, I'm easily distracte...oooooh, Top Gear is on...