Phi-3 shield


This is one of the most versatile shields on the do-it-yourself electronics market! As you may have guessed, this is the third major release of my phi-shield, a shield intended for beginners and advanced users to integrate user interactions to your Arduino projects. In 2010 I designed the Phi-1 shield, a shield with 16X2 character LCD, buttons, and other accessories to meet the market demand for LCD shields. Since then, lots of LCD shields have appeared on the market, including my Phi-2 shield, a revision of Phi-1 shield, in 2011, and Phi-2 20X4 shield, the very first 20X4 LCD shield in the market, in late 2011. To make the shields easy to use I wrote lots of sample projects including GPS logger, Morse code trainer, alarm clock etc. I have also released open-source libraries phi_interfaces and phi_prompt to simplify menu creation and generic user interaction. Over the past few years, I have revised Phi-2 shields and it has been the only 20X4 shield in the market that has this level of support. In 2016, I have decided to design a Phi-3 shield to give the phi-shield a major update. Using experience from other projects and the trend of current DIY electronics market, I completely redesigned the shield and now I am bringing to you the Phi-3 shield!

This shield is intended for an Arduino MEGA2560, although you can still use it on an Arduino UNO. I’ve taken the advantage of the more pins and more serial ports on MEGA to make the shield more versatile.



Here is a video of me navigating through the alarm clock program’s menu:

Here is a video of me explaining the components of the shield:

Here is a video of me explaining the different kits you can buy:

Assembling modules to the shield:

List of features:

The following hardware are provided by the shield:

  • 20X4 LCD with back light on/off control
  • Six buttons (up/down/left/right/B/A)
  • Two LED indicators
  • Speaker
  • MicroSD card slot
  • Real-time clock (DS3231)
  • EEPROM (32KB 24LC256)
  • Connector for Adafruit Ultimate GPS module or Bluetooth module
  • Stacking headers for easy access to all pins.
  • Recessed board right edge for easy access to MEGA’s 18X2 pin headers on the right side.
  • Reset button

The following software functions are provided by various supporting libraries:

  • User-selectable menu (LCD + buttons)
  • Number and text entry (LCD + buttons)
  • Scrollable long text (LCD + buttons)
  • Date and time (DS3231 or GPS)
  • Location (GPS)
  • Data and configuration storage (MicroSD card and EEPROM)
  • Playing simple tones (speaker)
  • Indicators (LEDs)
  • Wireless connection (Bluetooth module)

There are three tiers of Phi-3 shield kits: kit0, kit1, and kit2, none of which includes a GPS module.


Where to buy:

Buy directly from me:

You can place an order right here for a kit or follow the link below to visit online stores to make your purchase, with more options and purchase other hardware I sell:

kit0 Kit 0 out of stock (no sd, rtc or LCD)

kit1 Kit 1 out of stock (MicroSD + DS3231 RTC, no LCD)

kit2 Kit 2 out of stock (MicroSD + DS3231 RTC + LCD)

Buy from online stores:

There are more options you can buy at online stores but you do need to register at some of these stores.

Please click this link to redirect to the “buy” page for where to purchase this hardware.

Parts list:

The following table contains the content of each kit:

Description Kit0 Kit1 Kit2
SD card board 0 1 1
DS3231 and EEPROM 0 1 1
I2C LCD 20X4 0 0 1
4-pin jumper wires 1 1 1
Printed circuit board 1 1 1
Push button 6 6 6
Push button (RESET) 1 1
3mm LED (random color) 2 2 2
Standoff 3 3 3
M3 Hex Nut 3 3 3
M3 Screw 3 3 3
330 Ohm Resistor 3 3 3
Magnetic Transducer 1 1 1
10-pin Stacking Header 1 1 1
8-pin Stacking Header 5 5 5
6-pin Stacking Header 4 4 4
Right-Angle male header 1 1 1
2X3 stacking header 1 1 1

