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:

The library, including sample codes and full documentation are on the library and code download page:

Click here


Here is the class hierarchy:

I will be posting videos and tutorials soon!


Nov 5 2015:

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

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:

Well, I’ve decided to release my libraries under GNU GPL V3.0. Nevertheless, please support me with some donations.

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.

42 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.

    • liudr says:

      No, you have to keep calling the getKey method to poll the inputs. If you want, you can poll it inside a timed interrupt loop.

  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 😉

      • Hello, I left a comment last year, and it wasnt approved and now erased… could you point me the reason?
        good day

      • liudr says:

        Not really. It’s still in the queue. I’ve been busy so didn’t answer anything that requires more than a few minutes of time 🙂 To be honest, reviewing my own code is as difficult as reading others’ code. You have to be coding it everyday to have a good memory what you did and I have not touched my libraries for a while, just doing routine updates for arduino 1.6.x IDE.

      • Thanks for the reading! The stuff about the = and ==’s Im wrong, Im just comming from processing and plain arduino so I guess Im mixing syntax… be cool with that..
        about the rotary, it works now but in the strangest way: I can only put the rotary on pins 20 and 21 on the DUE… something like a year ago worked but now it doesnt on any other set of pins… it is cool for me as only one rotary, but it is a bug maybe related to ports? or maybe the pins are damaged, but I run interrupts rotary codes and they work well everywhere 🙁
        I understood the workings of encoders so no help on that either…
        thanks again

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

  15. Raghunathan.R says:

    Hi Liudr…. I downloaded your Phi_Interfaces and am might pleased with the results. I am using this single library for both Matrix KeyPad and Button groups in different sketches. I do suppose I can use them together also in a single sketch. Just to support your good work in a very small way I have just made my donation.
    Thanks for your support.

    Chennai / India.

    • liudr says:

      Thanks for your support! Yes, you can have any number of different inputs in one program. Just make sure you call .getKey() on all of your inputs in loop().

  16. chukovskij says:

    > Well, I’ve decided to release my libraries under GNU GPL V3.0. Nevertheless, please support me with some donations.

    Hi, thank you for a great library. Seems according to the license we need to open source any software which uses (e.g. linked) this library. LGPL allows to link without modification, but GPL doesn’t… If you want allow people to use freely this library for any purpose (including non personal use) GPL was a wrong choice.

    • liudr says:

      That was my exact intent. If you want free stuff, you need to maintain open source as well. GPL prohibits modifying the license, not modifying the code. Say you make some modifications so now the library handles more hardware, then you are required to release it under GPL as well so more people will benefit from your work, which benefited from mine. Arduino software is released with LGPL for its own purpose. If you are a company trying to make money off arduino, you can close source after you built upon their open source code. That’s their choice. GPL is mine. You should read the short license hosted on FSF a bit more.

      • chukovskij says:

        > you make some modifications so now the library handles more hardware, then you are required to release it under GPL

        Yes, I agree that sharing updated library is a benefit for all. But I’m talking about the whole application which use the library. If I just need a library without any modifications I cannot use it for any commercial purpose. Or I need to open source the whole project, this may “destroy” the product and allow anyone to copy it.

        As far as I understand the main difference with LGPL, is that second allows to link your code with such library and doesn’t require to open source the whole application. As for library modification they both require to share updated library

        > If you want free stuff, you need to maintain open source as well.
        I don’t like GPL due to its viral effect. Personally I prefer Apache common license or MIT. There are lots of free libraries which suitable both for commercial usage and not commercial without any viral effect. I know companies which support such open source projects (e.g. by patches) and use libraries in their own products. Good libraries are usually supported by community without corresponding license requirement.

        > That’s their choice. GPL is mine.
        Yes, your library, your choice.

      • chukovskij says:

        > If you want free stuff, you need to maintain open source as well.

        I mean, that if I event want to support/improve the library and I have some idea how to make some money using it I’ll have to chose another library. So that is why I consider GPL to be a wrong direction in free software. It works only if you want to cell some online service or you make money not on software development.

      • liudr says:

        I do make some money developing software. When I do, I give my clients proprietary license so they can do pretty much what you want to do with LGPL software. Most people have good ideas but lack skills to execute them. So they use libraries and shields, which can get them quite far along the development path. Then when they hit their limits, they usually turn to consulting. That’s where I come in. They’ve used my software or shields so they know that I’m good at the stuff. A little money from consulting also helps me maintain my free software. Nothing is free for everyone.

  17. Hello, Im using the new library, but Id like to point out that the “Class and function reference manual 20120124.pdf” is, as the name suggests, still the old version, and that the new “Phi_interfaces documentation 20151104.pdf” doesn’t updates the rotaryD and rotaryA stuff, as to what I’m seeing…. not to mention that the examples are still the old ones, lacking on the new types of rotary’s supported and etc…
    I’m extrapolating from the h file to make use of this, and would be willing to supply you “my examples” if you mind them worth while… also, I’m mostly working on the DUE arduino so you can acknowledge your library on that board also…

    good day,

    • liudr says:

      That was indeed an old document. rotaryA is a mistake. Trying to use analog input to sense a rotary encoder is unreliable although it sounds like it saves pins. rotaryD is the same as the original rotary encoder class. I’ll get rid of the rotaryA and update my docs when I get some time. Same with two versions of liudr keypads. They are not as good as I thought they would be. I’ll get rid of them as well. Sorry about that.

      • Ohhh, its a shame it didnt work the A… seemed saving for those having spare analogs…
        So it doesnt make sense still updating? I could help you out with the docs if you’d like… some way of retributing your helpful library… take care!

  18. Liudr, I need help with a matrix I’m developing on a large interfase, that needs multiple presses. First I repeated the rows pins with every column, so I got 7 temp’s saving the getkeys from each matrix, which I guessed was the way around but as I do multiple presses all seem to freeze until I release…
    Does it mean I should get dirty inside the library and work with sense_all ?
    Or should it work with a switch conditional analyzing only one temp? What’s the best approach for making the code fast? It all deals with sound so I need speed.
    thanks for reading me

  19. Pingback: Augmented reality sandbox control box updated | Liudr's Blog

Leave a Reply