Skip to content
All routes operational · 99.97% uptime

How to use 2.8 inch TFT display with Arduino for calculator project?

About the authoradmin
Published by BulkSMS Services

To use a 2.8 inch TFT display with Arduino for a calculator project, you need to connect the display via SPI, install the right libraries, and write code that handles both the graphical interface and the button inputs. The most common display for this is the ILI9341-based 2.8-inch TFT module, which typically runs at 240x320 pixels and uses a 5V or 3.3V logic level. For a calculator, you’ll map out a grid of buttons on the screen, capture touch input (if it’s a resistive touch version), or use physical push buttons connected to the Arduino. The key is to treat the display as a canvas where you draw numbers, operators, and results, while the Arduino processes the math. Let’s break down the hardware, wiring, software setup, and coding specifics so you can build a functional calculator without guesswork.

Hardware Requirements and Specifications

The 2.8 inch tft display module for arduino typically uses the ILI9341 driver chip, which supports SPI communication at speeds up to 10 MHz. The module itself consumes about 50-80 mA at 5V, depending on backlight brightness. For a calculator, you’ll need an Arduino Uno, Mega, or Nano—Uno is the most common. The display’s pinout usually includes: VCC (5V), GND, CS (chip select), RESET, DC (data/command), MOSI, MISO, SCK, and optionally LED (backlight control) and T_IRQ (touch interrupt if resistive touch is included). The SPI pins on Arduino Uno are: MOSI (pin 11), MISO (pin 12), SCK (pin 13). CS can be any digital pin, typically pin 10, and DC is often pin 9. RESET can be tied to Arduino’s reset pin or a separate digital pin like pin 8. If your module has a resistive touch controller (like the XPT2046), it uses additional SPI pins or shares the same bus with a different CS pin.

Wiring Diagram and Pin Assignments

Here’s a proven wiring table for the 2.8-inch TFT with Arduino Uno. Use female-to-female jumper wires for prototyping. Keep wires under 20 cm to avoid signal degradation at higher SPI speeds.

TFT Display PinArduino Uno PinNotes
VCC5VSome modules work at 3.3V, but 5V is typical for backlight
GNDGNDCommon ground
CSDigital 10Chip select, can be any digital pin
RESETDigital 8 or Arduino RESETIf tied to Arduino RESET, display resets with board
DCDigital 9Data/Command control
MOSIDigital 11Master Out Slave In
MISODigital 12Master In Slave Out (optional for read operations)
SCKDigital 13SPI clock
LED3.3V or PWM pinBacklight control; 3.3V for full brightness, or PWM for dimming
T_IRQ (if touch)Digital 2Touch interrupt, optional

For the touch controller, if present, it uses the same SPI bus but with a separate CS pin (e.g., pin 4). The touch controller’s MOSI, MISO, SCK are shared with the TFT’s SPI lines. The T_IRQ pin signals when a touch is detected, which you can use to trigger an interrupt. Without touch, you’ll need external push buttons—say 12 buttons for digits 0-9, decimal point, equals, and four operators (+, -, *, /). That’s 16 buttons total. You can use a 4x4 matrix keypad to save pins, or wire each button to a digital input with pull-up resistors. A matrix keypad uses 8 pins (4 rows, 4 columns) and is scanned in code.

Software Setup and Libraries

You need two libraries: Adafruit_GFX (for graphics primitives) and Adafruit_ILI9341 (for the display driver). Install them via the Arduino Library Manager. For touch, add the XPT2046_Touchscreen library if your module uses that chip. The Adafruit_ILI9341 library is optimized for SPI and supports 16-bit color (565 format). The display’s resolution is 240x320 pixels—that’s 76,800 pixels total. Each pixel requires 2 bytes of data in 16-bit color, so a full frame buffer would be 153,600 bytes, which exceeds the Uno’s 2 KB SRAM. Therefore, you cannot use a full frame buffer; you must draw directly to the display using the library’s immediate mode functions. This is fine for a calculator because you only update small areas (like the result line) instead of redrawing the entire screen.

