Although calculators have been around for thousands of years, electronic ones have been dominating the world for decades. From basic to scientific, calculators come in all shapes and sizes. But in today’s world, where virtually everyone has a smartphone, we have no use for them. That doesn’t mean we don’t like them or care for them anymore. So let’s pay tribute to them by making our own basic calculator with Arduino.
What you will need to complete this project:
- Arduino-based board (I used an UNO)
- LCD 1602A liquid crystal display
- 4x4 button keypad
- Potentiometer, 1-10Kohm
- Resistor, 200-1000 ohm
- Jumper wires
Before We Begin
To be able to compile this program, you will need to have both the LiquidCrystal.h and Keypad.h libraries installed in your Arduino IDE. You can do this in one of two ways. If your Arduino IDE is version 1.6.2 and above, simply use Library Manager. If you are using an earlier version, you will need to copy those libraries into the libraries folder of your Arduino IDE install location. So to make things simple and short for this article, here's a link explaining how to install libraries.
This simple device starts with a cleared LCD screen and waits for key input from the keypad. It forms numbers out of keys entered by the user. As soon as the user presses an operation button, it memorizes the first number and operation desired and continues the acquisition of the second number. When the user is done inputting the second number, after pressing the equals button on the keypad, the program performs the requested operation and prints the result. After that, it sits still and waits for the CLEAR button (’C’) to be pressed so it can start over. (The user can also reset the program at any point in time.)
The Arduino IDE has a built-in library (LiquidCrystal.h) that supports LCDs based on the Hitachi HD44780 chipset (and/or ones that are compatible with it). Other than displaying text on an LCD, the library can also handle printing floating point numbers to a specified amount of decimal places, which makes things easier for the developer. For example:
This will print 3.1415 on the LCD where 4 represents 4 decimal places.
The LCD in this example uses 4-bit data transfer Pins D4-D7 (11-14 on the board). The potentiometer acts as a voltage divider and controls contrast of the displayed text. Its middle pin connects to Pin V0 (pin3) of the display.
Most projects other than blinking LEDs (output-only-based projects) will require some kind of input from a user. In many cases, buttons are used for user input acquisition. There is a library for Arduino Keypad.h (if you don’t have it, check the links at the end of this article) that is capable of handling a button matrix and is simple to use. This library eliminates the need for external pull-up resistors because it enables on-chip integrated pull-up resistors, and it also handles/sets high impedance on all unused column pins. It basically scans column by column. It does so by setting the current column pin LOW and reads pin values of rows for that column, and then jumps to next column etc… until it scans all connected/assigned pins. Besides pull-ups, the library also handles button debouncing. The library doesn’t use delays; instead, it periodically uses a built-in Arduino millis() function and determines how long the button has been pressed or if there was a transition on a specific key. Without delays, the code executes more efficiently and doesn’t consume processing power by eliminating the need for debouncing with software delays.
I wanted to use only one side of the Arduino's Pins 0 to 13 since it’s the exact number of pins needed (and it would be simpler to connect all the wires on one side and not have spaghetti wire salad). But after few tests, the LED on Pin 13 was irritating so I decided not to use Pin 13. I also left Pins 0-1 unused for serial port testing purposes. I moved the LCD to use Pins 7-12, the keypad to use Pins 2-5, and analog pins A2-A5 for rows and columns. So you can connect this at your convenience; just make sure you split rows and columns. Either connect for rows Pin A2-A5 or Pin 2-5 and for columns connect the remaining for wires to the opposite side of Arduino board. So if you connect row 1 wire to Pin A2, then connect column 1 to Pin 2.If you would like to test your keypad or play with it, there is a simple code included in the code package that will help you do this. Simply download and burn the code to your Arduino board with the keypad attached to it.
I didn't have a keypad and I didn't want to wait a month for it to get delivered from China, so I made one myself. It's shown in a picture below. If you plan to do this, you will need:
- 16 buttons
- Small PCB proto board
- 8 wires (4 for row and 4 for column leads)
- Some solder and a soldering iron
The code is comprised of three loops. The first loop scans the keypad for keystrokes and prints them on the display one key at a time. At the same time that it shifts the previous number one decade up, it adds a new number to the first decade. This goes on until the user hits one of operator keys or resets by pressing ‘C’. Then the program breaks the first loop and jumps into the second one.
The second loop is basically the same as the first one but it only waits for equal key ‘=’ to be pressed. At that point, it calculates the total based on the operator selected, prints the result, and continues to the next and final loop.
In the third loop, the program just waits for the ‘C’ button on the keypad to be pressed. When the 'C' key is pressed, it restarts the program.
The code could be optimized, but I wrote it this way so a beginner audience can follow the code quickly and get the idea of program flow (and not get stuck analyzing tightly-packed code).
Now that we're done with hardware assembly and code explanations, it’s time to burn code.
If you don’t want to go through the trouble of connecting a keypad to this project (or you don’t have one or don’t want to build one), you can use your Arduino serial monitor instead. You can do this by changing a few lines of code:
Conclusion and Useful Links
Although this project is a simple calculator made with an Arduino, it mainly explains how to use a keypad to acquire characters and form a whole number out of individually entered characters.
It also explains how to control an LCD connected to an Arduino and combine the two into a functional calculator. This program is limited by the Arduino's platform variables and math, so don’t expect too much from it— Arduino has limitations when it comes to big numbers and floating point. For example, when it comes to floating point numbers, you have float and double. Double should have bigger precision than float, but on Arduino that is not the case. So using double instead of float will not give you higher precision unless you are using an Arduino Due.
Making a more complex calculator that would handle bigger numbers and a longer floating point is possible but is out of the scope of this article. For those of you that are interested in bigger numbers, there is a library (BigNumber.h, actually C++ class) that can handle big numbers, accessible via this link. And when I say big numbers, I mean you can do calculations until you run out of memory. So if you like big numbers and want to test the limits of your Arduino board, you should definitely check out that thread.
As for your keypad library, if you want to know how it works in-depth, you should check out this link and see its possibilities.
All in all, I hope you enjoy making this and have as much fun with it as I did.