Phi_interfaces library home page


This phi_interfaces library unites all input devices in an unprecedented way. You can sense a matrix keypad the same way as push buttons, rotary encoders, or analog buttons, or serial keypads, or simulate key presses on arduino serial monitor or even use your smart phone to generate key presses to control your arduino projects. You could create multiple operating interfaces, one on arduino project, one on a remote server and one on your smartphone. You can then control your project wirelessly from meters away or from world away and it feels like you’re controlling it right on your desk.

What is more exciting is that you don’t need to make any change on your code to do all the above. Start your project with a few push buttons and later decide to control your project on your smartphone with bluetooth serial, and finally settle for dual interface, with keypad on the project and with smartphone using bluetooth serial. No need to change any code while you are making all these hardware changes. Interfaces should be just like that, snap on and snap off, all with standard plugs and no fuss.

I will be using this as the physical layer for my phi_prompt user interface library soon.

Library, sample code and documentation download:

At the moment, I have placed the download on my phi_prompt google code page. Soon I will create a separate google code page just for phi_interfaces. The library, including sample codes and full documentation (in color LOL) are here:


Here is the class hierarchy:

I will be posting videos and tutorials soon!


Jan 2 2012:

As some of you may know, I have developed several arduino open-source libraries, phi_buttons, phi_prompt, phi_big_font,phi_morse, phi_super_font, etc.

My main focus is to interface arduino with inputs such as buttons, keypads, etc. and outputs such as LCDs so a project developer doesn’t have to through all the trouble to create these themselves. I’ve been successful with these libraries so far but I’m not completely satisfied with how contributed libraries are maintained.

The reason I developed these codes is that the current status of contributed libraries is that each library is managed by an individual and in order to say use a matrix keypad and a couple of rotary encoders, you need at least two libraries and they follow different conventions and you are expected to learn different things with each new library you come across. And most of them don’t even support hold-and-repeat! Not to mention lots of them are no longer maintained and are left to rot. There has to be some common basis among some of the libraries so a general expectations are met, such as each keypad library should have a getKey for getting a key press regardless who wrote the library, through inheriting from a common interface.

Here is what I’ve just done in the past few weeks, using what I already had as basis:

I’ve made a new library called phi_interfaces library. At the moment it contains classes such as single buttons, matrix keypads, analog buttons (essentially a keypad in nature), rotary encoders, and liudr keypad, plus some nice things shared by these classes.

To write a project, you just need to include one library, the phi_interfaces.h, and you can create objects such as single buttons, matrix keypads, rotary encoders etc and they all behave as expected.

The matrix keypads, analog buttons (keypad in nature), rotary encoders, and liudr keypads (or any other future keypads) are all inheriting from multiple_button_input, which has a function called getKey, same as the popular keypads library. Any of these objects can provide buttons pressed with this function. They all support hold-and-repeat and essentially can support my multi-tap codes if they have at least 10 number keys. If you are interested in expanding this interface to a different type of keypad, say a capacitive keypad, all you have to do is to write a sense_all() code to provide the interface a handle to sense all possible buttons and give an immediate status. All the debouncing and status changes are handled by interface functions and eventually by the getKey. So even a library developer will save time by not having to write their own debouncing etc. while we can all contribute to the polishing of these basic codes.

This also makes my library expansion much easier.

The buttons class is a subclass of the single_button_input class (interface). The interface has a few functions, sense() being the most useful function. Any classes using this interface will need to implement this function so they can be controlled the same way.

Future development will support IR remote, PS/2 keyboard, etc under the multiple_button_input, which will all support the getKey method.

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

