OBJECTIVE
We will build an 8-bit binary counter. This means that it will be able to count from 0 to 255, which in binary is 00000000 to 11111111. An LED that is off will represent a binary 0 and an LED that is on will represent a binary 1. Since computers count in binary, this is a useful circuit if you wish to understand what binary numbers look like.
Table 1 shows a snapshop of the 256 combinations that we need to cycle through.
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | DECIMAL |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 3 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 4 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 5 |
0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 6 |
0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 7 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 8 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 9 |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 10 |
… | … | … | … | … | … | … | … | … |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 247 |
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 248 |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 249 |
1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 250 |
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 251 |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 252 |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 253 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 254 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 255 |
THE CIRCUIT
To build this circuit you will need an Arduino (UNO or MEGA), 8 LEDs, 8 resistors and 10 wires.
TOP TIP
Instead of using 8 LEDs and 8 resistors, I like to replace them with an LED bargraph and resistor array. This makes the circuit look a lot neater!
THE CODE
First, we need to define which Arduino pins we will use to connect to the LEDs. We will use an array, with a data type of int.
int ledPins[] = {9, 8, 7, 6, 5, 4, 3, 2};
Then define a variable, with the data type of byte. We use byte because it can hold an 8-bit number (0 – 255), which is perfect for what we are doing.
byte count;
TOP TIP
This could have been written as int count;
This will work and you wouldn’t notice any difference. However, I want to encourage you to learn and think about data types.
int can be used for up to 16 bits. We are counting up to 255, which means that we have 256 different values (don’t forget binary 0!), This is why int works, because 8 bits of the 16 bits are used. However, this is not the most efficient way of doing this. It would be better to use a data type that can be used for up to 8 bits. The data type byte can be used for this
In our setup() we set each pin to be an output, using a for loop. We set our count variable to 0, to make sure that when we power up our circuit, it starts from 0.
void setup(void) {
for (byte i = 0; i < 8; i++) {
pinMode(ledPins[i], OUTPUT);
}
count = 0;
}
In our loop() we use the dispBinary() function to display and increment our count variable by 1 each time the loop runs. After each iteration we have a 1 second delay to hold the LEDs that are currently on and off.
void loop(void)
{
dispBinary(count++);
delay(1000);
}
We then use the dispBinary function, with a for loop, to display each number, one at a time.
void dispBinary(byte n)
{
for (byte i = 0; i < 8; i++) {
digitalWrite(ledPins[i], n & 1);
n /= 2;
}
}
THE RESULT
IMPROVEMENTS
One way that we could improve our circuit is by adding a button so that the counting is not automatic and you can press the button to increment the count by one. This would be useful for checking individual numbers and thinking about their decimal equivalent.
A further improvement would be a reset button, so that you could start from 0 whenever you wanted to.
FURTHER READING
If you want to learn more about binary numbers, then have a read of this article: understanding binary
If you want to learn more about data types in C++, then have a read of this article: data types in C++
If you want to learn more about calculating resistor values for LEDs. then have a read of this article UNDERSTANDING LED resistor values