For the calculator interface, you’ll design a grid of buttons. A typical layout: 4 rows of 4 buttons (12 digits + decimal, equals, and four operators). Each button can be 50x40 pixels, with a 5-pixel gap between them. That fits within 240 pixels width (4 buttons * 50 px + 3 gaps * 5 px = 215 px, leaving margins). Height: 4 rows * 40 px + 3 gaps * 5 px = 175 px, leaving space at the top for a result display area of about 100 pixels. The result area can show up to 10 characters in a large font (say 24-point). The Adafruit_GFX library supports custom fonts via the setFont() function, but for simplicity, use the built-in 5x7 or 8x13 fonts. For a calculator, you’ll want a larger font for the result—you can use the FreeSans12pt or FreeMono12pt fonts from the Adafruit GFX Fonts library.

Code Structure for the Calculator

Your code needs to handle three main tasks: drawing the UI, capturing input (touch or button), and performing calculations. Here’s a skeleton with high-density details. First, initialize the display in setup():

#include
#include
#include
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

In setup(), call tft.begin() and tft.setRotation(1) to set landscape orientation (320x240). For a calculator, portrait (rotation 0) is more natural because it mimics a phone screen. Set rotation to 0 for 240x320 portrait. Then clear the screen with tft.fillScreen(ILI9341_BLACK).

Draw the result area: a rectangle from (0,0) to (240, 80) filled with dark gray, and a border. Use tft.fillRect(0, 0, 240, 80, ILI9341_DARKGREY). Then draw the button grid. Define a 2D array for button positions and labels. For example, buttons[4][4] with labels: “7”,”8”,”9”,”/”, “4”,”5”,”6”,”*”, “1”,”2”,”3”,”-”, “0”,”.”,”=”,”+”. Each button is drawn as a filled rectangle with a border, and the label is centered using tft.setCursor() and tft.print(). Use tft.drawRect() for the border and tft.fillRect() for the fill. For button colors, use ILI9341_BLUE for digits, ILI9341_RED for operators, ILI9341_GREEN for equals, and ILI9341_YELLOW for clear (if you add a clear button).

Touch Input Handling

If you use the resistive touch overlay, the XPT2046 controller returns raw X and Y values (0-4095). You need to map these to the display coordinates. Calibration is crucial: touch the four corners and record the raw values. Then use map() to convert raw to pixel coordinates. For a 240x320 display, typical raw ranges are 200-3800 for X and 200-3800 for Y, but they vary. In the loop(), check if a touch is detected via ts.touched(). If yes, read the point, map it, and then determine which button area the touch falls into by comparing the pixel coordinates with the button rectangles. For example, if the touch is between 90 and 130 pixels in Y and between 0 and 60 in X, that’s the first button in the second row. Execute the corresponding action: append digit to a string, set operator flag, or compute result. Use a string buffer like String input; to store the current number. When “=” is pressed, parse the string, perform the operation using float arithmetic, and display the result.

Physical Button Matrix

If you opt for physical buttons, wire a 4x4 matrix keypad. Connect the row pins to digital outputs (e.g., pins 2,3,4,5) and column pins to digital inputs with internal pull-ups (e.g., pins 6,7,8,9). In the loop(), scan each row by setting it LOW and reading the columns. Debounce with a 50 ms delay. Map each button press to a character. The code is simpler than touch because you don’t need calibration. The downside is more wiring and less flexibility for UI changes. For a calculator, a matrix keypad is reliable and uses only 8 pins. You can also combine: use touch for the display buttons and physical buttons for power or reset.

Performance and Memory Considerations

The Arduino Uno has 2 KB of SRAM. Your code must be lean. Avoid using the String class; use char arrays instead. For example, char input[16]; to hold up to 15 digits plus null terminator. The display draws at about 10-15 frames per second when updating a 50x40 pixel button. That’s fast enough for a calculator. The SPI clock speed is set by the library to 8 MHz by default, but you can increase it to 24 MHz by modifying the library or using SPI.beginTransaction() with a custom speed. However, keep in mind that long wires reduce maximum speed. For the calculator, 8 MHz is sufficient because you only update small areas.

Data for Button Layout and Font Sizes

