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 :)