Kit0 includes the basic kit without the LCD, MicroSD card slot, or DS3131/EEPROM. You can purchase an I2C LCD with your favorite color or use your existing hardware, or install DS1307 RTC if you want.

Kit1 includes Kit0, MicroSD card board, and DS3131/EEPROM. The MicroSD card board and DS3231/EEPROM have been tested against flaws. You can purchase an I2C LCD with your favorite color.

Kit2 includes Kit1 and a yellow/black I2C LCD that has been adjusted and tested.

Project ideas:

  • Standalone or PC data logger
  • Lab data acquisition system (Physics, Chemistry, Earth science etc.)
  • Weather station
  • Input or operating panel, like security panels or garage door opener
  • Handheld GPS
  • Alarm clock (see complete project code)
  • Tweet update display
  • Morse code trainer (see complete project code)
  • The list goes on…

Arduino Pin Usage

The following Arduino pins are used or potentially used by the shield:

Arduino pin Phi-3 shield Comment
2 Button A Can cut trace and use other pins
3 Button B Can cut trace and use other pins
4 Button R
5 Button D
6 Button U
7 Button L
10 SD_card_chip_select
16 TX2 Lined up with GPS Adafruit Ultimate GPS module
17 RX2 Lined up with GPS Use two jumpers to connect
50 MISO SD card
51 MOSI SD card
52 SCK SD card
59 A5 Lined up with LED0 Use jumper
60 A6 Lined up with LED1 Use jumper
61 A7 Lined up with SPKR Use jumper
Reset Button for reset


The shield comes with standard stacking headers for you to access all Arduino MEGA2560 pins (except for the 18X2 header on far right).

The shield also comes with six additional headers for various functions. The connections to the two LEDs and the speaker are on the “Access” header near analog inputs A5-A9. You can easily connect LEDs to A5 and A6 and speaker to A7, using jumpers or just small piece of hookup wires.

The buttons A and B are connected to both pins 2, 3 and to the “Access” header. If you really need these two Arduino pins for external interrupts, you may cut the traces and reroute these buttons from the pins A and B on the “Access” header to other Arduino pins.

The “MicroSD” socket is located in the middle of the board and should match the pin arrangement of very common MicroSD card breakout boards. You will need to bend a 6-pin stacking header’s pins 90 degrees before soldering the header on (see photo). Have some double sticky foam tape below the breakout board for additional stability.

There are two sets of identical header locations for the real-time clock/EEPROM module. The module should hang below the board so its header should have its pins bent 90 degrees and installed below the board. This is a very common pin arrangement. The second set of header location can be used to gain access to the square wave pin so you may use this pin to wake Arduino.

The LCD header (4-pin right-angle male) should be installed below the board since there is no space above. If you get your own I2C LCD, be very careful with the pin out as different I2C LCDs have different pinouts. If you get the LCD from me, then do a direct connect, i.e. the top pin on the header connects to the top pin on the I2C LCD.

The GPS header is next to the TX and RX pins on Arduino. You can easily connect TX and RX to Arduino MEGA RX2 and TX2 using short jumpers. The rest of the pins don’t need to be connected.

The GPS/BT socket is for you to solder your GPS module or Bluetooth module to the board. The GPS module is a bit large. Its top pin (3.3V) will hang over the edge of the board. We don’t need that pin.

If you use a 4-pin BT module, your RX will be connected to the TX vice versa. So make sure on the GPS breakout header to connect TX to an Arduino’s TX pin and RX to an Arduino’s RX pin.

0 LED0 0 32K 0 GND
2 Speaker 2 SCL 2 SDA
3 N/C 3 SDA 3 SCL
5 BTN A 5 GND GPS/BT socket
0 EN
MicroSD GPS breakout 1 VBAT
0 CS 0 PPS 2 FIX
1 SCK 1 GND 3 TX
2 MOSI 2 RX 4 RX
4 VCC (5V) 4 FIX 6 VIN
5 GND 5 EN 7 PPS

Components and layout

