Maker.io main logo

Build a Simple Binary to Decimal Converter Box

2022-05-26 | By Maker.io Staff

License: See Original Project Switches

Learn how to build a straightforward binary-coded-decimal (BCD) to decimal number converter ‎box by following this beginner-friendly article. The final product contains eight switches that let ‎users input a number between zero and 255 by setting the individual bits of a byte. A custom-‎built microcontroller board then interprets the input before converting it to its decimal ‎representation to display the result in a more human-friendly format using a standard 16x2 ‎character liquid crystal display (LCD).‎

product_1

This image shows the final product. The LCD shows the input switch states and the decimal ‎equivalent.‎

BOM

Part/Qty

Building the Project Using as Few Digital I/O Pins as Possible‎

Although the schematic diagram of this project may look complicated at first, it only comprises a ‎handful of simple-to-use components:‎

 

This image shows the schematic diagram of the project.

The character LCD and the 10K potentiometer are the most prominent parts of the schematic. ‎The display uses six general-purpose input/output (GPIO) pins of the ATMega328PU ‎microcontroller (IC1). Note that the BOM for this project lists an Arduino UNO board. However, ‎the finished build only uses the microcontroller (MCU) of the Arduino board. You can use the ‎Arduino board as a convenient way to program the MCU and then pull the microcontroller out of ‎the development board and plug it into this project’s board.‎

As this project utilizes only the MCU without the rest of the Arduino UNO, you’ll have to add a ‎few external components that ensure that the IC functions as intended. The 16MHz crystal and ‎the two 22pF capacitors feed the MCU’s clock input. The 10K pull-up resistor prevents the MCU ‎from resetting itself, and the 100µF electrolytic capacitor helps prevent brown-out issues that ‎would also lead to the MCU resetting itself erroneously.‎

Besides these components, the finished project also contains eight toggle switches that allow ‎users to input a binary coded number. Instead of connecting the switches directly to the MCU’s ‎GPIO pins, I added an SN74HC165 shift register between the switches and the microcontroller. ‎This digital logic chip converts eight parallel inputs to a single serial line, which frees up five ‎GPIO inputs of the MCU. Therefore, the eight switches interface the inputs A through H of the ‎shift register, where A is the least significant bit (the rightmost switch on the finished device). ‎Finally, I connected two control signals and the serial output line to the MCU.‎

Tips and Tricks for Simplifying the Assembly Process‎

Start the build by thinking about where you want to place the components in the project box. You ‎can use masking tape and a pen to draw guidelines that help you make straight cuts. Then, ‎create a cutout for the LCD and drill four holes to mount the display to the case using four ‎screws. Then, drill eight holes for the switches and another for the potentiometer. Next, solder ‎the male pin header that comes with the LCD to the display PCB pins. You can later add the ‎female pin header to the perfboard to effortlessly connect the display to the rest of the circuit. ‎Finally, mount the switches, the potentiometer, and the LCD in the enclosure.‎

device_2

Your device should look similar to this once you add all the components. I used a smaller ‎potentiometer that I directly soldered to the perfboard inside the project box.‎

Next, assemble the circuit on a piece of perfboard. I recommend you start with the IC socket for ‎the ATMega328PU microcontroller, as this part has the largest footprint, then place the female ‎pin header close to the IC socket. Next, connect the other components according to the ‎schematic above. Lastly, tie the switches to the shift register IC using longer, flexible wires. ‎Repeat this process for the external potentiometer.‎

connect_3

Connect all the switches to the shift register. The pin headers let you easily disconnect the ‎circuit from the LCD.‎

Understanding the Device’s Firmware‎

Similar to the schematic diagram above, the project's firmware may look complicated at first. ‎However, you can break it down into three main tasks, as illustrated by the following flow chart:‎

flowchart_4

This flowchart illustrates the main tasks of the firmware.‎

The yellow box outlines the setup function’s primary task: initializing the necessary GPIO pins ‎and the LCD. The firmware for this project uses the standard Arduino LiquidCrystal library that ‎comes with recent versions of the Arduino IDE:‎

