Simple and intuitive web interface for your Raspberry Pi

Picture of Simple and intuitive web interface for your Raspberry Pi

The Raspberry Pi is an amazing 35 dollars mini-computer. It allows you to do everything you could do with a regular Linux computer (Connecting to the internet, watching videos, launching applications, ...) but also to interact with the world surrounding it, just like an Arduino. That's why I qualify it as a mix between a computer and a micro-controller.
That's also why I chose it for this project. I'm going to show you how to control LEDs with your Raspberry Pi. Firstly directly from the Raspberry Pi itself, then from any device in your house like your Smartphone or your tablet.

Here is a very good example of what you can achieve after reading this Instructable: Thanks to Rleddington for his amazing project.

Update: French version here

Remove these adsRemove these ads by Signing Up

Step 1: The electronic part

Picture of The electronic part
     The electronic part is nothing special, it's only 8 LEDs with their protecting resistor. The only hard part is to connect the LEDs to the good pin on the Raspberry Pi. Indeed, I'll be using later a library called Wiring Pi made by Gordon Henderson (You can visit his website at: and the pin's numbers used in this library aren't the same than the ones on the Raspberry Pi. See this page for matches: (just be careful about your Raspberry Pi revision, the pinout isn't exactly the same). I'll be using Wiring pins 0 to 7.
     Concerning the resistors, they should be 270Ω but since I don't have this precise value, I'm using 560Ω resistors (LEDs are just less bright).
     Finally, I've made two schematics to make it simpler. The first one (with the complete Raspberry Pi) is showing you the real pins as they are shown on the board. The second one is a simplified version, it's showing you only the useful pins and their matches in the Wiring Pi library (GPIO Wiring number/Actual number on the board).

Step 2: Installing and using the Wiring Pi library

     As said before, Wiring Pi is a library. It simplifies a lot using the Raspberry Pi GPIOs (one command instead a long process). It also means that you can use it in any of your C codes. However, we won't build and use a C program but the Gpio utility. It's a software made by Gordon and coming with the library. It allows you to control the GPIOs in a bash script or directly in a command line. Using this utility is however a lot slower than a C program.

     We first need to install it. Gordon himself is explaining it very well on his website: You just need to download it from GIT then to build it using the ./build command.
     You should now be able to use the Gpio utility, type the "gpio mode 0 out" command to test it out. If nothing special appears, everything's fine. Else, if the board is printing "command not found error" or something like that, be sure that you've followed the guide and build the library.

     Let's turn on and off the first LED (Wiring pin 0). You first need to set the pin as an output. Use the "gpio mode 0 out" command to do so. "0" is the wiring pin number and "out" simply stands for output. Now, use the "gpio write 0 1" command to turn on your LED. "0" is again the pin number and "1" is the status (1 for ON and 0 for OFF). If everything's fine you should see your LED shining. To turn it off, simply use the "gpio write 0 0" command.
     Just a little tip, if you want to use the actual pin number (GPIO-17) instead of the Wiring Pi number (0 is corresponding to GPIO-17), use the -g flag in your command. Ex: "gpio -g write 17 1" instead of "gpio write 0 1".

      There is also the "gpio read" command which allows you to read the pin's status. It may seems useless when the pin has been set as an output but it allows you to be sure of the pin's status when you can't see the LED. Using it is as simple as before, just type "gpio read 0" where "0" is the wiring pin number. The command is returning the pin's status (again 1 for ON and 0 for OFF).

     Finally the Wiring Pi library is containing a lot of other commands/functions but I'm not gonna cover them in this instructable since there are not useful here. See this page if you are more curious: (library's functions) and or the "man gpio" command for the Gpio utility.

     Now that you can use this utility, let's play a little bit with it. You can first, if it's not already the case, control remotely your Raspberry Pi with SSH. You can use Putty for Windows or ServerAuditor for your Smartphone. Then have fun with bash scripts such as this one which is turning on LEDs 0 to 7, waiting 2 seconds, then turning them off again:

#set mode to output
for i in 0 1 2 3 4 5 6 7;
   do gpio mode $i out;

#turn on LEDs 0 to 7
for i in 0 1 2 3 4 5 6 7;
    do gpio write $i 1;

#wait 2 seconds
sleep 2;

#turn LEDs off
for i in 0 1 2 3 4 5 6 7;
    do gpio write $i 0;

Step 3: Installing a web server then transferring your website to it

Picture of Installing a web server then transferring your website to it
     Controlling the LEDs remotely with SSH is pretty cool but the interface (console) isn't very user friendly and typing the commands every time is long and annoying. That's why we need a graphical interface for our project.
     Programming an app for each OS (IOS, Android, Windows phone, Mac, Linux, Windows,...) would be too long and would require to know a lot of different languages for nearly nothing. It would also require to do an application running on the Raspberry Pi. Making it this way would be overkill and time wasting.
     That's why a website is the best solution, it's compatible with all devices and you "only" need to know four languages: HTML (for the page's skeleton), CSS (page's style), PHP (interactions with the server) and JavaScript (interactions with the user).

     We indeed need to install a web server on the Raspberry Pi. In our case, we don't need a MySQL database, only a HTTP server and its PHP extension.
     After updating your Raspberry Pi with the "sudo apt-get update" command, type "sudo apt-get install apache2 php5 libapache2-mod-php5" to install Apache HTTP server and PHP5 extension. You can now test if your server is working by typing the IP of your Raspberry Pi in your browser. You should now see a "It works!" page with two other lines. If you don't, then check your board's IP, try re-installing Apache or rebooting your Raspberry Pi. This page is showing that your Apache server is working properly but not its PHP extension. To check it, navigate to your "/var/www/" directory by using the "cd /var/www/" command. If you use the "ls" command, you should have only one file named "index.html". This file corresponds to the "It works!" page. You can now delete it ("sudo rm index.html") and create another one called "index.php" (use "sudo nano index.php"). Then type the following text:


     After saving it using ^o (Ctrl + o), exit nano editor with ^x (Ctrl + x). Now if you refresh your browser, you should see a long page with lots of information about your server and PHP. If you don't, check the index.php file, try re-installing PHP or try to understand the error displayed instead of the page (Google it if necessary).

      If both pages were correctly displayed, then you now have a fully functional Apache/PHP server but using nano every time is annoying and not very comfortable. We indeed need to transfer files from your computer to your Raspberry Pi. You may want to install a FTP server but it isn't necessary, you can already transfer files using the SFTP protocol. All you need is an SFTP client on your computer. I'm personally using  WinSCP for Windows but there are Cyberduck for mac and Filezilla for Linux. If you try transferring files before reading what's next, you'll probably have issues such as "access refused" or "cannot write here". It's due to the fact that the user pi isn't owning the www directory. Indeed, if you try the "ls -l /var/www" command, you'll see that only root (the super user) is owning the www directory. You can (like I did) use the "sudo chown -R pi /var/www" command to change it or create a group named www-data in which you place the pi user then use the "sudo chown -R www-data /var/www" command. The -R flag is standing for recursive, it means that the user/group isn't owning only the directory itself but also everything inside (index.php as example).
     You now have your server ready to work and to receive web pages. Have fun with it if know HTML, CSS and PHP.

Step 4: Controlling the LEDs with PHP

Picture of Controlling the LEDs with PHP

We now have a web server and a library, let' put them together.
PHP stands for "PHP: Hypertext Preprocessor", It's a server side scripting language. It means that the PHP code is executed once (each time the page is requested) by the server and cannot be seen by the client. I used this language because it's the most popular (and that's the only one I know) but you have to know that they are other server side languages like Python, Ruby, Lua, Perl, ... However, I don't know if the functions we are gonna use have their equivalents in these languages.

Executing applications with a PHP code can be done with two different functions: exec (for execute) and system. Firstly, the "system" function. It takes two parameters: "system ( string $command, int $return_var )", as you guessed it, the first parameter is the command to execute and the second one is the returned status of the executed command. The second parameter isn't compulsory. You can use this function if you don't expect an answer from the command executed. Thus, you can use it if you need to execute "gpio mode 0 out" or "gpio write 0 1" commands. Example:

     system ( "gpio mode 0 out" );
     system ( "gpio write 0 1" );

Then, the "exec" function. This function is making exactly the same work than "system" but it reads and stores what the command printed. It takes three parameters: "exec ( string $command, array $output, int $return_var )", again $command and $return_var are the same parameters and the only difference is the $output array. As it's name says it will store the command's output in an array. Thus, you can use this function if you need what the command prints like with the "gpio read 0" command. Example:

     exec ( "gpio read 0", $status );
     print_r ( $status );

You can now execute nearly whatever command you want but let's make a little PHP example to practice: We will turn on LEDs 0 to 7, then wait 2 seconds, then turn them off. Just like we did with the bash script. Edit the index.php file with the following code:

$status = array ( 0 );
//set pins mode to output
for ($i = 0; $i <= 7; $i++ ) {
     system ( "gpio mode ".$i." out" );
//turns on the LEDs
for ($i = 0; $i <= 7; $i++ ) {
     system ( "gpio write ".$i." 1" );
//reads and prints the LEDs status
for ($i = 0; $i <= 7; $i++ ) {
     exec ( "gpio read ".$i, $status );
     echo ( $status[0] );
//waits 2 seconds
sleep ( 2 );
//turns off the LEDs
for ($i = 0; $i <= 7; $i++ ) {
     system ( "gpio write ".$i." 0" );

Step 5: Making the interface

Picture of Making the interface

We can now control our Raspberry Pi with simple PHP scripts but there is no interaction with the user and thereby we can't choose the LED to turn on/off. Let's make the interface!
It's composed of pictures I've found on Google images (search for "on/off button"). One was green and the other one red, I just added the number using The Gimp. Each picture/button is corresponding to its LED, so if you click on one of these, the corresponding LED will be turned on/off and the picture will be changed to its green/red version. The page's skeleton will be made with HTML, the server interactions and page's generation with PHP and at last JavaScript to manage interactions with the user and page's animation. If you don't know, JavaScript is a client side language and unlike PHP, it's executed not once, but continuously by your browser. That's why you can change the page's look without reloading it or accessing to an other. If you are wondering why I spoke about CSS before, it's just because we need it for some style and page-layout like the the black background. I didn't make a full .css file because it wasn't necessary here.
We first need an "index.php" file (extension is .php and not .html cause we will use PHP code, it helps the server to know if there is PHP to execute before sending the generated page). This page is the main page containing the 8 buttons. These buttons are first generated with a "exec ( "gpio read ".$i, $output );" in a for loop. Then we need to detect when the user is clicking on one of these buttons. That's where the JavaScript is useful, I put it in a separate file called "script.js" but it's still included in index.php. The script is simply adding an event listener to all of the eight buttons and each time one of these is pressed, it uses a function which is asking for gpio.php, receiving the answer then returning it. Finally, in function of this, the JavaScript changes the button to red (for OFF) or to green (for ON). Now, the last page: gpio.php. It contains the PHP code to turn on/off the LEDs in function of what the JavaScript function sent. The user shouldn't normally ask for this precise page but there is one golden rule when creating websites and you should always remember this one: "NEVER TRUST THE USER". In other words, never think the user is always gonna do what you think he's gonna do. Thus, I added some securities at the begin of the PHP code like making sure the user gave a correct value and not a letter as example. I made a small diagram to sum up all this text.

You can download the full project directly on this website below.

Web.zip701 KB

Step 6: Conclusion and ideas of improvements

This small but long explained project was fun and I learned a lot. I hope you did the same. However, controlling LEDs isn't very useful. That's why what we made is rather a tool than a real project. Christmas is soon (about one and a half months from the day I wrote this instructable) so why not replacing LEDs by relays and controlling lights around your house. There are some pretty good relay boards for the Raspberry Pi on Ebay and more generally on the Internet. Alternatively, and if you're not scared about working on your house, you can even control your house's lights, garage door, coffee machine, heating system, ... The only limit is your imagination.
There are also a lot of possible improvements like changing the interface, adding more LEDs via a shift register, using vocal recognition, ... In addition, with PHP, you are not limited to gpio write or read. You can use the full Gpio utility and thus interact with other devices with UART or any other implemented protocol. You can also use PWM (Pulse Width Modification) to control servos, ...
Writing this Instructable and sharing my little knowledge was a great pleasure for me and I hope it was the same for you to read it. I tried to keep it simple but at the same time to teach the most possible. I didn't want to do a simple and dumb step by step: "download this code, run it, you're done". I think that something is useless to learn until you understand how it works or why you do this and not that. Let me know if you think it's the good way or if I should do it otherwise.

PS: This is my very first instructable and English is not my native language so if you have any comment, advice, suggestion, idea, ... Just let me know, I'll be glad to answer you and of course to learn.

1-40 of 273Next »


very nicely structured tutorial, however i am stuck at last step the web folder that u have provided where do i have to paste it.

Do i copy the contents to /var/www/ folder or the folder requires to be inside it or any particular file.


TheFreeElectron (author)  rsharma6021 hours ago
Thank you!

You have three files "index", "gpio", "script" and 1 folder "data". Place all of them in the /var/www folder. Just be careful about the access rights.

Hope I Helped,
iQBenQi5 days ago


This is a great project, that has been written extremely well! I am stuck, however, as the images won't load properly (see picture), even though I've followed everything accordingly.



TheFreeElectron (author)  iQBenQi5 days ago
Hi Ben!
Thank you!

If you followed everything written, that's a bit weird that you get this problem. Are the pictures folders placed in the same directory as the php pages? with the correct file tree?
What do you get if you directly ask for the picture via your browser "192.168.1.**/data/img/green/green_0.jpg" for example?
Is the folder correctly owned? (access rights are very often the problem)

That's what I can imagine with what you told me, hope this helps. ;)


It was indeed an issue with Permissions. Managed to get it sorted, thank you very much.

Again, a great project with great instructions.


TheFreeElectron (author)  iQBenQi3 days ago

Glad it now works for you!

Have fun with your Raspberry Pi!

i made email python that send email. well i have a problem. I would like to --- when state of buton changes or I meen , when someone click and change buton from red to green that than I recive email. well i tryed with script.js but nothing worked ..... can you tell me is this posible? over script.js or some kind php code.

TheFreeElectron (author)  gago.babic.35 days ago
Hi !

I already played a bit with python and I have one simple solution: sockets.
No change in the JavaScript but in the gpio.php page. Instead of using the gpio software, you send requests to a python daemon via local port socket. The daemon is a simple script running permanently and listening to a given port. If it receives a request from the php script, it sends a mail or do whatever you want. To sum it up, you have something like this: User -> Html interface -> JavaScript -> PHP script (server side)-> sockets -> Python -> email sent.

Take a look at these pages:

It may look quiet hard but it's actually easy as pie! ;)

Hope I Helped,
i tryed to learn but nothing... i am totaly begginer. Can you do that for me ? if it is not a problem. my server is on 5223 port . i just don't know good enough. never hered for sockets . Please.!
TheFreeElectron (author)  gago.babic.34 days ago

Here's a code I made a while ago;
*index.php hasn't changed.
*Script.js has been cleaned and optimized.
*gpio.php is now using sockets (nothing to modify in it except removing the part receiving the data back)
* has been added, remove the whole wiring pi part and replace with your smtp functions (everything happens in the "main" part around line 123)

Just launch on your Rpi and that should work if you modified everything right. Try to visit the links I gave you to fully understand what's happening.

Hope I Helped,

well I did that. i have error . in line 7 . it say import " wiringpi2 as wp " "no module named wirinpi2". i have wirinpi instaled but i don't know what is wiringpi2. do i have to erase 2 ? and thanx for help.

sorry. i am instaling wiringpi2 than I will see.

TheFreeElectron (author)  gago.babic.34 days ago

As I said, you can remove everything that is not related to the socket server so it also includes the wiring pi library that has nothing to do with it.
Keep lines 1-5, 95-132 and replace:

print >>sys.stderr, 'sending data back to the client'
data = str ( file_shiftOut ( data[0], data, clock, latch ) )

With :

print >>sys.stderr, 'sending mail'
"function sending mail"

You'll have to modify several things if you want the button to change its color when clicking it but you have here the main idea.

it is working. i guess. "starting up on localhost port 1000
waiting for a connection" but my butons are reciving server error. I don't know why. i will study this. but I am afraid that will not be successful
. thanx.

donk113 days ago

Thanks for the excellent project! I put the whole thing together and it works great! Keep up the good work. btw- I am a native english speaker (almost one language under control!) and your english is one step below impeccable.

very awesome!

TheFreeElectron (author)  donk113 days ago
Just a huge thank you! I'm really glad you made it! ;) made it!15 days ago

How to use i2c with it? Could be your next instructable.

TheFreeElectron (author) days ago

I think wiring pi does have a i2c functionality. You should check its reference. And you should be able to do everything via the gpio program and commands.
Unfortunately, I have no longer the time to do projects. Your picture looks really nice, what about writing an 'ible on it yourself ? ;)
ACPixel.19 days ago

hey man i,m kinda new to all this php and javascript mixing stuff... i was wondering how to just make a simple one button and one led. i cant seem to find any good in depth tutorials on ajax and the gpio pins. i would love a little explanation of how everything is being processed. i hate using things that i don't know how/why they work. I'm making all of this through ssh if that helps at all... i just don't really understand how it all works and how the html calls a javascript that calls php and gets values back... thanks for your time <3 i hope you can help me ;)

TheFreeElectron (author)  ACPixel.17 days ago

I really understand the fact that you don't like using things you don't understand, I'm in the same case ;)
Actually the html is just the page's skeleton with the 8 pictures. JavaScript is transforming these pic into clickable buttons. Every time you click one, your browser (executing the script) is asking for the gpio.php page. Actually this page will execute wiring pi commands via "system" and "exec" functions to change the GPIO pins status. Once it read the new status, the php code prints it on the response and that's what the browser gets back. Finally, the JS reads that answer and updates the pic in function of it.

If you want to make a single button, you'll have to modify quite a lot of things. I think that an example has already been posted in one of the comments. You should take a look.

Hope I Helped,


yeah man you totally helped <3 thank you so much!!!

TheFreeElectron (author)  ACPixel.17 days ago

No problem! ;)

AlW218 days ago

Such a useful tutorial and so well written, especially if English isn't your first language.

I'm trying to combine this project with the reading and activation of an NFC reader, which also uses pins 23 (GPIO 11) / 24 (GPIO 8). Is is possible to use alternative GPIO pins with this project??

TheFreeElectron (author)  AlW217 days ago
Really thank you!

Actually, I have been a bit lazy so the Wiring Pi pin's number is directly corresponding to the pic's number. There are two workarounds:
-Add a certain number to the pin's number in gpio.php so instead of using WP pins 0 to 7, you'll be using n to 7+n. In this case, don't forget to subtract back at a moment if necessary.
-Change the pin's number in the JavaScript, you'll probably have more modifications to do.

In both cases, you'll have to be careful. I've put some verification at certain points and they may disturb the process if not adapted to your solution.

Hope I Helped,

hughjeremy21 days ago

Hi there, great tutorial!

I love the idea and it looks great, but from what I can see this runs through the router. How would I make this so that the Rapsberry Pi is creating its own wifi where you can control the GPIO through this.

As another function I would find really useful, if there was a way to activate each pin through a URL link rather than just on a UI. For example when the URL is something like 'raspberrypi.ip/pin2=HIGH' it will set Pin 2 to high. Similar to on this page '' Problem is I don't really understand whats happening over there :(

Thanks very much,


TheFreeElectron (author)  hughjeremy21 days ago
Hi Hugh!

Thank you, that's always a pleasure!

Creating a wifi network between the Rpi and your phone (for example) should be possible. Anyway your phone may have the capability to create the network itself. Ask Google to find a tutorial.

This project is actually working with URL links. The UI is only used to generate the request via JavaScript. This is the line sending the request: "GET" , "gpio.php?pin=" + pin + "&status=" + status );
You ask for the gpio.php page followed by the pin's number and the status. Like "gpio.php?pin=0&status=1"

Hope I Helped,

Brilliant! I suspected, but wasn't sure if I was right.

I really appreciate the time you put into this and helping out, thank you very much!

TheFreeElectron (author)  hughjeremy20 days ago

It'll always be a pleasure! :)

Just thought I'd mention that, with the help of your tutorial, and five others (as well as countless scraps of one line sections of code from google) I have made a Frankenstein of a project that which will automatically unlock my car when I walk up to it, and lock it when I walk away. All I need to do now is wire the car keys instead of LEDs using some optocouplers, which I've done before and is fairly easy.

I'm only 17 and don't have any experience other than self taught tutorials like this that help me so much! So I wanted to say a massive thank you for your awesome tutorial that has helped me to create this first Frankenstein project of mine!

TheFreeElectron (author)  hughjeremy19 days ago

Your "Frankenstein" as you call it, looks amazingly cool! Try optimizing your project, cleaning it up a bit and why not publishing an 'Ible about it?

I'm pretty much in the same case as you, self-taught, just having fun with great things, being curious and discovering more and more! Now it's up to you to make things and share them with people in our case! ;)

Which parts of the script do I have to change if I want to change the commands to sudo rasperry-remote/send 10101 3 1 (and 0 to turn off). I'm just confused because there are a few command with "system" oder "exec" and I have no idea which is used for the commands to send the commands. Thanks for all answers.

I've searched a long time for this solution but I don't have the essential coding skills to adapt this project to my needs. I want to control sockets via WiFi.

TheFreeElectron (author)  AcousticAnimal21 days ago

It's as you said the "system" and "exec" functions that are used to execute commands in a kind of virtual terminal. The expression between tiles is the command, the variable after it is the one used to get the result from this same command.
However you're trying to execute your command as super-user (via sudo) I don't think this will work since apache (or php) isn't super user.

Hope I Helped,

Thank you very very much for the quick answer!

Is it possible to boot the raspberry pi directly into the Rasperry-remote directory? :) This is the project I try to copy (it's german but the commands are the same). What I don't get is if I have to change te system and exec commands in index.php or gpio.php.

TheFreeElectron (author)  AcousticAnimal21 days ago

No problem! ;)
I'm not a linux expert, you better ask google. I don't know if it is possible.
Just use the "system" function:

system( "command" );

This will execute the command but don't know in what directory. I know it is possible to make a program "global" so you can launch it from anywhere you want. Another solution would be giving the program's full path. Try things like that, ask google. That's what I usually do in this kind of situation.

I've quickly watched the video, your project looks really cool! :)

gaelp126 days ago

Hello , we conducted a tutorial that works perfectly, but now we want to insert data from our arduino sensor on our website, but we do not know commme do. Can you please answer us ?

TheFreeElectron (author)  gaelp126 days ago

I think the best way would be creating a script (python or whatever allowing serial and file writing) that you run every x minutes via a cron job. This script is interrogating the arduino about the sensor, receiving the value then writing it into a chosen file. You website would be using some php to read the file and display it on your website. If you want auto-refresh, add some JavaScript asking for the file every x seconds.
That's what I would do, it allows you to keep all your data and they are not dependent on your website.

Hope I Helped,
Syed TalalH29 days ago

Hi, the question is relevant to this article only because I used your concept and extended it to make something like an mp3player. I made a php page which lists all songs in my directory and added javascript clickable links. I have one problem. when it tries to play the song I get this error

" * failed to open vchiq instance". the PHP command I use is system("omxplayer 01.mp3") and song is in the right directory. I tried to play with changing chown,chmod rwx permissions but still no solutions. Any help?

TheFreeElectron (author)  Syed TalalH28 days ago
Hi Syed!

This may help:

I've never used this kind of app but it looks like access rights problems.
deekaylol1 month ago

Hello! Excellent
work, working as it should J I´m just wondering, is It possible to make a timer?
For example in a form of slider? Or interval control? For example turn on from
1 PM to 3PM?

Thank you,

TheFreeElectron (author)  deekaylol1 month ago
Thank You!
As said in some other comments, to add new functions. You have two solutions:
-- Do it in the JavaScript (but it won't work in your case)
-- Create a Python server that will be running permanently (this may be the solution if you have a changing interval with a slider)

Actually, the best way you can achieve this "1PM to 3PM" timer is to create a bash script turning lights off or on. Then you set a cron job to execute this script at the desired hour. You'll find plenty of information on Google.

Hope I Helped,

1-40 of 273Next »