Most of the components are on top of the board (solid line). There are two components below the board (dashed line).



The I2C LCD that comes with Kit2 is based on PCF8574. All my code should be able to run on it without problems. If you want to get your own I2C LCD, it doesn’t have to be any special type as long as you can find the library and pinout. If you wish to use the menu system provided by phi_prompt library, you will need to find I2C LCDs that are supported by NewliquidCrystal library written by Francisco Malpartida:

The most common I2C LCDs are based on PCF8574, same as the one that comes with Kit2. The following is a picture of this LCD. Notice the blue square (potentiometer) and blue rectangle (jumper for back light):


Figure: I2C LCD and MicroSD board

MicroSD card board:

The MicroSD card board that comes with Kit1 and Kit2 can plug directly into the MicroSD card header. The header is a 6-pin female stacking header. You need to bend its pins to 90 degrees to make the connection. See figure above. If you get your own board, make sure the pin outs are exactly the same.

Please refer to the picture of the board, which is very common.


I am also using a very common DS3231/EEPROM board in Kit2 and Kit1. See the picture below:

746-08 sku082052j

Figure: DS3231/EEPROM and GPS modules

The socket of this board is a 6-pin female stacking header. You also need to bend its pins 90 degrees and solder it below the board so this module can hang below the shield board.


The pin out for the GPS module matches Adafrtuit’s Ultimate GPS module. Refer to the picture. The module is not included in any kits and must be purchased from Adafruit or its distributors. The GPS is not a required component. With the GPS, you can log location and time.

To connect the GPS to Arduino serial port Serial2, insert jumpers between TX2 and RX, and RX2 and TX. If you connected a Bluetooth module that has RX and TX swapped (compared with GPS’s markings), insert jumper between TX2 and TX and RX2 and RX. You need one of them to not short-circuit the other.


Figure: GPS/BT header

Other hardware

To connect the LEDs to Arduino pins, insert a jumper between the Access header’s L0 and L1 pins and Arduino pins. In the following picture, L0 is connected to A5, which is right below L0. L1 is connected to A6 and the speaker is connected to A7. You can easily make a jumper out of the LEDs’ legs after you solder the LEDs to the board and trim the legs off.


Figure: LEDs, speaker, Access header, resistors and buttons B and A.

If you want to reassign buttons A and B to other Arduino pins, cut the traces here:


Figure: Traces of buttons B and A are right below Arduino pins 3 and 2.

Then you can jump them to other Arduino pins from their pins on the Access header.


The following order of assembly is recommended:

  1. Arduino’s stacking headers (five 8-pin headers and one 10-pin header) with GPS/BT header, and Access header. Insert them and flip the board upside down. Before you solder, make sure the header is vertical instead of at an angle. Only solder one to two pins on the header to tack it. Tack all headers and then examine whether they are good. If not, reflow one of the tacked pins at a time to fix their positions. Then solder the remaining pins. You don’t need the long pins on the GPS/BT header or the Access header. Carefully trim off the pins. Make sure you don’t mistakenly trim off a pin on the Arduino stacking header.
  2. The kit comes with two identical LEDs of random color. Test them to see if you like the color, with the included 330 Ohm resistors. They are very bright but by declaring the corresponding Arduino pins as INPUT, you can drive them dimmer, more like an indicator. The LEDs have polarity. First identify the longer leg on the LED. Next identify the hole on the board with a “+” sign next to it. The long leg should go into the hold with the “+” sign. Bend the legs once you insert them so they won’t fall back out of the hole. Resistors have no polarity. Bend the legs of the two resistors as well. Trim the legs after soldering. Save the LED legs to make jumpers.
  3. The speaker also has polarity. A “+” sign is marked on its top and should match the “+” sign on the board. Attach the last resistor next to the speaker. You can either hold the speaker while soldering or turn the board upside down and let the speaker rest on your table top. It won’t stay flush with the board but that won’t be a problem.
  4. Insert the buttons. The reset button is the one with a short plunger. The rest either have longer plungers or caps to make them stand above Arduino’s stacking headers. Make sure they are secure before soldering on the back side.
  5. Take the 4-pin right-angle male header and insert it into the I2C LCD pins from below the board. Solder on the top side of the board.
  6. (Kit2, Kit1) Take a 6-pin header and bend its pins 90 degrees before inserting into one of the two RTC/EEPROM headers FROM BELOW the board. Solder on the top side of the board. Trim the pins. Insert the module into the header.
  7. (Kit2, Kit1) Take a 6-pin header and insert it into the MicroSD board. Then bend the header’s pins 90 degrees before inserting them into the holes. Solder on the back side. You can use some foam double-sticky tape to secure the board before soldering.
  8. (Optional) Solder either the GPS module or the BT module to the GPS/BT header.
  9. Attach the standoff on the board with screws on top left, top right, and bottom left.
  10. Connect I2C LCD using the 4-pin jumper cable.
  11. Run the test code and adjust the LCD contrast to see the text. Then Secure the LCD on standoff.
  12. Tuck the jumper wire below the board. You can wrap around the RTC module.