Copy Code
void setup()
{
pinMode(SH_LD, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(QH, INPUT);

digitalWrite(CLK, LOW);

lcd.begin(16, 2);
}

As you can see, the setup function initializes the three control lines connected to the shift register. ‎In addition, the method also pulls the clock low to disable the serial output of the external storage ‎IC. Finally, a special function, which I discuss below, sends clock signals to the shift register ‎when the Arduino is ready to receive the input bits.‎

The green boxes in the flowchart highlight the primary responsibilities of the loop function. The ‎loop method first resets the cursor position. It then prints some characters and requests the ‎current state of the eight toggle switches from the external IC. Next, the loop function converts ‎the eight input bits to a decimal number before it sends the result to the LCD:‎

Copy Code
void loop()
{
unsigned long currentMillis = millis();

if(currentMillis - lastMillis > REFRESH_DELAY)
{
lcd.setCursor(0, 0);
lcd.print("BIN: ");

readShiftRegisterValue();

// Write the bit values to the LCD
for(int i = 0; i < 8; i++)
lcd.print(bits[i], DEC);

lcd.setCursor(0, 1);
lcd.print("DEC: ");
lcd.print(getDecimalValue(), DEC);

lcd.print(" ");

lastMillis = currentMillis;
}
}

Converting the eight input bits from a binary-coded decimal to a single integer value is a ‎straightforward task. There are various methods you can employ to achieve the same effect. ‎However, this program loops over all eight bits and multiplies each bit with the appropriate power ‎of two. The resulting sum is the decimal representation of the encoded number:‎

Copy Code
int getDecimalValue(void)
{
int ret = 0;
int base = 1;

for(int i = 7; i >= 0; i--)
{
ret += bits[i] * base;
base = base * 2;
}

return ret;
}‎

Requesting Bits from the External Shift Register

‎The program’s main loop needs to request eight bits from the external shift register. The MCU ‎can accomplish this by setting the three control lines to the correct values:‎

Copy Code
void readShiftRegisterValue(void)
{
// Pull SH_LD low to latch the switch values
digitalWrite(SH_LD, LOW);
delay(5);

// Pull SH_LD high to enable bit shifting
digitalWrite(SH_LD, HIGH);
delay(5);

for(int i = 0; i < 8; i++)
{
bits[i] = digitalRead(QH);
sendShiftRegisterClockPulse();
}
}

The code snippet above demonstrates how to read eight bits from the SN74HC165 shift register ‎using an Arduino. The MCU first pulls the SH_LD line low to make the shift register latch the ‎switch values. Then, after a short delay, the Arduino sets the SH_LD output high again to enable ‎the register’s shift mode. Doing so makes the shift register output the previously latched bit ‎values using the QH line with every positive clock pulse. To read all eight bits, the for loop first ‎reads and stores the current state of the QH line before sending a positive clock pulse that ‎makes the shift register output the next bit value on its QH line. The program repeats the loop ‎eight times and stores the input bits in an array that the other program parts can access.

Download the Source Code

You can download the complete source code here.‎

Summary

finished_5

This image shows the finished product. ‎

This beginner-friendly project lets you build an intriguing BCD to decimal converter that’s perfect ‎for learning how to use the binary system for counting. Eight toggle switches allow users to flip ‎each of the eight bits of a byte. A display shows the input combination and the decimal ‎equivalent of the input values.‎

As the display already uses quite a few GPIO lines of the microcontroller, I added a parallel-to-‎serial shift register. Instead of using eight additional GPIO inputs by directly connecting the ‎switches, this approach only occupies three data lines of the ATMega328PU. The firmware ‎instructs the shift register to latch all eight switch states once the MCU is ready to read the ‎following values. Once done, the MCU individually requests each bit from the shift register by ‎reading the QH output and then sending a single clock burst to the shift register. This single rising ‎clock edge lets the register IC know it should output the next bit in the sequence.‎

制造商零件编号 830058383B
WE-XTAL QUARTZ CRYSTAL 16.0 MHZ;
Würth Elektronik
¥4.07
Details
制造商零件编号 C317C220J2G5TA
CAP CER 22PF 200V NP0 RADIAL
KEMET
¥2.36
Details
制造商零件编号 860010372006
CAP ALUM 100UF 20% 16V RADIAL TH
Würth Elektronik
¥0.81
Details
制造商零件编号 A000066
ARDUINO UNO R3 ATMEGA328P BOARD
Arduino
¥190.97
Details
制造商零件编号 181
LCD MOD 32DIG 16X2 TRANSMISV WHT
Adafruit Industries LLC
¥80.99
Details
制造商零件编号 P120PK-Y25BR10K
POT 10K OHM 1/20W PLASTIC LINEAR
TT Electronics/BI
¥13.68
Details
制造商零件编号 1555JLGY
ENCLOSURE PC GRAY 6.3"L X 3.5"W
Hammond Manufacturing
¥167.97
Details
制造商零件编号 FIT0193
BREADBOARD GENERAL PURPOSE PTH
DFRobot
¥25.64
Details
制造商零件编号 ED281DT
CONN IC DIP SOCKET 28POS TIN
On Shore Technology Inc.
¥3.83
Details
制造商零件编号 PPTC161LFBN-RC
CONN HDR 16POS 0.1 TIN PCB
Sullins Connector Solutions
¥7.33
Details
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum