This is the first ever Arduino Text-based User Interface library ever developed to handle text-based interactive user interface  on 16X2 to 20X4 character LCD and up to six buttons. This is the second release and the next generation to the original phi-menu, which I developed some time ago. The library is developed for my phi-2 shield but should work on other hardware with minimal modification.

->Click here to link to my online store to get a phi-2 shield<-

With this library, you can ask user to input numbers, select from a list, or enter a string, which you can use to steer your program execution (menu) or modify how your program runs (parameters such as RPM, delay, brightness), or even enter a file name (with input panel) for logger projects with SD cards.

Typical use for phi_prompt is:

Asks user to update operating parameters (input numbers, select from list)

Asks user to select from a list of options, such as different pastas, Months, Days, Yes/No, etc. You may use input integers to accomplish the same function but having text lists is much more user friendly.

Using lists, you can create extensive menus of infinite levels.

Many customizable options and list rendering styles. Potentially supporting multiple displays although I didn’t try it.

The library is not wrapped around in a class so instead of creating an object, you just create a data structure: in the type of phi_prompt_struct, which stores all needed information for the library functions to work.

Projects that use phi_prompt

There are many complete project codes waiting for you to use and study. Since this library was written for the famous phi-2 shield, please visit phi-2 shield home page and read under “Complete projects”.


New 20X4 display phi-2 shield variant is fully benefiting from the update of phi_prompt

One example of using phi_prompt to create a user selectable list:

Here is a play list of phi_prompt examples included in the end of the page:

More videos:


Nov 5 2015:

Library released under GNU GPL V3.0, compatible with Arduino IDE 1.6.0 or higher.

I make regular updates on the library sometimes taking suggestions from library users like you! Please leave comments and suggestions on this page. I will make announcements on my blog every time I make updates. The next update is scheduled to happen around the winter break (Dec 2011 to Jan 2012). New features will include rotary encoder support, analog button support, keypads and more features on select lists.



If you really like this open-source library, please consider donating $5 to the cause!

Project code and documentation:

Library and examples:

Please visit my library and code download page.

Click here


Documentation is included in the release.

Changes in new version 20110523:

Lots of changes have been made since the last release. Please read the updates section of the documentation


The documentation includes 6 examples and the library download has complete example codes.

Example codes:

For Phi-1 shield users, make these changes in the main program:

#define btn_r 3

#define LCD_D7 4

More extensive examples:

For Phi-1 shield users, make these changes in the main program:

uncomment #define phi_1_shield

comment #define phi_2_shield


First download the package, then extract the files under your Arduino Sketchbook/Libraries folder, so that the three files will be under c:/Arduino22/Sketchbooks/Libraries/phi_prompt/ (Just example, your directory may be different)

Then close all Arduino IDE windows.

Reopen Arduino IDE, open a sketchbook you want to use the phi_buttons. Then choose under the Arduino IDE menu Sketch->Import library->phi_prompt

The Arduino IDE automatically creates a line in the beginning of your sketchbook: #include <phi_prompt.h>

OK you’re done!

Using phi_prompt or phi_interfaces library in commercial products:

The libraries are free for personal use. If you want to integrate the libraries in a product that you will sell for money, please obtain a license for $30, which covers the current and all future updates of both libraries. This purchase grants you license to both phi_prompt and phi_interfaces libraries. Additional programming assistance can also be purchased at store but please contact me first regarding the type of programming help you need before purchasing.

Buy phi_prompt library commercial license

