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
制造商零件编号 C317C220J2G5TA
CAP CER 22PF 200V NP0 RADIAL
KEMET
制造商零件编号 860010372006
CAP ALUM 100UF 20% 16V RADIAL TH
Würth Elektronik
制造商零件编号 A000066
ARDUINO UNO R3 ATMEGA328P BOARD
Arduino
制造商零件编号 181
LCD MOD 32DIG 16X2 TRANSMISV WHT
Adafruit Industries LLC
制造商零件编号 P120PK-Y25BR10K
POT 10K OHM 1/20W PLASTIC LINEAR
TT Electronics/BI
制造商零件编号 FIT0193
BREADBOARD GENERAL PURPOSE PTH
DFRobot
制造商零件编号 ED281DT
CONN IC DIP SOCKET 28POS TIN
On Shore Technology Inc.
制造商零件编号 PPTC161LFBN-RC
CONN HDR 16POS 0.1 TIN PCB
Sullins Connector Solutions
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