Here’s a precise layout for a 240x320 portrait display. The result area is at the top: from y=0 to y=80. The button grid starts at y=90. Each button is 55 pixels wide and 45 pixels tall, with a 5-pixel gap. That gives 4 columns: 55*4 + 5*3 = 235 pixels (fits within 240). Row height: 45*4 + 5*3 = 195 pixels, ending at y=285. That leaves a 35-pixel margin at the bottom for a status bar or extra buttons like “C” (clear) and “CE” (clear entry). For the result text, use a 24-point font. The Adafruit_GFX setTextSize() function scales the default 5x7 font. A size of 4 gives 20x28 pixels per character, so you can display about 10 characters in 240 pixels (240/20 = 12, but with spacing). For better readability, use the FreeSans18pt font from the GFX Fonts library. That font is 18 points, which is about 24 pixels tall and 14 pixels wide per character, allowing 17 characters. The library includes these fonts in the Fonts folder. Include them with #include and call tft.setFont(&FreeSans18pt7b). Note that these fonts use more flash memory (about 10 KB each), but the Uno has 32 KB, so it’s fine.

Common Pitfalls and Fixes

One frequent issue is the display not initializing. Check that the RESET pin is connected properly. Some modules require a hardware reset by pulling the RESET pin LOW for 10 ms then HIGH. The library does this automatically if you pass the RST pin. If you tie it to the Arduino’s RESET, the display resets when the Arduino resets, which is fine. Another issue is garbled text or lines. This is usually due to loose SPI connections or incorrect pin assignments. Double-check that MOSI goes to pin 11, SCK to pin 13, and CS to your chosen pin. If you use a 5V Arduino with a 3.3V display, you need a level shifter on the SPI lines. Most 2.8-inch modules are 5V tolerant on the logic pins, but check the datasheet. The DM-TFT28-105 module is designed for 5V, so it’s safe. For touch, if the screen registers touches in the wrong location, you need to calibrate. Write a simple calibration sketch that draws crosses at the four corners and prints the raw values to the Serial Monitor. Then use those values in the map() function.

Advanced Features for Your Calculator

You can extend the calculator with memory functions (M+, M-, MR, MC) by storing a float in EEPROM. Use the EEPROM.h library to save the memory value across power cycles. Add a backlight control using PWM on the LED pin. Connect the LED pin to digital pin 5 (PWM-capable) and use analogWrite(5, brightness) where brightness is 0-255. This allows dimming the display to save power. You can also add a splash screen at startup: draw a logo or “Calculator v1.0” for 2 seconds. For sound feedback, connect a piezo buzzer to pin 3 and play a short beep on each button press. Use tone(pin, frequency, duration). The frequency for a click is 1000 Hz for 10 ms. These additions make the project more polished and demonstrate deeper understanding of Arduino peripherals.

Power Supply and Stability

The 2.8-inch TFT draws up to 100 mA with the backlight at full brightness. The Arduino Uno’s 5V regulator can supply 500 mA, so it’s fine. But if you use a battery, use a 9V battery with a 5V regulator or a 5V USB power bank. The display’s backlight is the biggest power drain. You can reduce it to 50% brightness and still see clearly indoors. For a calculator, you don’t need high brightness. Measure the current with a multimeter: at 50% brightness, the module draws about 40 mA. The Arduino itself draws about 50 mA, so total is under 100 mA. A 2000 mAh power bank can run it for 20 hours continuously.

Testing and Debugging

After wiring, upload a simple test sketch from the Adafruit ILI9341 examples (graphicstest). This verifies the display works. Then test touch by uploading the touchtest example from the XPT2046 library. If you use physical buttons, write a sketch that prints the button pressed to the Serial Monitor. Once both work, combine them. For the calculator logic, test edge cases: division by zero (display “Error”), overflow (result > 999999999), and decimal point handling (only one decimal point per number). Use isnan() to check for invalid results from float operations. Display “Error” on the result area and clear the input after 1 second. These details make the calculator robust and user-friendly.

Ready to put this into production?

Spin up a workspace in under 15 minutes — 100 SMS credits on us, no card required.

Get a Free Trial →