137 Responses to Phi_prompt

  1. Pingback: Morse code translator new version « Liudr's Blog

  2. Pingback: Phi_prompt new version soon « Liudr's Blog

  3. gamezat says:

    very nice work
    thank you

  4. Pingback: Release Two Workspace (/Fork name TBD) - Page 13 - Fuel Economy, Hypermiling, EcoModding News and Forum -

  5. Alberto Gago says:

    I is really a GREAT work!!

    • liudr says:

      Thanks! You’re not just getting the hardware, my software is the most complete among arduino shields. If you have questions or want to share some success, please come back and post!!

  6. Tim Laren says:

    Great work. Waiting for the hardware.

    On another note, any chance you have thought of using a matrix for the keys? You could have more buttons and use less pins.

    If you have already looked into this and have reasons, it would be great if you shared your findings.

    Thanks, and keep up the great work.

    • liudr says:


      Yes, I’m looking at a solution. Currently the phi_prompt is exclusively developed for the phi-2 shield and the phi-2 shield needs 6 pins for the 6 keys. It’s a simple but a bit costly solution. If I incorporate a key pad, I need at least 9 keys to make it advantage. If I incorporate a typical 12 to 16 key pad, that is going to be 7 to 8 pins. So not very practical for phi-2 shield but could be added to phi_prompt library. Instead, I am developing an alternative solution, that could prove effective, as long as you don’t need two key combos, just one key at a time. This way can save pins drastically, such as 16 keys with only 5 I/O pins and a 595 shift register, or 16 keys and 8 general purpose outputs (LEDs, relays) with 5 I/O pins and 2 shift registers. I’m still working on the code 🙂

  7. Tim Laren says:

    I am still waiting for my shield to get ordered, accounting (wife) is delaying it, all the paperwork and politics… 🙂

    I have started playing around with the code and have not seen how to check for a button press. All I want to do is wait till someone has time to read the screen and press the ‘any key’ (or a specific key).

    Something else I noticed, when in a menu, I press the UP key and it goes up, when entering a number, with a range of, say 1-9, pressing up goes from 0–>9–>8–>7. It seems to me it should go the other way around.

    Also, (get out of here Tim, you are bugging the guy) I see a reference to the buzzer pin but do not see any other reference to using it. All I see is it is set for output. On my test board all it does is click when Arduino is reset. Am I missing something?

    I hope to get the order off this weekend. Thanks for the prior response.

    On another project I did, I used the same 4 data lines as the LCD to scan 16 keys on a keyboard (with an additional 4 lines). All that was required was 4 diodes to prevent the keypad from interacting with the data for the display. It worked well.

    • liudr says:

      Tim, to wait for someone to press a button to continue, use this code:

      while (!wait_on_escape(20))
      This makes arduino wait for any input for 20 milliseconds. If a key is pressed, wait_on_escape() returns a value (1-6). If no key is pressed it returns 0 and !0 is true so the while loop repeats until a key is pressed.

      Oh for the up button function, someone else has complained already 🙂 I will remember to make some changes for next release. Meanwhile if you want, go ahead and change this in phi_prompt.cpp for yourself:

      First open the file and find this line:

      int select_list(phi_prompt_struct *para)

      You will find the following lines:

      case 1:
      if ((para->low.i+1)high.i)) para->low.i++;
      else para->low.i=0;

      case 2:
      if (para->low.i-1>=0) para->low.i–;
      else para->low.i=para->high.i;

      Swap 1 and 2 and you will get what you want! Actually I’m doing it right now so I don’t forget it in the next release..

      For the buzzer, I defined the buzzer pin to be analog 2 or digital 16 so you need to connect that pin to the pin near the buzzer. Make sure you have the right orientation for the buzzer, plus on top. If you swap the polarity you may only hear like a zzz not a buzz.

      BTW, I am traveling this Friday so if you want to order something, tomorrow is much better than later. I’ll be able to wrap your package and have my wife ship it otherwise it will wait until next Thursday.

    • liudr says:

      Oh Tim, if you intend to order something, just reply here so I can reserve the items in a box and then my wife can ship them out after you order, while I’m gone. That’s one week better than have you wait for me to come back. No need to do paperwork on your side 😉

  8. LUCKY SAGOO says:

    i m very impress with this kit but in india kit is not available can i get full circuit diagram and full par list so i can get assemble it here

  9. Jim Ford says:

    I’ve assembled my phi-2 shield kit and run the Phi_2_testing_v2 program, but all I’m getting is black squares on lines 1 and 3 of the LCD and blank lines in 2 and 4 (I’ve tried adjusting the contrast).

    The testing program compiled and uploaded OK, without errors. I’ve also carefully checked over the shield for shorts and dry joints with a watchmakers eyeglass (I’ve been building circuits for many years), but found no problems.

    Before I start doing tedious continuity checks all over the board, do you have any suggestions as to what might be wrong, or can provide ideas for troubleshoot?

    Regards, Jim

    • liudr says:


      I was checking the program and found the pin settings were for phi-1 shield. I must have changed this to update the older phi-1 shield testing program and forgot to change them back. Here is how to change the code:

      #define buzzer 16
      #define btn_u 5
      #define btn_d 10
      #define btn_l 11
      #define btn_r 4
      #define btn_b 14
      #define btn_a 15

      //Phi-2 shield LCD pin setting
      #define LCD_RS 8
      #define LCD_EN 9
      #define LCD_D4 7
      #define LCD_D5 6
      #define LCD_D6 2
      #define LCD_D7 3

      The 2 bold lines are the changes. In your program just make the change and you will be fine. Sorry for the inconvenience and I will upload the right code right away.!

  10. Jim Ford says:

    That was it, ‘liudr’ – works a treat now.

    Thanks for the very quick reply.

    Regards, Jim

  11. Steve says:

    wow I just discovered this library by chance and I’m excited
    I need to write an interface for my project but I’ve been delaying that because it proved harder than I first thought (all accounting for all possible actions and changing the flow of the program) but with this help it should be much much easier 😉
    great, more time to concentrate on the hardware instead! thank you

    • liudr says:

      Exactly! Once you know how to use this library, you can focus on the important part: getting the hardware to work, instead of having “program user interface” always hanging over your head 🙂

      I even took a further step in eliminating the need to program a user interface with some new designs: the phi-panel serial user interface panel. If you want a menu, just print on serial the menu texts and the panel would display it. Then you wait on serial input and if a button is pressed, say ‘3’, then it comes down the serial input so you can respond to it. Check it out:

      Make a menu as easy as this on arduino:

      // Phi-panel with 20×4 display is connected via serial port
      Serial.println(“Menu:”); // Display ” Menu” on line 1
      Serial.println(“1.Display GPS info”); // Display option 1 on line 2
      Serial.println(“2.Record GPS info”); // Display option 2 on line 3

      while(1) {
      if (Serial.available()) { // Make sure there is a key press
      char; // Read key press from phi-panel
      if (response==’1′) display_GPS(); // Display GPS info on LCD
      if (response==’2′) record_GPS(); // Record GPS info on SD card or EEPROM
      break; // Breaks out of the while (1) loop.

  12. Steve says:

    hi again liudr,
    this ability to generate a menu on the fly indeed seems great, I will have to look at it

    btw, what will be the relation between phi_prompt and phi_panel? are they going to be united at some point or they will serve different purposes? I understand that phi_menu is now replaced/succeeded by phi_prompt, but what about the panel?

    • liudr says:

      Hi Steve,

      Thanks for the compliment! The phi_menu was just a part of a project I did. I ripped it off that project and made it into a library, only to see its limitations. So I re-wrote the whole thing and released the library under the name: phi_prompt to remind myself I really wanted to have some DOS-like simple text-based user interface or prompt. Both phi_menu and phi_prompt are software libraries that can run on my phi-2 shields and any other compatible hardware, as long as you have an LCD and a few buttons. Many people made hacks, say with serial LCD, shift register LCD etc.

      On the other hand, the phi-panel (notice the ‘-‘ instead of ‘_’ between phi and panel) is a piece of hardware. It has LCD, keypad, etc. and integrated most of phi_prompt library on the on board microcontroller so you, as a developer, can call limited versions of those phi_prompt functions by printing human-readable commands and texts to the serial port. Say if you want to display a selection list on the panel, you just do serial.print(“\eF”); to tell the panel a list is coming down the serial. Then you print the title of the list and the entire list item by item separated by new line (‘\n’) with serial.print();. Then you end the list with serial.print(“~”); so the panel will immediately render the list, process user keys, and return the choice via serial. This way it is absolutely easy to whip up a menu, just print it out, and wait for user response in terms of a number. On the other hand, it offers no options such as number of columns or rows or width of each item. The panel automatically calculates optimal sizes to display the list. That is the drawback. In the future, I plan to develop separate function calls that gives you full freedom to control every aspect of the list over serial.print(). But again, like MicroSoft thinks, the more options they offer, the more questions they will be asked when people mess up 😉

  13. Steve says:

    and just for the record, for anyone that wants to use the phi_prompt library with custom hardware, it’s more easy that it seems

    the phi_prompt_example_menu_16X2_display.pde example is the best place to start
    you just go to defs.h, in the Phi-2 shield definitions part below the #ifdef phi_2_shield line, and

    1 you enable one of the #define use_3_btn etc according to how many buttons you will use
    2 define which pins the buttons are attached to eg #define btn_u 3
    3 do the same for your LCD eg #define LCD_RS 7 etc
    4 define the behavior of your buttons in the corresponding part of the definitions (according to the number of your buttons) eg phi_buttons btn_1(btn_u, LOW); it means the button ‘up’ will be considered to be pressed if its pin goes to LOW (change to HIGH it you want the opposite)

    the .pde then it should run without any other change and you start hacking it 🙂

    • liudr says:

      Thanks Steve. I will post this to the phi_prompt google code page for anyone interested in using this library on custom hardware. I’m thinking adding matrix keypad support too but the popular keypad library has no repeat function so you will have to press the key many times instead of holding it to repeat. My own library addresses that and is an integral part of the phi_panel hardware. Since I develop both software and hardware/firmware, things can be mixed up. To address that, anything with underscore like phi_prompt, is a software library or program. Anything with a dash ‘-‘ like phi-2 shield or phi-panel is a piece of hardware I designed. I don’t know if that naming convention helps at all. 🙂

  14. Roy wurth says:

    I’m fairly new to the Arduino environment and don’t know what my wisest purchase option would be…. the Phi-2 2004 shield or the 20×4 keypad panel. I’m using the uno (328). I’m assuming by the write-up that I could use either with my Arduino projects. I assume its worth the extra $$ if I get the full interface flexability and can interface to other platforms in the future. Is this a correct assumption on my part? Your thoughts??

    • liudr says:


      Thanks for your interest in the phi-2 shield and the phi-panel. Your assumption is right. The phi-panel is more flexible and only requires two digital pins to operate a 20X4 display, 4 LED indicators, a speaker and sense 16 buttons. You can use this panel with other microcontrollers such as PIC or others or even on a PC if you get a USB TTL converter. On the other hand, the phi-2 shield 2004 only works with the arduino form factor and needs more pins on arduino to operate the LCD and keys. Since there is an on-board microcontroller, the same one that an arduino UNO has, in order to handle all the hardware, the panel is more expensive. But you get all the functions with very easy serial access and you can update the firmware every time I release new functions in new firmware. One thing, assembling the panel takes longer time with more components. The phi-2 shield has a real time clock and other things the panel doesn’t have.

      My original intent for the shield is “all-purpose shield that you can do a lot of different projects on”. I have complete project codes for lots of projects I made with this shield.

      My intent for the panel is “easy panel to handle human machine interface with LCD, keypad and buzzer”. So which one to buy depends on your intended project too. I guess I wasn’t offering much advice 🙂

  15. Pingback: Phi_prompt is upgrading to arduino 1.0 « Liudr's Blog

  16. Jim Ford says:


    Have you produced a version of your Phi-Prompt library to use ‘keija’s NewSoftSerial.h for serial displays? Or do we have to hack your library according to his instructions?

    Cheers, Jim

    • liudr says:


      I have not yet. You are welcome to make the change. I have not touched how I do the LCD commands in the library so the same change should apply. There are just a few more places to replace lcd library with serial. I suggest you use the arduino 1.0 IDE, which has the softserial, the decedent of the newsoftware serial, when doing the hacking.

      As a matter of fact, I am planning to incorporate more output devices in the library. Just like the newly written phi_interfaces library replaced the button library and enables phi_prompt to process buttons, keypads, rotary encoders, serial keypads, etc. as inputs, I will expand this library to incorporate different types of output devices, such as the character lcd, serial character lcd, glcd, serial port, etc as alternate outputs. It’s going to be exciting, only if I have time for it now.

      • Jim Ford says:

        Hi John.
        I’m using the Arduino IDE on Ubuntu Linux. The current version is 0022 and doesn’t have softserial.

        Whilst I have one of your shields, I don’t want to dedicate it to my project and also want to have more pins available.

        I’m struggling with converting the phi_prompt files to use NewSoftSerial. Part of the problem is rather than doing the file conversions ‘by hand’ as in keija’s guide, I thought I’d use the opportunity to get up to speed with ‘bash’ programming and ‘sed’, and automate the conversion. It’s taking about ten times longer than If I’d done it ‘by hand’!

        I’m also having problems with the Arduino Library structure (which I’ve met before!). The ‘phi_prompt’ library as supplied by you I’ve put in ‘/usr/share/arduino/libraries’ as normal, with the examples in a sub-directory ‘examples’. The ‘serial phi_prompt’ library that I created I called ‘phi_prompt_serial’, which I also put in ‘/usr/share/arduino/libraries’ with the converted examples in a sub-directory ‘examples’. The problem is that when I try to open up an example in the ‘phi_prompt_serial’ library with the IDE, it only finds the original ‘phi_prompt’ examples, rather than the serial versions.

        I’ve met this problem before. I downloaded the ‘adafruit’ liquid crystal library to use a serial display and renamed the old library to ‘LiquidCrystal-old’ and installed the new library as ‘LiquidCrystal’ when I went to use the library it still went for the old library. The only way I managed to get around this was to rename the old library to ‘Dummy’!


  17. Bruno says:

    I need to translate the intenal YES/NO prompt in French as OUI/NON how can i do that ?

  18. Bruno says:

    I need to block all the time the setting menu # to not confuse end user and use the display with or without the phi prompt, how can i do that ?

    • liudr says:

      Don’t know what you mean. Try explain another time. Maybe give an example.

      • Bruno says:

        When using phi-panel 4×20 with a keypad hooked there is a key reserved to invoke this menu:

        Main Menu ->1/4
        -> Terminal
        . Settingd
        . Serial address
        . Show Credit

        How to disable this key in firmware or by sending special command, so end user can’t invoke this menu or change setting ?

      • liudr says:

        Understood now. You want to reclaim the escape key for your own use. Alright. I’ll add this to the next firmware update. I’m working on getting everything into arduino 1.0 compatible 🙂

  19. Jim Ford says:

    Hi ‘liudr’

    Forget my post dated 8th March!

    I got ‘my knickers in a twist’ over SoftSerial. I’d fitted a ‘ladyada’ backpack to the LCD I’m using, which uses the modified LiquidCrystal library, also from ‘ladyada’. So I didn’t need ‘NewSoftSerial’ or the ‘SoftSerial’ libraries.

    It works a treat and only needs “LiquidCrystal lcd(0);” to create the lcd object.


    • liudr says:

      Awesome! BTW, I also sell my serial LCD backpack. Adafruit backpack is actually just a port extender so arduino is still doing all the work and the library resides in arduino program space. Mine and sparkfun’s serial LCDs both have on board processors so arduino has more free space and time to handle other stuff. 🙂

  20. Jim Ford says:

    [quote]Awesome! BTW, I also sell my serial LCD backpack.[/quote]

    Yes, it looks like that’s the way I should have gone, but I wasn’t aware of your ‘backpack’. I’ll get one when I need another.

    BTW, what’s the link to the site that creates the big text you use in your comment blocks, please? I had it somewhere in your documentation, but can’t find it now.


  21. Jim Ford says:

    Thanks ‘liudr’

    I went to the site and saw that it’s a front end for ‘figlet’. I installed figlet (and the similar ‘toilet’) on my Xubuntu Linux machine.

    I write my programs using emacs with the screen split to give a shell in a few lines at the bottom. I can now run ‘figlet’ in the shell and copy and paste the output back into the program – it’s very convenient and I don’t have to be online.

    If I could only have one program on a machine it would be emacs. I’ve used it for years and am still stunned by its power and versatility.


  22. Jim Ford says:

    It looks like you can run a figlet clone on a Windows machine – have a look here. (There’s also a version for MSDOS):


  23. dionweston says:

    Is there a core library function that permits emulation of the ‘Escape’ key on a 5 button analogue based key pad. Say for example, if the “Enter” button [char enter_keys[]={“B”};] is held depressed for more than 2-3 seconds, can this be captured ‘as if it were the ‘Escape’ for use by the library? I’m using a DFRobot-07 LCD Keypad Shield.

    • liudr says:

      There is no way to allow hold to be counted as a different key press. You will have to try to modify my library yourself to see if you can achieve that. I don’t really have DFRobot LCD shield neither am I a tech support of that shield. That shield seems to have not much support compared with my own phi-2 shields. As much as I would like to help everyone, I have too much work planned out and that doesn’t include supporting this shield. Good luck.

      • dionweston says:

        Thx Lludr. Well understand you not wishing to provide tech support for this particular shield. It just happened to be the one I had to hand when I came across your library. You’ve been super generous as it is with providing code examples for non-phi-2 applications.

      • liudr says:

        My focus is to produce enough generic library code to help most people here and spare some time to help particular cases. Right now my hands are tied. I’m working on a commercial product using my library for a company that hired me to develop user interface.

        Depending on how that particular shield is designed, you may get lucky with a “two keys” acting as one key. That is again just a guess. You press two keys “simultaneously” and the analog value is outside the range of all 5 analog values and if it is sufficiently far from all values, you may define that as the escape key’s value. The simultaneity is also tricky. If you are able to sacrifice the left button and you can define the escape to be “L” instead. You may also dynamically redefine what key does what function. Say if you want escape in one particular case and you need left for the rest of the case, when you enter this particular case, define escape to be “L” and if you exit this case, define it back to be left.

        If what you are doing is for commercial product, I might be able to consult or program for you, just FYI. The semester is almost over and I don’t teach in the summer. 🙂

  24. dionweston says:

    Excellent to note you’ve had some commercial work supporting you. That’s great.

    Thank-you for the suggestion of dynamic redefinition. That looks like the way to go. And no, it’s not a commercial app I’m working on. Just a GPS back-up NMEA feed, position logger and anchor alarm for my sail boat.

    • liudr says:

      Let me know how the dynamic redefinition goes. I’ve never done that before but I think in principle it will work.

      • dionweston says:

        Will do.

        Tried the following, but result appeared to corrupt later interpretation of the ‘enter’ key.

        // Dynamic resetting of function keys set up for phi_prompt library to make Left key work as ‘Escape’
        char up_keys[]={“U”}; ///< All keys that act as the up key are listed here.
        char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
        char left_keys[]={""}; ///< All keys that act as the left key are listed here.
        char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
        char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
        char escape_keys[]={"L"}; ///< All keys that act as the escape key are listed here.
        char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here for phi_prompt.

        // Reinitialising phi_prompt to use Left key as escape
        init_phi_prompt(&lcd,keypads,function_keys, lcd_columns, lcd_rows, '~');

        int user_input;
        phi_prompt_struct myIntegerInput;

        lcd.clear(); // Clear the lcd.
        center_text("Set Bklight Lvl"); // Prompt user for input
        user_input=(lightLevel-5)/10; // Initialise user_input variable
        myIntegerInput.ptr.i_buffer=&user_input; // Pass the address of user_input to the library.
        myIntegerInput.low.i=0; // Lower limit. The number wraps to 25 when decreased from 0.
        myIntegerInput.high.i=25; // Upper limit. The number wraps to 0 when increased from 25.
        myIntegerInput.step.i=1; // Step size. You will get 0, 1, 2, 3, 4, etc if you set it to 1.
        myIntegerInput.col=4; // Display the number at column 4
        myIntegerInput.row=1; // Display the number at row 1
        myIntegerInput.width=2; // The number occupies 2 character space.
        myIntegerInput.option=0; // Option 0, space pad right, 1, zero pad left, 2, space pad left.

        // If the user didn't press escape (return -1) then update the back light value in the buffer.
        if (input_integer(&myIntegerInput)!=-1) {
        lightLevel = user_input*10+5;
        analogWrite(backLight, lightLevel);

        // Dynamic resetting of function keys set tup for phi_prompt library back to normal
        char up_keys[]={"U"}; ///< All keys that act as the up key are listed here.
        char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
        char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
        char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
        char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
        char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
        char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here for phi_prompt.

        // Reinitialising phi_prompt to normal
        init_phi_prompt(&lcd,keypads,function_keys, lcd_columns, lcd_rows, '~');

        else {

        // Dynamic resetting of function keys set tup for phi_prompt library back to normal
        char up_keys[]={"U"}; ///< All keys that act as the up key are listed here.
        char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
        char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
        char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
        char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
        char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
        char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here for phi_prompt.

        // Reinitialising phi_prompt to normal
        init_phi_prompt(&lcd,keypads,function_keys, lcd_columns, lcd_rows, '~');


      • liudr says:

        How about just redefining the content of left_keys and escape_keys instead of redoing the whole thing?

  25. dionweston says:

    Yes I tried modifying only the lines I thought would impact but got the same outcome. Once the ‘init_phi_prompt() call is made with the remapping the key map gets screwed up. I loose the ‘Enter’ key functionality altogether. So I thought I may have to redefine all the key variables again. Either way the key mapping goes skew-whiff.

    I’ll see if I can debug by printing the ‘&myIntegerInput’ value returned to the monitor. And dig deeper.

  26. dionweston says:

    input_integer(&myIntegerInput) returns ‘-4′ for the left hand key under struct myIntegerInput; so I’ll use that to ’emulate’ the escape key for the time being.

    • liudr says:


      Regarding the redefinition of function keys, what about just this instead of running init routine again?

      strcpy(left_keys,”X”);// X is not used anywhere so there won’t be any match

      For restoring default settings:
      strcpy(left_keys,”L”);// X is not used anywhere so there won’t be any match

      • dionweston says:

        strcpy(left_keys,”X”); // X is not used anywhere so there won’t be any match

        just prior to a phi_prompt structure call results in the following compile errors:

        Menu:162: error: stray ‘\’ in program
        Menu:162: error: stray ‘\’ in program
        Menu:163: error: stray ‘\’ in program
        Menu:163: error: stray ‘\’ in program
        LCD_gps_logger_v1.cpp: In function ‘void top_menu_function_5()’:
        Menu:162: error: ‘u201dX’ was not declared in this scope
        Menu:163: error: ‘escape_key’ was not declared in this scope
        Menu:163: error: ‘u201dL’ was not declared in this scope

      • liudr says:

        You need to retype the double quotation marks. Your system made them into left and right marks, not recognized by arduion.

  27. dionweston says:

    Ah yes – the MacOS text twitch bites again.

    Compile error now:
    LCD_gps_logger_v1.cpp: In function ‘void top_menu_function_5()’:
    Menu:163: error: ‘escape_key’ was not declared in this scope

    So maybe I have a problem with the first initialisation. Possibly having only five keys, not six, defined in the analog_mapping variable? The code I’ve used there is taken from your ‘Template_using_analog_keys.pde’ example, as follows:

    char analog_mapping[]={‘L’,’U’,’D’,’R’,’B’}; // Key map that works for a DFRrobot-007 LCD analogue keypad shield.
    byte analog_pins[]={0}; // The pin numbers are analogue pin numbers.
    int values[]={0, 143, 328, 503, 741}; // Measured DFRrobot-007 LCD analogue switch threshold values
    phi_analog_keypads analog_keypad(analog_mapping, analog_pins, values, analog_buttons_per_row, analog_buttons_per_column);

    // This serial keypad is for debugging.
    phi_serial_keypads debug_keypad(&Serial,9600);

    // The following sets up function keys for phi_prompt library
    char up_keys[]={“U”}; ///< All keys that act as the up key are listed here.
    char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
    char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
    char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
    char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
    char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
    char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here for phi_prompt.

    // The following adds all available keypads as inputs for phi_prompt library
    multiple_button_input * keypads[]={&analog_keypad, &debug_keypad,0};

    • liudr says:

      Sorry I typed in the wrong name. It should be escape_keys. There is an “s” that I was missing.

      • dionweston says:

        Yes that correction enabled a clean compile.

        And the code has the effect intended altering the left key response to emulate the escape function. Only now the right key appears to also have been altered. It now has the same effect as the ‘Enter’ key. It terminates the Integer Input routine, whereas previously it had the same functional effect as the down key.

        Under the yn_dialog routine the remapped left key as escape terminates the dialog routine as expected, but, of course, it is difficult to then capture the ‘Escape’ after closure of the routine to then enable a return to a higher menu level. Interesting that the right key under the yn_dialog routine has the effect of moving the ‘highlight’ to the left (the only other option available of course), at which point that’s as far as it goes. It doesn’t trigger an ‘Enter’ response as occurs under the integer entry routine?

        It looks like I really need to delve into trying to understand how the getKey() call inside wait_on_escape() works with the Analog_keypad interface. In articular how the various menu routines respond to the return through wait_on_escape() from phi_prompt_translate().

        By the way, with an analog keyboard, how does NO_KEYs get transferred to NO_KEY in wait_on_escape()?

      • liudr says:

        Regarding the NO_KEY and NO_KEYs, always use NO_KEY. It’s the external value of no key pressed. NO_KEYs is internal to the keypad sensing routines and is translated by an intermediate layer that developers should not interact, unless they are developing new input functions, say capacitive sensing routines.

        Regarding the problem of switching, what about this way:


        Then to restore:


  28. Jim Ford says:

    Hi ‘luidr’

    I’m using ‘text_area’ in your library for my project. It works fine, but I can’t embed a newline in the text using ‘\n’, as your documentation states. It would be very helpful if I could do so.

    Regards, Jim

    P.S.: I saw an Australian documentary about John Rabe last week. It was very interesting. I think you’d be interested and if you haven’t already seen it and can’t locate it on the net, I can send you a copy. email me.

    • liudr says:


      If you open your phi_prompt.h and read the comments in the beginning, what date of release do you see? I’m sure the new line works but not until a more recent release.

      Yeah, there should be quite a lot of John Rabe’s documentaries out there. I bet most tell the truth of how many Chinese he saved during Japanese raid of Nanjing. Japan still refuses to admit it even now. They instead warship their war criminals every year. A conservative number is 300,000 died in the month-long raid. 30 million Chinese died in the Sino-Japan war 1937-45.

      • Jim Ford says:

        My library release is 20110523, which I think is the current one.

        We in the U.K. aren’t brought up with much information about the Sino-Japan war. I knew there had been major atrocities committed and also that war criminals weren’t prosecuted by the U.S. in exchange for scientific data on the horrific medical experiments carried out on Chinese captives!

        The school where I worked before I retired had quite a few Chinese students. I developed a high regard for them and my experience turned me into something of a ‘Sinophile’!


      • liudr says:


        The new edition of the library is 1.0-pre release. I’m lagging on documentation for the 1.0-formal. Here is the download link:

        Documentation is forthcoming.

        I didn’t know the part where Americans exchanged war criminals for human experimentation results. I was never told in Chinese school I went to and there’s no reason Americans would tell this to its own people so no idea even after I lived in U.S. for some years. I guess if people from different worlds, like the two of us, can talk freely about anything, no governments can shield any truth from us anymore. There is a documentary/movie called “black sun” talking about what Japanese carried out savage experiments (say cut off arms and lags and sew back legs where arms below and etc, or freeze someone and puts him in hot water see how long he lasts etc.) on innocent kidnapped villagers and POWs. To think of it, after knowing the movie for decades, I didn’t realize until now that the sun must be the Japanese flag, which symbolizes the sun but it’s red. The black is just how dark the sun gets. See, the Germans were not allowed to use their Nazi flags after the war but Japan limped on with all the unfinished business of war crimes. Maybe there is a reason they get punished with nuclear disasters. You can’t imagine how glad an average Chinese felt knowing the nuclear plants were going critical. What kind of horror must have Japan done to China to make a mild people hate them so much?! It’d be much more forgivable if they just admit their crimes and make proper corrections. Of course the Americans used Nazi German scientists for all the major advances they got. God knows how many deals they made with the Nazis. Many many Americans died fighting Japanese imperial army in the war and how would their family react to the fact their top enemies go unpunished. Too much trouble in the world. Focusing on Arduino so we can make something constructive 🙂

  29. dionweston says:

    results in a error: invalid conversion from ‘const char*’ to ‘char’

    The Massacre of Nanking, seared into my psyche, is one incident I donlt think even the Japanese deny occurred, although attempts at revision of histrory have seen Japanese apologists playing down the number of people killed by a factor of 10! And they claim of these, most if not all, those killed were Chinese soldiers.

    • liudr says:

      The code should work. The error occurs if you assign a character to the name of a character string, like escape_keys=’X’ or if you assign a string address to a character like escape_keys[0]=”X”;. Notice the double quotation. You should use the single quotation marks so escape_keys[0]=’X’;//Retype the single quotations in arduino since the copy and paste messes up the quotations. If you use double quotations, it means string, not character anymore.

      • dionweston says:

        Yes code works with the single quote mods you point to.

        Out of interest is there a way of curtailing the right hand key from having the same effect as the ‘Enter’ key under the input_integer() method?

      • liudr says:

        That requires modifying the library or writing your own enter_integer. It’s a bit involved.

  30. Jim Ford says:

    Hi ‘luidr’

    This is the sort of thing I read about many years ago:

    In particular – from the last 2 paragraphs on page 5:

    “The Japanese shared some of their secrets with the Americans. The Americans in return granted the Japanese immunity from prosecution for war crimes.”


    • liudr says:

      Thank you Jim. You got to hate the governments but forgive their people. I bet the “Americans” and “Japanese” referred to the governments and those in power. Not everyone benefited from these dirty deals.

  31. Jonathan says:

    so I bought board and assembled it…none of the software compiles …using latest ver IDE 1.o

    hmm tried different ones

  32. Jim Ford says:

    Hi ‘liudr’

    I need to alter my Arduino 022 project such that it will now compile with Arduino 1.0.

    I see that phi_buttons has been superseded by phi_interfaces.

    I need to translate entries in my code eg:

    phi_buttons btn_1(btn_u, LOW)

    to the phi_interface equivalent.

    What line of code would I use, please?

    Regards, Jim

    • liudr says:


      Before the code, I’d like to explain the fundamental changes between the phi_buttons and the phi_interfaces so the code would make more sense. The phi_buttons is a library that only handles tactile buttons that are hooked up to digital pins. The phi_interfaces is a library that handles all sorts of input devices and produces a return that is one ASCII character for each button. Compatible hardware includes tactile buttons hooked up to digital pins, matrix keypads, rotary encoders, analog buttons, analog joysticks etc. Every device has a different sensing routine but to the developer, all of them have a object.getKey() function that when a key press is recognized, will return the predefined character of that key. Yes, you can have multiple inputs return the same character so they invoke the same responses, nice thing to make a hall light switch in 2 to 3 locations all doing the same, toggling the hall light. So under this framework, you will be able to use any combination of input hardware and switch between them if you like. so with that, how to do it? I have a dozen sample codes attached to the phi_interfaces library release along with detailed documentation. I’d like you to ask questions regarding a specific sample code if possible. I suggest you look at the phi_button_groups sample code, which now handles a bunch of buttons, each hooked to one digital pin.

      • Jim Ford says:

        Thanks for the reply ‘Liudr’.

        I’ve tried a tentative conversion to phi_interfaces, but am getting so many compiler errors that it’s going to be much simpler to ditch Arduino IDE 1.0 and go back to 022 with phi_buttons.

        My project was working fine with 022 and the older phi libraries, but I automatically got ‘upgraded’ to Arduino 1.0 with Ubuntu 12.04. It’s all a total mess now and I’m pretty pissed off (not your fault though).

        Best wishes, Jim

      • liudr says:

        Most of the problems in upgrading to Arduino 1.0 was with Serial.write() and include files. I was not the first wave of people that upgraded since I have these many libraries to upgrade but once I did (took a lot of time) I was glad I did. So maybe try Arduino 1.0 on a different computer just to get a feeling of it?

  33. Jim Ford says:

    Thanks for the reply, ‘liudr’.

    Panic over!

    I’ve reverted to Arduino 022 now and am going to restore my project files to remove the 1.0 stuff. Fortunately I’m using a revision control system (RCS) which integrates nicely with Emacs, so it’s no problem.

    I’ve also just discovered that ‘figlet’ (the program that produces big comments in ascii) also integrates with Emacs. All you need to do it to type ESC+X and enter ‘fig’ in the minibuffer window, press TAB and it auto completes to ‘figlet-message’, press Enter and enter your text, press Enter again and it invites you to choose a font from a list, a last Enter and the big comment gets put in your code. Very quick and convenient. If you prefer the ‘starwars’ font (like you do!) you can download it and put it in the figlet font directory.


  34. Jim Ford says:

    I’m using your phi_prompt library in a project to record battery current and amp hrs, ambient temperature and barometric pressure. I want to read and record the values transparently in the background, and use a menu system to select them for display.

    It’s pretty much working, but values aren’t read and recorded whilst waiting for user input – eg while waiting in ‘select_list(&myMenu’.

    Can you offer suggestions as to how I can overcome this, please? The only thing that’s occurred to me is to set up an interrupt to periodically call a routine to read and record the values, wherever the program is in the menu system.


    • liudr says:


      A simple way is to open up phi_prompt.cpp and modify the wait_on_escape(). This is the subroutine that every wait function calls so buttons are checked in this function. You can insert your analogRead inside and maybe update every 50ms with if (now-last>50) update.

      To use the interrupt, take a look at timer1 library on arduino website. You can trigger periodic function calls if you set that function to be called at say a period of 50ms or maybe 100ms.

  35. Des Wong says:


    This is a great library and I was hesitant at first to use this as on first glance, this would make things more complicated for me, but have found it has made it easier to write a full menu and actually add a lot more functionality to my project by having this library available.

    I do have a question though, I have a project similar to the alarm clock that you have as example code, mine differs in that I am using analog pin with 3 buttons on it.

    I notice in your code that you actually run the alarm checking and display update loop as a menu option.

    I have been working on mine for a few weeks and been trying to run my alarm checking and display update loop as part of the void Loop() section of code as shown here:

    // Check for keypresses
    byte temp=panel_keypad.getKey();
    if (temp!=NO_KEY) {
    if (temp==’2′) {
    old_minute = 255; // Set this so that it refreshes the time display on exit

    I have found that this code just never works, and never calls the top_menu(); For all intents with the code presented it *should* work if button 2 is pressed.

    Is there a known issue trying to use this library with the phi_interfaces and trying to call the top_menu() in this method? Is this why you have actually written it into one of the menu options to run this loop? Is this the recommended way of working with this library (so you only call the menu in the main execution of the program, and everything including checking for alarms and updating the time screen is done within the menu option)?


    • liudr says:


      Sorry for the delay. Been busy with something. Yes, the code should work. Have you run a test code on the keypad just to make sure it is returning a key press at all? If you are using analog buttons, the variation of resistance of resistors you use could throw off the program to the point that it doesn’t trigger.

      The reason I have inner loops is to repeat that part until some conditions become true and it quits that loop. I could use the main loop() too but that won’t allow more loops within a loop.

      Try the phi_interfaces sample code with the analog buttons and make sure you modify the analog values to your exact setup so the buttons actually work before you use them in your code.

  36. chris lange says:

    Hello agian , Well I was giving your phi prompt a test drive with the examples, using my 16×2 wired up the same as the diagram shows and the text scrolls so fast you can’t read it. I’m using MacOs x adrunio 1.0.1 and it compiles correctly with no changes. Any clues? I am using the example that has your credits as a test. Looking forward to actually getting the real deal! My fingers are sore from jabbing wires into a breadboard for a LCD. Tried to make a LCD shield with a proto shield its like parking a caddy on a postage stamp, no room!

  37. jay says:

    I’m hoping to use some multiplexed buttons with this. How might I do that?

    • liudr says:

      Tell me some more details of how the buttons are multiplexed, like a matrix keypad? The phi_interfaces library supports matrix keypads. Phi_prompt doesn’t concern what input type you use, single button, keypad, rotary encoder, analog keys, serial input, etc. Phi_interfaces library creates a universal interface so all these inputs appear the same to phi_prompt. Hope that helps. I was away from my blog for some time.

  38. Larry Walker says:

    Help again: I posted a couple of days ago with this question, but my post seems to have disappeared, so I’m trying again: a client wants me to get your phi-panel 4×20 LCD and your 4×3 matrix keyboard working on an Arduino Mega. I found the photo of how to connect the ribbon cable to the backpack, but my backpack has a 10-pin connector, as opposed to the 11-pin connector shown in the photo.

    I hooked it up “as shown”, with the ribbon connector all the way to the left side of the backpack connector. I can use # to activate the backpack’s monitor and the A and B keys let me move up/down in your menus. But the rest of the keys do not seem to work: when I’m out of the monitor, my sketch’s Serial-available() and calls never return anything, as far as I can tell.

    When I try running the phi_matrix_keypads_example sketch, the “Phi_interfaces library matrix keypad test code” header appears, but even without touching the keypad, the sketch prints a continuous line of * characters.

    I’m having a very hard time finding the specifics on using the matrix keypad on your blog; any links I should be reading? Any idea why wouldn’t be able to Serial-read from the panel, even though it works fine with the backback’s monitor?

    Thanks in advance for any insights you might have on this…

    Larry Walker

  39. Larry Walker says:

    Boy, talk about embarrassing: the solution hit me while eating dinner yesterday: when my client gave me his newly-purchased keypad, I’d already had the LCD up and was writing to it for a week or two. I hooked up the keypad, but neglected to hook up the other half of the TX/RX pair: LCDs only listen, right? Oops!

    It is is now working correctly; your phi-menu commands are very useful,and I now have a nice user-interface running on it…

    Sorry to bother you for such a silly oversight!


    • liudr says:

      I will remember to add “check tx” in my next revision of phi_panel manual. Glad it worked out. If all possible, come back with a video of the menus you did.

  40. Robert Bush says:

    First I must give you a big thanks for this. I am needing a menu set up for my current project and this library is awesome! I was using menubackend and ran into some limitations I didn’t like and found yours upon further searching. Anyway I am having some issues getting started and was hoping you could point me in the right direction. Thanks again

    In file included from phi_prompt_example_menu_16X2_display.cpp:59:
    defs.h:150: error: ‘phi_buttons’ does not name a type
    defs.h:151: error: ‘phi_buttons’ does not name a type
    defs.h:152: error: ‘phi_buttons’ does not name a type
    defs.h:153: error: ‘phi_buttons’ does not name a type
    defs.h:154: error: ‘phi_buttons’ does not name a type
    defs.h:155: error: ‘phi_buttons’ does not name a type
    In file included from phi_prompt_example_menu_16X2_display.cpp:62:
    C:\arduino-1.0.1\libraries\phi_prompt/phi_prompt.h:111: error: ‘multiple_button_input’ has not been declared
    phi_prompt_example_menu_16X2_display.pde:-1: error: expected constructor, destructor, or type conversion before ‘*’ token
    phi_prompt_example_menu_16X2_display.cpp: In function ‘void setup()’:
    phi_prompt_example_menu_16X2_display.pde:-1: error: ‘btns’ was not declared in this scope

  41. Robert Bush says:

    Sorry I can’t recall were I downloaded those files, But I would like to say after a week of playing with this library…..super bad ass. At first I did feel a bit intimidated but gets cooler every time I play with it! Well worth the time to check this one out!

  42. Is there a way to prevent this main menu from showing when the escape key is pressed? I like to use the escape key in my own routine.
    Main Menu ->1/4
    -> Terminal
    . Settings
    . Serial address
    . Show Credit

    • liudr says:


      I will make a firmware that will have a disabled on board menu so you can use the escape key. Give me some time.

      • Hi John:
        I have a couple of question about your back panel.
        When you change the firmware to give access to the escape key will I be able to read the escape key as a return value from e.g. an interactive list/menu? It would be useful to indicate that the user changed his mind and does not want to replace a current value with a new value from the menu.
        Also, your documentation states that the maximum choices allowed for an interactive menu is 16. Is this an arbitrary number or could it be changed? I would like to create a menu for camera f-stops from f/1 to f/22 with a 1/3 stop increment. This would create a menu with 32 choices. The total bytes for the string would be below 255.
        It’s an amazing little board which allows me to create menus etc. with very little code. Thank you.

      • liudr says:

        BTW, if you split your menu into two separate ones, then you can do it with the current limitation 🙂

      • liudr says:

        For Arend,

        Yes, when I turn off the ESCAPE key for setup menu, you will be able to detect it in a menu as a 255 return value. The 16 maximum is a rather arbitrary to not run out of memory on the panel processor. I can change it (busy right but will do it some time soon) while you make your further project development. I am very happy you like the simplicity of making a user interface with this panel. That was the number one goal of the panel when I designed it, use 3 lines of code to create a menu or other stuff.

      • Hi John:
        From your blog I know your a busy guy but I would like to make one more suggestion/request regarding the backpanel firmware. Would it be possible for an interactive menu to start with a current value selected instead of always starting with the first value selected? It would save the menu user a lot of keystrokes. For example, if the current value is the middle of a long list of values, it would only take one keystroke to change the value one position up or down instead of many when you have to start every time from the beginning of the list? Thank you!

  43. Robert Bush says:

    Is there a way to print a variable next to a menu item that represents the menu item? Ex..
    PROGMEM prog_char top_menu_item00[]=”Water temp”(temperature); seems no easy way to do it? Thanks again

  44. Jim Ford says:

    Hi ‘liudr’

    Looks like over a year has passed since the last blog entry, so I don’t know if you’re still monitoring it!

    I’m trying to get back up to speed with a project I shelved 18 months ago.

    The project used the Arduino 022 IDE and your phi_prompt and phi_buttons libraries, as well as the LiquidTWI one and a few others.

    The project compiled and worked OK, but I want to add some more ‘bells and whistles’.

    Since I shelved the project I lost the Arduino installation on my machine, so I’ve had to start again. Fortunately my program was stored elsewhere, so I still have it.

    I’ve downloaded the Arduino IDE version 1:1.0.5+dfsg2-1 and the libraries I need, including your phi_prompt and phi_interfaces (I’ve decided to re-hash my code to use phi_interfaces instead of phi_buttons).

    On running the examples provided with your libraries I find that whilst the phi_interfaces compile OK, there are lots of library related errors in the phi_prompt examples.

    Is your phi_prompt library compatible with the Arduino 1.0 IDE, and if not is there an easy way to fix it, please?

    Best wishes, Jim

  45. Jim Ford says:

    Forget the above, ‘liudr’, I’ve now installed Arduino 1.5.4 and the examples compile OK.

    I am however getting problems with using the LiquidTWI with phi_prompt. I’m not sure what the problem is, as I had it working previously – but can’t remember how I did it!

    Best wishes, Jim

  46. Jim Ford says:

    OK – new question about phi_prompt:

    With the ‘input_integer’ function the lower limit integer is always initially displayed.

    Is it possible to have another value between the upper and lower limits displayed? This would be handy if a previous value had been stored, and it was desired to display it in order to adjust it up or down.


  47. Jerome Cloutier says:


    I would like to purchase your phi_prompt pcb and firmware, but the shipping and time is rather large to Canada, Can I purchase just the .sch &.brd file and the firmware so that I can make them here and save the shipping cost and time?

    I would also like to make a modified library of your phi_prompt that does I2C LCD and Keypad. I would like to make and send you a I2C keypad and breakout board so that you can test with also. I think a I2C phi_prompt for people that only need more simple menus but like to use your great system would benefit from the I2C keypad/LCD to save many pins.
    need to make a menu with this layout

    II have a few other questions for you if you have the time Can you email me directly please



    • Jim Ford says:

      I think you’ll be lucky to get a response from Dr Liu ‘Jerome’. He seems to have lost interest in the project, or maybe doesn’t have time. I understand he’s a professor now and therefore would be running a department and supervising students.

      It’s a pity because it’s a great menu system he devised. With my project I found that the waiting for an input blocked other processing. I got round this by using the ScoopME library such that in the Phi-Prompt wait loops, background processing continues. It works very well and makes the Phi-Prompt library far more versatile.

      Best of luck with your project. Jim

      • liudr says:


        I’ve been too busy the past 2 years. I’ve only updated the phi_prompt library (internally, not released) a few times to support more keypad types I came up with (on phi-panels). The library is relatively stable so I’m on not updating it till later this year. I’m also doing more consulting work than when I released the library. I’ll post some recent progress when I have some time. It’s strange. I am on sabbatical leave. I don’t teach this semester. But somehow I manage to make my life a lot busier than when I am teaching regular loads.

        You are right, the library only polls hardware for inputs. This is ok if you are not running a lot of timed events. With so many supported input devices, it makes a very difficult task to support them all and use interrupts. I’ll check out ScoopME for sure. Thanks for your continued interest in my work 🙂

    • liudr says:


      There may be some confusion. The phi_prompt is a library. It’s software, not hardware. THere is no pcb or firmware. Do you mean the following hardware instead?—phi-panel/×4-lcd-keypad-panel—phi-panel/

      If you are using adafruit’s I2C LCD, you can download this library that they modified from the original LCD library:

      This will work the same way original lcd library works so the phi_prompt library will be able to use it.

      In my opinion, it’s a bad idea to modify an included library in arduino ide but adafruit doesn’t do a lot of things right anyway. I’ve wasted time and effort playing with their oled display and I decided not to support it in my phi_prompt and other library and hardware. If only adafruit inherited their I2C SPI lcd class from the original LiquidCrystal class, it would probably make a lot of things easier. Plus, there are too many different I2C lcd and keypads out there using different chips and pinouts. It makes no sense for me to modify my library to work with any of them. A developer like yourself with a specific lcd and keypad would be doing that.

      I looked at your menu system. It’s got quite a few layers. For now, let’s make clear what you really want first. If you are using a phi-panel hardware, then the menus will be organized in slightly different way than if you use phi_prompt directly.

  48. Jim Ford says:

    All I did to make phi_prompt ‘scheduling/multitasking’ was to add a ‘yield()’ in ph_prompt.cpp:

    int wait_on_escape(int ref_time)
    //Wait on button push.
    long temp0;
    byte temp1;
    byte i=0;
    if (temp1!=NO_KEY) return (phi_prompt_translate(temp1));
    } while ((millis()-temp0<ref_time));

    return (NO_KEY);

    and include the SCoopME library in my code.

    For my purpose it works perfectly.

    Best wishes, Jim

  49. Jerome Cloutier says:


    Thanks for the quick reply,
    You are a very busy man I can only Imagine. I however have all the time in the world as I am a stay at home dad (progressive muscle disease.)

    I would like to use your phi-Panel and would like to buy from your inmojo store

    “PCB + MCU If you already have parts to build these, save some money with this option: only includes PCB and ATMEGA328P-PU loaded with firmware.”

    but to Canada the shipping is another $10
    I already have the things I need to build the board myself and the time to do so,

    I heat with only a wood stove way out in the country and my current project for what it’s worth it a controller that senses the wood stove and based on thermocouple input where by it PWM’s a dc fan that injects air into the front air intake as well turns on the blower fan for my front room and another blower for the upstairs.

    If I can get Phi_prompt to work that would be great, I use a PCF8574 for the I/O expander and I currently use PCF8574-HD44780.

    I use a second pcf8574 to interface my keypad with a Keypad_i2C library that extends the standard keypad.h of the IDE to use I2C and all normal commands.

    I am stuck where to start to get phi_prompt to use my method of keypad and LCD, I’d rather not modify the standard library either but use a good I2C lCD library and change phi_promt to suit. I am quite new at C++ and learn by example ( I do have learning issues when it come to linear thinking as required when coding, I tend to be all over the place). I compiled Phi_prompt and found that it is around 16kb my current code complies right around 17kb so I cant fit it on a atmega328 and this is where my request to purchase the .sch .brd and the firmware directly from you so that I can make my own phi_panel.I’m not sure if you would sell that to me in such a way?

    If anyone else on here might be interested in lending me a hand in adapting Phi_prompt to work with a I2C lcd and keypad with the PCF8575 or other expanders Please let me know I would like nothing more than to learn and better myself for my next project, the Goat&Chicken house controller and as well the GreenHouse controller. (Yes I grow as much of my own food as I can and be as self sufficient as I can in any given situation.)

    Thanks for your time.

  50. Jim Ford says:

    I agree – the pre-assembled panel is a good way to get started and experiment.

    BTW (and way off topic!):

    If you (Dr Liu) find yourself in the UK during a sabbatical, feel free to look me up. I’m retired and can show you around, including Bletchley Park, which is less than a one hour drive from me and was where Alan Turing worked during the War – and also where Tommy Flowers built the World’s first electronic computer (eat your heart out M.I.T.!).


  51. I forked your phi_prompt and doing some improvements on it. Would be a bad idea share this code on my github ?

  52. Fábio Jorge Costa says:

    Good afternoon,
    Been a while since I visited your blog, last time I bought a backpack for an application that made access control, now I’m making a system to monitor my solar panels and wood heating.

    In short, I’m trying for your pri_interfaces (with a keypad_matrix), with pri_prompt, and I am not able to set keys, because from what I have not comapctiveis the two.

    Vine then ask if it is possible to use the phi_prompt with shares created by us, and each of these actions aroused the actions of the library.

    Again, my congratulations for the libraries and hardware.

    Yours faithfully

    Fabio Costa

  53. Does the $30 fee for a Comercial license just cover an individual unit of my prospective product, or can I use the code in all the units I hope to sell?

    • liudr says:

      It covers everything you will every make with the libraries and its updates. It’s just a gesture that you appreciate the work I did, not a means for me to get rich 😉

  54. Dave Robinson says:

    I am having a slight issue with your phi prompt code: I am looking to run a void to take temperature, calculate PID and update LCD from within a menu. However I was either getting stuck in the void and not being able to escape by pushing a button, or the code was only running once and then escaping back to menu. To solve this I put the PID_Run void inside a while loop; now it takes 4064ms to run the loop which was messing up my sample time of 1000ms. Is there any other way to run continuous code and escape by pushing a button?

    • Brian Gonzalez says:

      Dave, I use osPID and osPID stripboard. The have a built-in menu and always run the PID and temp sense functions in the background. Just another solution in case you can’t figure this one out.

  55. Sean says:

    Hi, I’ve been searching the forums & previous posts for days trying to find a solution to the problem of using a 20×4 I2C LCD with Phi_prompt. I need some explicit help on which LCD library to use and what lines of code I should use to get an I2C LCD talking to init_phi_prompt.

    When I compile I get the error:
    cannot convert ‘LiquidCrystal_I2C*’ to ‘LiquidCrystal*’ for argument ‘1’ to ‘void init_phi_prompt(LiquidCrystal*, multiple_button_input**, char**, int, int, char)’

    I’m guessing LiquidCrystal is looking for this format: LiquidCrystal(rs, enable, d4, d5, d6, d7)
    But I can’t work out how to manipulate LiquidCrystal_I2C to work.

    Help ?

    • liudr says:

      Replace anywhere you see LiquidCrystal with your library and give it a try. There are too many I2C LCD modules and libraries so I’m not interested in tailoring to these modules. If you find success, please send me a zipped file and where you got your LCD module and library. I’ll post it as an alternate version.

      • Sean says:

        Using the adafruit LiquidCrystal library appears to work well with Phi_prompt. (using an adafruit I2C backpack).

        Next problem:
        I only want to invoke the Menu and LCD backlight when a user presses any key. The rest of the time I want the Menu/LCD to be blank (no light) and allow the loop to handle other things.

        I’ve tried some simple if statements to call top_menu(), but the code never seems to exit the top_menu() to run the code further down the script.

        void loop()
        char temp;
        if (temp!=NO_KEY)
        top_menu(); //code stops here. Menu runs OK.
        lcd.clear(); //never gets to this line
        lcd.setBacklight(LOW); //never gets to this line…..
        more code down here….. //never gets to these lines, once the Menu is displayed.

        What am I doing wrong ?

      • liudr says:

        You won’t be able to do anything else in the background while you are in the menu. There is a way to do this while keeping the menu working but it involves a lot of coding (involving the menu render-er in your loop). I don’t have document ready for this part. If you want to say run some timed loops in the background while you ask the user to respond, you can try the phi-panel lcd panels and backpacks. They are loaded with functions of the phi_prompt library and connect to arduino via serial port (soft or hard). You render a menu by sending a text message to the panel. Then the panel will interact with the user and send back a one-character response, such as ‘1’ if the user selects the first item in the menu. While the panel interacts with the user in the menu, the arduino is free to do anything. Just check back on the serial port for response in your timed loop.

  56. Sean says:

    OK Thanks. Playing around with the menu – I’m starting to understand it now.
    When I execute a return; from the menu – it resumes my main loop code and then I can call the Menu at any time by simply pressing a button. So long as I don’t press a button, my main loop runs.

    Instead of executing a return; from the menu, is there a simple method to setup an inactivity time period to execute a return; if there is no button pressed (say) after 30 seconds ?

    Should I use millis() and where do you suggest I insert this ?

    • yhchan86 says:

      Have you been able to figure out a way? I was able to add some very crude code to idle out of the select_list function and return a value to tell the main program to run background task, and tell the main program to finish the last cycle of background task when a key is pressed. Would love to hear back from you.

  57. Alejandro Mesias says:

    Would be a problem if you change for a non viral licence, like bsd, apache, etc ? I love your library, and I’ve adapted it for many things, added some options, created progressbar component. But, to contribuite I can’t use it as GPL license.

  58. Leandro says:

    Are you still maintaining this library? I’m having errors when compiling like:

    phi_prompt.cpp: warning: ‘sizeof’ on array function parameter ‘msg’ will return size of ‘char*’ [-Wsizeof-array-argument]

    phi_prompt.cpp: warning: no return statement in function returning non-void [-Wreturn-type]
    phi_prompt.cpp:warning: control reaches end of non-void function [-Wreturn-type]
    phi_prompt.cpp:warning: unused variable ‘ret_val’ [-Wunused-variable]

    Thank you for your support!

    • liudr says:

      It’s been a while since I last maintained that library. My focus has changed from that to more data logging and sensors. If you’re willing to toy with arduino IDE 1.0.6, that was the last IDE version I updated the library for.

      • Leandro says:

        Thanks for you reply Dr. Liu! I will try to update your library to IDE 1.8.15, I saw that you have some features that are not available in the current download files, do you mind to share the code to dynamically update the menus or multi-select itens as in your PDK. I will try to improve and update the code for you, as long as you keep it as GPL. What do you think? Thanks in advance for your attention.

      • liudr says:

        Here is the PDK documentation:!ApfcTYdmRdGlhL0QYtYNscMAMpqIHg?e=OWuYV6

        It’s been a long time since I last updated the code so I don’t remember any details or could help you.

  59. Leandro says:

    Thank you Dr. Liu. I will check and let you know as soon I as get something. Thanks again!

Leave a Reply