Test code

Install libraries

The following libraries are needed. For libraries on, you mostly have to download the zip file and upzip into your Arduino sketchbooks/libraries folder with proper folder names such as sdfat instead of sdfat-master. Some libraries can be added to Arduino IDE via the library manager and they are indicated next to their names. No need to go to their webpage to download.



Adafruit_GPS (install directly from Arduino library manager):




Restart your Arduino (close all Arduino windows first).

Install test code and alarm clock project code

The code is here:

Download the code and unzip in Arduino sketchbooks folder.

Restart your Arduino (close all Arduino windows first).

Flow of the test code

The test code tests all functions of the shield. You will need to make sure you adjusted your LCD’s contract to see the text on screen. The code does the following:

  1. It displays a long message. You can scroll it with up/down and dismiss it with B or A.
  2. It displays a sample menu with six items. Use up/down to navigate through the menu and press B to select an item. Your selection will be displayed (0-5).
  3. It displays a number entry with a default value of 40000. Use left and right to select which digit to modify and up/down to modify the digit. Press B to confirm. Your number will be displayed and saved to SD card. The file name is LOG.TXT. The time stamp of the file will come from either the RTC or GPS, depending on the value of use_GPS. The code will restart.

Menus, number entries, and scrollable text

The code is quite self-explanatory. You can try and modify the code to see what happens. The menu and number entry are extremely easy to do, thanks to my phi_prompt library.

Scrollable text

All you need to do is to call simple_text_area() function and include the text in the parenthesis. The function will return when the user dismisses the message with B or A.

// Displays a long message

simple_text_area(“This is a sample code for displaying information, menu, and collecting user inputs on phi-3 shield with phi_prompt library.\nAuthor: Dr. Liu\nDate: 2017-02-17”);


Menu is also very easy. Define a variable ret_val to store return value. Call simple_select_list() function with the content of the menu. Each item is ended by a “\n” including the last item. The first item is treated as menu title and will always be displayed on the top line. The return value ranges from 0-5 for the following menu that has 6 options.

int ret_val=255;

ret_val=simple_select_list(“Main menu:\nDisplay GPS info\nRecord GPS info\nErase data\nDisplay records\nParameters\nShow credit\n”);

Number/text entry

This is not too hard either. You first define a user_input as long integer if you want number entry. Then you define a char string to hold the initial value, which will turn into final value when the user confirm with B. Print a prompt with lcd.print(). Then call simple_input_panel(). The function needs the buffer’s name, and the lower and upper limits of the characters that are allowed. In the following example ‘0’ and ‘9’ limits the entry to be only number. Once done, call sscanf() to turn the text into number and store in user_input.

long user_input;

char input_buffer[]=”40000″;


lcd.print(“Enter 5-digit:”);



Leave a Reply