27 Responses to phi_interfaces

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

  2. Steve says:

    hi Liudr and thanks for one more great library!

    I think I found a tiny error in the example for a matrix keypad

    These constants are defined,
    #define buttons_per_column 4
    #define buttons_per_row 3
    (that’s for 4×3 keypad, like the one in the pdf without the extra A,B,C,D column)

    and then the matrix it’s initialized like
    phi_matrix_keypads panel_keypad(mapping, pins, buttons_per_row, buttons_per_column);

    but the numbers of columns are rows are exchanged, since the prototype is
    phi_matrix_keypads::phi_matrix_keypads (char * na, byte * sp, byte r, byte c)
    so the 3rd argument should be the number of rows = buttons_per_column = 4

    So it has to be
    phi_matrix_keypads panel_keypad(mapping, pins, buttons_per_column, buttons_per_row);
    which means
    phi_matrix_keypads panel_keypad(mapping, pins, 4, 3);

    I tried it like this with my keypad and it works fine.

    also some quick questions:
    -is it safe to use the keypad without row resistors? I know that Arduino has internal pullup resistors which are used during the matrix scanning…but you know when you don’t see something, it easy to worry about it. It’s much more simpler, however, not having to include row resistors.

    -also I’m curious how is the synergy between phi_prompt and phi_interface going?

    thank you

    • liudr says:


      Thanks for pointing out the mistake. I will make a correction in the next release. I guess it didn’t affect me since I’m using a 4X4 keypad. The reason that there needs no resistors is because there are internal pull-up resistors to keep the values high unless the key is pressed. Also, if you are concerned with shorting, it’s not an issue. Arduino pins are tristate pins so those columns that are not addressed are not pulled high but rather put into the hi-impedance mode (input mode) so there won’t be any shorting. If your pins are only bistate, ie. output high or output low, then you need to add resistors to prevent a high line connecting to a low line, when a user presses two buttons at the same time.

      Regarding the synergy between phi_prompt and phi_interfaces, I wrote phi_interfaces specifically to upgrade phi_prompt to the current version so that whatever input devices you use will work the same way transparently with phi_prompt. Say you have up/down buttons and later decide to use rotary encoder for up/down, all you have to do is to use phi_rotary_encoders object instead of phi_button_groups object. Since all of them are derived from the same base class, they all share the .getKey() method. It makes no difference to phi_prompt what is generating a click. You can have multiple buttons/input devices generate the same click too or programatically change what output a certain button generates. Then you pick up on the receiving end and decide what to do when a certain click is generated. The added layer of which button generates what click (a one-char return value) gives you the freedom to do great things, if you want to use this layer. The common base class glues all different types of input together so you never have to write a program that only works with tactile switches and had to do major changes when you decide to go with rotary encoders or matrix keypads. This happens a lot, since every separate library was written by a different individual, and people tend to grow their projects to more complexity and find the original 3-button is not enough anymore :)

  3. Darron says:

    I was wondering If u can help me out I am planning on making a touchscreen computer and was thinking of using adruino to connect to phones and ect and view it on the screen and make it so when it gets close enough to be able to sense it please help if possible

    • liudr says:


      I currently don’t have any libraries that deal with touchscreen. What I suggest you to do is to post on the arduino forum to ask for some help. I’m only using smaller text-only screens and those don’t have touch capabilities. When you post a thread on the forum, make sure you paint the complete picture, what you want to do, what you have as hardware and software, where you need help.

  4. tirlochan says:

    Sir, Thanks for contibution of Phi_prompt,phi_interface library
    i have a problem while displaying 2d array on 16x2lcd

    it shows 1st row and ten slides to left with data in 2nd row of 2d array
    codes is

    void displayData(){
    for(int j=0;j<2;j++){
    for(int k=0;k<3;k++){

  5. tirlochan says:

    it will work

  6. Tom says:

    Does your phi_interface library use the arduino timers? My sketch uses the millis() function and I understand that millis() uses the timer0. I found the arduinios softwareserial library uses timer0 so I had to not use it and go back to using the arduinos Uart pins (0 and 1) and use the plain Serial library.

  7. Tom says:

    Hi Liudr, thanks for your reply. Its good to know that your phi_interface does not use timer0. Using a timed interrupt to poll with the getkey method should work well.

    I am considering using the I2C bus to connect a 16×2 lcd display on my arduino unos because the uart will be connected to a XBEE wireless transceiver. I undestand that to use I2C I must include WIRE,h library. I want my remote arduinos to have a small lcd display for testing, status reporting, debugging, etc.

    Question: Do you know what resources such as timer0, timer1, timer2, int0, int1 the WIRE library uses? My app needs timer0 for use of the millis() method, it also uses both hardware interrupts (int0 and int1), the uart and timer1, so only timer2 is available.

    I found out by trial and error that the Software Serial library uses timer0 which of course, broke my code since my code uses the millis() method.

    It sure would be nice if the authors of all arduino libs and sketches identify which, if any of these resources are used by their libs somewhere easy to find so one can read them first before trying them and finding out your app no longer works.

    I am considering moving my app to the arduino mega 2560 because it has more of these resources but my uno shields may not fit well.

    Would using your phi_interface library solve this resource issue?
    Can I share the uart somehow with code and control pins and a few hardware logic gates?


  8. tirlochan says:

    ‘O’ Thanks for the reply
    It is great to receive response from You
    Such a great library

    Tirlochan Singh

  9. Carl says:


    I have the 2×16 lcd/4×4 keypad/serial backpack combo used with an Arduino UNO, and it’s really great! So easy to plug and go!

    I am using it for a design project for school, and am wondering if it is possible to change the functions of the A,B,C,D and * buttons. Since everything is communicated to the Arduino via the RX and TX pins, would this require a change in the backpack’s firmware? Do I need any special tools / hardware to do this? What would you recommend?

    Thanks for all the awesome contributions!

    I look forward to your response,

    • liudr says:


      Thanks for your comments. I can create a different firmware if you tell me what you would want and what not. If you still want the on board menu renderer to render menus on the panel (not the setup menu), you will need to keep at least three function keys, up, down, and enter. Then the rest can be reset to their face values. If you don’t need the on board menu renderer, you can reclaim all keys. I will need to make new firmware. Let me know what you want.

      • Carl says:

        Wow! Thanks for the immediate response!

        I think we will not need the on board menu. If possible:

        * = decimal point
        # = enter
        D = backspace

        and then 0-9 and A-C can be their ascii equivalents.

        Alternately, without an onboard menu, will ‘backspace’ be necessary, or would you suggest simply recognizing ‘D’ to perform backspace within the program?

        Thanks again for everything,


      • liudr says:

        The easiest way is to get another kit with 16*2 display and I will load it with the modified firmware. This way you always have a back up, the one you have at hand, in case the modified firmware creates trouble. What about it?

      • Carl says:

        I think that makes sense, overall. I’ve organized the project budget for a little extra expense. How should I place the order for the kit with custom firmware?

        Thanks again,

      • liudr says:


        Just place an ordinary order on with a phi-panel backpack 16X2 LCD kit. Then remind me either with email (you will get my email with paypal payment) or on blog that I should do this for you. I will modify the firmware, load it and test it before I send it off to you.

        Dr. Liu

  10. wawawuwewo says:

    Hello, can u teach me how to make an arduino programming code for control wireless CCTV using smartphone :) hope u can explain a little bit about the program. Thanks

    • liudr says:

      That’s outside the capabilities of the phi_interfaces library, which is where you posted your comment. You will have a better luck with answers if you post on arduino forum.

  11. Ernesto says:

    como puedo hacer lectura de botones analogicos con la libreria phi_interfaces?

    • liudr says:

      Google translate: I can do reading as analog buttons with phi_interfaces library?

      Yes you can. Use phi_analog_buttons class. There is sample code in the library.

      Sí se puede. Utilice la clase phi_analog_buttons. No hay código de ejemplo en la biblioteca.

  12. Pingback: Debouncing a mechanical rotary encoder | Liudr's Blog

  13. Hello, first of all, I’d like to thank you for your useful library!

    I’ve been tweaking it to do some specific stuff, and have come across some problems, but before I tell you them, I’d like to point you some strange issue, that doesn’t make anything wrong but that gives me some bad feeling (wish you understand me…)
    inside the phi_interfaces.cpp, at line 215:20 inside the button_status’s case buttons_up, you can see the line button_sensed==button_pressed; not inside an if, but as a statement, and there’s my bad feeling… maybe not passing between states because of that?
    all the case’s code goes like this:
    case buttons_up:
    if (button_pressed!=NO_KEYs)
    else button_sensed=NO_KEYs;
    ok, so the problem:
    I want to use the implementation of the held case to make some timed based functionality on my project, and well I first saw the button_status and the scanKeypad() have to be made public but that doesn’t get to pass correctly the boolean I installed inside the cases….

    I wish you could have some time to help me out… any ideas appreciated, and I wish I don’t deficit that much from short snippets, I just feel ashamed of passing you my entire code…

    Thanks in advance for just reading.

    Great day!

    • liudr says:


      Thanks for your comment. I am a bit confused. The line 215:20 is inside an if statement if (button_pressed!=NO_KEYs). This means that if a scan on the matrix keypad (or whatever underlying keypad) returns a key (say 0-15 for which key is down on a matrix keypad), then there is a key code in the button_pressed, instead of NO_KEYs. The code thinks that there is a button down. It will put the state machine in debounce state. The scanKeypad was not meant to be called by functions outside. If you insist, you can change it so it stays out of private or protected area in the .h file. I would recommend defining the scanKeypad method as virtual, derive a class from matrix keypad with a redefined scanKeypad, if you wish to retain all features of a matrix keypad and want time based functions, such as holding a key over 3 seconds means pressing a different key. Then the scanKeypad needs to be a state machine, so that it recognizes a hold over a threshold time and when being called further, it generates a sequence of different key. Sorry I didn’t respond in time. I didn’t delete your comment. There is a long back log of comments awaiting for approval. Lots of spams on wordpress blogs so I have to approve every new person and then their comments get automatically approved once I approve them once. I’ll delete your other comment asking why I “deleted” your this comment ;)

  14. Pingback: Arduino, RTCs, Unixtime, and the DS1307.h Library | kevinfundarek

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 59 other followers

%d bloggers like this: