Instructables

Simple and intuitive web interface for your Raspberry Pi

Featured
Picture of Simple and intuitive web interface for your Raspberry Pi
P1040971.JPG
P1040976.JPG
P1040977.JPG
P1040978.JPG
     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: http://www.instructables.com/id/Web-Controlled-8-Channel-Powerstrip/. Thanks to Rleddington for his amazing project.

 
Remove these adsRemove these ads by Signing Up

Step 1: The electronic part

Simple.JPG
P1040967.JPG
P1040968.JPG
raspberry-pi-rev2-gpio-pinout.jpg
     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: http://wiringpi.com/) 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: http://wiringpi.com/pins/ (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: http://wiringpi.com/download-and-install/. 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: http://wiringpi.com/reference/ (library's functions) and https://projects.drogon.net/raspberry-pi/wiringpi/the-gpio-utility/ 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:
 
#!/bin/bash

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

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

#wait 2 seconds
sleep 2;

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

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:
 
<?php
     phpinfo();

?>

     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:
 
<?php
     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:
 
<?php
     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:
 
<?php
$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

     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 at: http://www.mediafire.com/download/1rgs4t52o8ptd5r/Web.zip
 

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.

Step 7: The full code

Here is the full project, you can still download it but here is the code just in the case you have troubles downloading the project. You need to create three files named index.php gpio.php and script.js ; a directory named data in which you place two other directories called green and red ; then put the different buttons in their respective directories. You may need to rename them from red_0.jpg to red_7.jpg and from green_0.jpg to green_7.jpg.

index.php : 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Raspberry Pi Gpio</title>
    </head>

    <body style="background-color: black;">
     <!-- On/Off button's picture -->
  <?php
  //this php script generate the first page in function of the gpio's status
  $status = array (0, 0, 0, 0, 0, 0, 0, 0);
  for ($i = 0; $i < count($status); $i++) {
  //set the pin's mode to output and read them
  system("gpio mode ".$pin." out");
  exec ("gpio read ".$i, $status[$i], $return );
  //if off
  if ($status[$i][0] == 0 ) {
  echo ("<img id='button_".$i."' src='data/img/red/red_".$i.".jpg' alt='off'/>");
  }
  //if on
  if ($status[$i][0] == 1 ) {
  echo ("<img id='button_".$i."' src='data/img/green/green_".$i.".jpg' alt='on'/>");
  } 
  }
  ?>
 
  <!-- javascript -->
  <script src="script.js"></script>
    </body>
</html>



gpio.php : 


<!-- This page is requested by the JavaScript, it updates the pin's status and then print it -->
<?php
//Getting and using values
if (isset ($_GET["pin"]) && isset($_GET["status"]) ) {
$pin = strip_tags($_GET["pin"]);
$status = strip_tags($_GET["status"]);
//Testing if values are numbers
if ( (is_numeric($pin)) && (is_numeric($status)) && ($pin <= 7) && ($pin >= 0) && ($status == "0") || ($status == "1") ) {
  //set the gpio's mode to output 
  system("gpio mode ".$pin." out");
  //set the gpio to high/low
  if ($status == "0" ) { $status = "1"; }
  else if ($status == "1" ) { $status = "0"; }
  system("gpio write ".$pin." ".$status );
  //reading pin's status
  exec ("gpio read ".$pin, $status, $return );
  //printing it
  echo ( $status[0] );
}
else { echo ("fail"); }
} //print fail if cannot use values
else { echo ("fail"); }
?>



script.js : 


//JavaScript, use pictures as buttons, sends and receives values to/from the Rpi
//These are all the buttons
var button_0 = document.getElementById("button_0");
var button_1 = document.getElementById("button_1");
var button_2 = document.getElementById("button_2");
var button_3 = document.getElementById("button_3");
var button_4 = document.getElementById("button_4");
var button_5 = document.getElementById("button_5");
var button_6 = document.getElementById("button_6");
var button_7 = document.getElementById("button_7");


//this function sends and receives the pin's status
function change_pin (pin, status) {
//this is the http request
var request = new XMLHttpRequest();
request.open( "GET" , "gpio.php?pin=" + pin + "&status=" + status );
request.send(null);
//receiving information
request.onreadystatechange = function () {
  if (request.readyState == 4 && request.status == 200) {
   return (parseInt(request.responseText));
  }
//test if fail
  else if (request.readyState == 4 && request.status == 500) {
   alert ("server error");
   return ("fail");
  }
//else
  else { return ("fail"); }
}
}

//these are all the button's events, it just calls the change_pin function and updates the page in function of the return of it.
button_0.addEventListener("click", function () {
//if red
if ( button_0.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 0, 0);
  if (new_status !== "fail") {
   button_0.alt = "on"
   button_0.src = "data/img/green/green_0.jpg";
   return 0;
   }
  }
//if green
if ( button_0.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 0, 1);
  if (new_status !== "fail") {
   button_0.alt = "off"
   button_0.src = "data/img/red/red_0.jpg";
   return 0;
   }
  }
} );

button_1.addEventListener("click", function () {
//if red
if ( button_1.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 1, 0);
  if (new_status !== "fail") {
   button_1.alt = "on"
   button_1.src = "data/img/green/green_1.jpg";
   return 0;
   }
  }
//if green
if ( button_1.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 1, 1);
  if (new_status !== "fail") {
   button_1.alt = "off"
   button_1.src = "data/img/red/red_1.jpg";
   return 0;
   }
  }
} );

button_2.addEventListener("click", function () {
//if red
if ( button_2.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 2, 0);
  if (new_status !== "fail") {
   button_2.alt = "on"
   button_2.src = "data/img/green/green_2.jpg";
   return 0;
   }
  }
//if green
if ( button_2.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 2, 1);
  if (new_status !== "fail") {
   button_2.alt = "off"
   button_2.src = "data/img/red/red_2.jpg";
   return 0;
   }
  }
} );

button_3.addEventListener("click", function () {
//if red
if ( button_3.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 3, 0);
  if (new_status !== "fail") {
   button_3.alt = "on"
   button_3.src = "data/img/green/green_3.jpg";
   return 0;
   }
  }
//if green
if ( button_3.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 3, 1);
  if (new_status !== "fail") {
   button_3.alt = "off"
   button_3.src = "data/img/red/red_3.jpg";
   return 0;
   }
  }
} );

button_4.addEventListener("click", function () {
//if red
if ( button_4.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 4, 0);
  if (new_status !== "fail") {
   button_4.alt = "on"
   button_4.src = "data/img/green/green_4.jpg";
   return 0;
   }
  }
//if green
if ( button_4.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 4, 1);
  if (new_status !== "fail") {
   button_4.alt = "off"
   button_4.src = "data/img/red/red_4.jpg";
   return 0;
   }
  }
} );

button_5.addEventListener("click", function () {
//if red
if ( button_5.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 5, 0);
  if (new_status !== "fail") {
   button_5.alt = "on"
   button_5.src = "data/img/green/green_5.jpg";
   return 0;
   }
  }
//if green
if ( button_5.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 5, 1);
  if (new_status !== "fail") {
   button_5.alt = "off"
   button_5.src = "data/img/red/red_5.jpg";
   return 0;
   }
  }
} );

button_6.addEventListener("click", function () {
//if red
if ( button_6.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 6, 0);
  if (new_status !== "fail") {
   button_6.alt = "on"
   button_6.src = "data/img/green/green_6.jpg";
   return 0;
   }
  }
//if green
if ( button_6.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 6, 1);
  if (new_status !== "fail") {
   button_6.alt = "off"
   button_6.src = "data/img/red/red_6.jpg";
   return 0;
   }
  }
} );

button_7.addEventListener("click", function () {
//if red
if ( button_7.alt === "off" ) {
  //use the function
  var new_status = change_pin ( 7, 0);
  if (new_status !== "fail") {
   button_7.alt = "on"
   button_7.src = "data/img/green/green_7.jpg";
   return 0;
   }
  }
//if green
if ( button_7.alt === "on" ) {
  //use the function
  var new_status = change_pin ( 7, 1);
  if (new_status !== "fail") {
   button_7.alt = "off"
   button_7.src = "data/img/red/red_7.jpg";
   return 0;
   }
  }
} );
felipemundy4 hours ago
Hayaalsh20 days ago

Hello TheFreeElectron :)

Thank you for this amazing tutorial!
but I have a question. One of the members said that they
can control the LED lights from New-Zealand! However, I cannot control the pi
unless the pi and my Smartphone are connected to the same network.

Is there any way to control the pi
from any place in the world without the need of being connected to the same
network?

I hope you get what I mean.

please answer me :(

Hayaalsh19 days ago

Hi again,

I have another 2 questions:

Can I use LED light bulb instead of those small LED lights?

And can I control things other than light? like a small motor? or it would require more power?

justcus1 month ago

I am unable to download

You can download the full project at: http://www.mediafire.com/download/1rgs4t52o8ptd5r/Web.zip

Any help would be greatly appreciated!

TheFreeElectron (author)  justcus1 month ago

Hi Justcus,

It still works for me. A further description of the problem would be useful.

I have tried to download the web.zip file using IE11 and Google Chrome but to no avail. When I click on the download button, I am usually directed to another site and it downloads other files that I am suspicious of. Other times I get "This Page Can't Be Displayed. Is there another way to get the file?

Thanks,

TheFreeElectron (author)  justcus28 days ago

Hi Justcus,

I've tried downloading the file on other computers and platforms, all of them worked. It's maybe a network configuration problem. Have you tried the other links in the comments?

Hi TheFreeElectron,

I forgot to applaud you on the great project. I have it working up to the point of setting up the iPhone or Android to control the Raspberry Pi. I don't know crap about programming these days so the step by step was great. I last programmed in assembler and BASIC for the 8080A (1976) after that it was all appliance computing.

I tried one other the was on mediafire.com/download/xxxx/xxx.zip and had the same problem. Maybe it is my firewall or antivirus. My pea brain just doesn't work so good anymore. Can the file be placed in dropbox or can it be downloaded from a ftp site. As far as my network configuration I think it is OK I have downloaded files from other sites without any problems. The older I get the more about computers I have forgotten. CRS!

Thanks,

TheFreeElectron (author)  justcus25 days ago

Hi Justcus,

Definitely you won't stop harassing me (just kidding, there's no problem). Thank you for your comment, that's always interesting to exchange experiences and thoughts with others, writing this 'Ible was a real pleasure and finally, knowing that some people actually learned something by reading what I wrote is an even greater pleasure. By the way, I wasn't even born in 1976 and I've never heard about the 8080A. ;)

Concerning your problem, I didn't take the risk of another website not to work so I added a new "last" step in which I pasted the whole code and uploaded the different pictures.

Cheers,

TheFreeElectron

Thanks so much for the finishing touch!!!

When you don't have anything to do, look up IMSAI 8080. That is where it all started for me. Keep up the excellent work!!!

Again thanks,

kounenos1 month ago

Hey TheFreeElectron,

First of all thanks for this nice Tutorial it helped me a lot with web interface! i 'm new in web interface and i try to upload the files in /var/www with WinSCP and tells me

Permission denied.
Error code: 3
Error message from server: Permission denied

you can help me a little?

TheFreeElectron (author)  kounenos1 month ago

Hi Kouenos,

This problem is surely caused by the fact that the user you're connecting with (probably pi) isn't owning the www directory (therefore doesn't have read/write rights in it). You need to use the command "sudo chown -R pi /var/www" if pi is your user.

If this is not the cause, I do not see other possible reasons, maybe a configuration problem. Try the "ls -l" command to check who's having the rights on this folder.

Hope I helped,

TheFreeElectron

motzer1 month ago
Hey TheFreeElectron,

first of all thanks for this nice Tutorial - it helped me a lot! I am using your start to controll som Remote sockets. There is a little problem with my web programming skills =) So the Problem is to switch one socket on you have to set two GPIOs High for a short amount of time (~1sec) and then one of these Ports has to bet set Low again after this second. And tried it now for hours but no solution.

Little Example what I tried in the javascript file:

var new_status = change_pin ( 0, 0);
var new_status = change_pin ( 4, 1);
setTimeout(change_pin( 4, 0),1000);

So Pin 0 and 4 are the two GPIOs to set, but Pin 4 has to be toggled after one second. With this code it works sometimes and sometimes not on clicks so sometimes Pin4 is set LOW and sometimes not. Do you have an idea or a advice for me to solve this "small" Problem?

PseudoCode
Set Pin 0 and 4 High
Change Button0 Picture to Green
wait 1 secodn
Set pin 4 Low again

Cheers,
Ben
TheFreeElectron (author)  motzer1 month ago

Hi Ben,

Thank you for your comment and your feedback, I really appreciate.

As I understood your idea, you push one button to turn high two GPIO ports, then 1 second after, one of the two ports is turned low. Correct me if I'm wrong.

I'm not really a pro of JavaScript but you're setting the new_status variable to what the change_pin function returns for (0,0) then for (4,1) without doing anything between or after. You're also setting the pin 0 to 0 <=> LOW (first line). That's what I can say about your code example.

After that, dealing with the delays as the client doesn't seem, to me, a good idea. You can do this in the PHP script using the sleep( TIME_IN_SECONDS ) function. Or by using the method I described in several comments below (using a python daemon and a PHP page to make the link). Here's an example I wrote for another 'Ible: http://www.mediafire.com/download/p88afnrybdmxsu6/... It isn't including a delay but it's still very interesting to understand the method. You just need to run the gpio_server.py file and to put the rest in your www folder. I also corrected several bugs and "upgraded" the way the project works. Again that's just a personal opinion and using JS is also a good idea.

Hope I helped, do not hesitate If you have any other questions/problems.

Cheers,

TheFreeElectron.

ainsey111 month ago

Hi ThefreeElectron,

First of all - what a brilliant 'ible. I think this is great for any fun little project :)

However I get PHP errors when running /gpio.php - it comes back with fail. also index.php just gives me a blank screen.However when i rename the file from .php to .html I get a black screen with a missing picture symbol...

I have copied the files from your Web_simple folder into the root of /var/www.

my lights also change when I issue for i in 0 1 2 3 4 5 6 7 ; do gpio write $i 1; done

Am I missing something obvious?

Cheers,

Ainsey11

TheFreeElectron (author)  ainsey111 month ago

Hi Ainsey11,

Thank you for your comment, I really appreciate your feedback!

Concerning your problem(s), I can only give several clues:

  • Firstly, you can't run gpio.php alone, it needs parameters sent through the URL. You get a "fail" because of the protection I put to be sure the user did input values, therefore you should type something like "gpio.php?pin=PIN_VALUE&status=CURRENT_STATUS".
  • I do not see why you would get a blank screen when running index.php. However, it seems you're running the pages with the php program in a command line. If it's true, it may be the problem.
  • Renaming the file to .html will tell the server NOT to execute the php code, that's probably why the pictures are missing.
  • Finally Web_simple is a modified version of the original script I made for Singhdeolji and I haven't tested it, he may have done several modifications for it to work but I don't think it's the case.

That's all I'm thinking about now, I'm maybe missing something too but it's hard to solve problems hundred (maybe thousands) of miles away ;) If it still doesn't work, keep trying and try to understand why, but I hope it will.

Cheers, TheFreeElectron.

Hello TheFreeElectron,

Good news! I have managed to get it working :) I spotted that on line 25 you had a random } as soon as I removed this it all worked fine. However when running the web page I can only see one button (see image) This button works perfectly but I have no idea how to add the other 7, would you be able to assist?

Have a great day,

Ainsey11

Capture.PNG
TheFreeElectron (author)  ainsey111 month ago

No problem, it was a pleasure.

Keep going, there are a lot of possible things to do with this simple project ;)

Cheers, TheFreeElectron.

Hi Again,

All is working again :) I didn't spot the full web.zip folder..

Great 'ible- thanks for all of your help, keep it up :)

Thanks,

Ainsey11

jeffpagnutti2 months ago

I think this is my first comment on instructables, but I really think that this is a great tutorial and just wanted to say great job. Thanks for the instructable! Cheers, Jeff.

TheFreeElectron (author)  jeffpagnutti1 month ago
Hi Jeff,
Thanks for your comment, I'm glad you liked my Instructable!
Don't hesitate if you have any question.
Cheers, TheFreeElectron.
nicolluch2 months ago

great project! only if a can walk through my ignorance to make it work!

I can't put the server to work. working with att dsl modem -> router -> cat5 to pi. I have internet on pi.

I'm getting my ip with 'what's my ip on' google, then write that on the browser, and it doesn't find it.

already tried everithing you suggest, on two SD cards and not wirking, really frustrating!

Any ideas? thanks again!!

TheFreeElectron (author)  nicolluch2 months ago
Hi Nicolluch,

Your problem is in fact really simple, what I'm doing in this 'Ible is accessing the Rpi over my house's local network. That's why the ip address looks like 192.168.1.xx. If you want this ip, just take a look at your router's page (generally by typing 192.168.1.1 in your browser) or type the "ifconfig" command in your Rpi's command line.
In fact each device in your house is having two ip's. The LAN ip (Local Area Network) which is the ip of your device in your local network. Then there is the WAN ip (Wide Area Network), this one is in fact the ip of your router and therefore is the same for all the devices in your house. What you're getting when using services like "whatismyip.com" is the wan ip.
If you want to access to your Rpi over the Internet, you first need to forward the http port (or any others) to your Rpi. It means that when someone will try to connect to your WAN ip, the request will be redirected to your Rpi. Then you can access to your Rpi over the Internet.

Hope I solved your problem, TheFreeElectron.

Thanks! I was half way there, now it's working!

I'm on the hardware side, working on a home automation system, if you need anything, let me know.

thanks again

TheFreeElectron (author)  nicolluch2 months ago
No problem, it was a pleasure.
I hope to see soon an 'Ible of your Home automation system. ;)
NiBa3 months ago

This is awesome, thanks!

BTW, I would like to know some more about this nice project and I have two questions here:

I did everything similarly as in your tutorial, but my leds are on when they should be off so the operation of them are inverted somehow?

I'm totally new with javascript and php so sorry if I'm disturbing. It would be great if there is some way to change the turn on action of the led so I could generate just a one pulse by clicking on and another pulse when turning off. With this it would be possible to control devices with the pulses. What I'm trying to explain, raspberry gpio signal stays up until on or off is clicked.

TheFreeElectron (author)  NiBa3 months ago
Hi Niba,
No problem, thanks for your comment.
To answer your first question, I do not see why a problem like this would happen. You should use the developer's tools of your browser to see what you're sending when clicking one of the button then what you're receiving. The fact that the LEDs are inverted may signify that the first inversion happened when generating the index page. You should therefore check the source code of that page to see what is the value of the "alt" variable. However, it's hard for me to resolve this kind of problem without having it in front of me.
Concerning your second question, that wouldn't be a problem since everything is done by the gpio.php page, you would just need to modify the code and/or the different commands to do whatever you want. The Gpio Utility is allowing you to do nearly whatever you would like to do. This method is however very slow when it comes to complex things. You should check the "Python daemon" method I described in some other comments, it's a lot faster and safer.

Do not hesitate if you have any other questions, you're not disturbing, far from it. It's really interesting for me to get feedback from other members.

Have a good day, TheFreeElectron.
singhdeolji3 months ago

First of all i must say " great work!!!!!", I am new to php/javascript or even html for that matter, i have been trying to understand your project and try to dumb your project down to a single html button, which turn a led on [or something even more basic]. If its not too much to ask..... perhaps a little example code. thx in advance.

TheFreeElectron (author)  singhdeolji3 months ago

Hi Singhdeolji, Thanks for your comment.

Concerning the code, I'll try to explain it to you then I'll give an example. The first thing to do is to generate the buttons of the index, I'm using php code directly inside of the home page. After that, the JavaScript watch if you are clicking one of the buttons, if you are, it sends a request the gpio page. This page is then receiving the number of the LED you wanna change then executing the same code you would be executing yourself in a terminal. Finally, this page is sending back the status of the LED, the JavaScript reading this status then updating the button's color in function of it.

Here's an example for one button but I haven't tested it: http://www.mediafire.com/download/2z3h7g4yjeoc7be/...

Hope I answered your questions,

TheFreeElectron

Thx for the quick reply man!!!
Every thing is running smooth, i put you files in the www folder, went to the browser, even on my phone + even my cousin sitting in Newzeland turn the led on off.
[but every thing is too magical if you kw what i mean............]
So i figured i need to understand the php & ajax relationship here first to get a grasp on things. So after doing some research, i came up with code where i have a php.code, html.code.
In the html code i have the input "text" & "submit". and also the httprequest function(). The function takes what I type in the html text area, and set it to a variable. then the var gets send to the php file(using POST instead of GET, not so sure abt either of them). I also have a html div tag and its name ="status", which display responsetext (returndata =http.responseText) from the server.
like- document.getElementById("status").innerHTML = returndata;

In the PHP file, i simple get the text value, put it in a var and add 1 to it. Then echo the result.

So when on my html page i type 1 in the text box, then press submit. i get back a result of 2.
My question is: Why would this approach works or am i missing some very basic like- checking the wrong pin or something else.
<?php

$x=$_POST['text'];

if ($x=='1'){

system("gpio mode 15 out");

system("gpio write 15 .$x.");

system("gpio write 15 0")

}

?>

If i run the php file from the command line(php filename.php) taking out the first two lines it works,[ pi's(pin 8)== gpio(pin 14) == wiring pi(15) ]
But when i run it through the browser nothing happens.

TheFreeElectron (author)  singhdeolji3 months ago
No problem, it's a pleasure to know that your cousin can now turn your LED on/off from New-Zealand. ;)
So as I understood, you are using a text input and a submit button which is managed by a JavaScript "script". This one sends the input to a php code which is executing the commands then sending back the value and finally the JavaScript is modifying the content of a textarea in function of this.
I see no possible errors in using this method so the problem should be somewhere in the code.
1) I don't know if it's an error you made when typing the message or a real error, but the $x of the 5th line shouldn't be within the quotes, rather like system("gpio write 15 ".$x);
2) Are you sure about the type of the variable or the value itself? You should add more tests at the beginning of your php code.
3) You should install a Wamp server on your computer (or Xamp/Lamp depending on your OS). It is very useful since the errors are displayed and it tells you why your code isn't working. It would therefore allow you to debug the part of the code which is receiving and using the variable. You would just have to comment the lines working only on the Rpi (system,...).
4) You are turning off the LED directly after having turned it on, why not adding a delay.
5) The fact that the code is working when using it in the command line is a little bit weird but it shows that connections are good and that the problem is rather coming from the variable.

Again, it's hard to answer without having hands on the code but I hope you'll find a solution (maybe in this comment ;). Do not hesitate to ask if you have any other question.

Greetings, TheFreeElectron.

PS: If you're still wondering, the difference between POST and GET is easy. GET is transmitting the data via the URL, and POST via the request's body. The only practical difference is that a POST request is harder to build in JS.

just got back from work, decided to give this an another shot!!!!
Its is quite ridiculous that its was just a syntax error. instead of system("gpio mode 15".$x), It needed an space between 15 "
But ya i was so convinced for some reason that this approach was not possible don't know why?
May be i have been quite a history of disappointment and struggle to get something like this to work..
i actually started with using java (only language i kw) to control GPIO pin, i came accross "pi4j" a libraray to control GPIO using java. > Then i want to do it over the network, thats when the struggle begin.
then looked into html>javascript >node.js>+several node.js modules>finally php/ajax
I really appreciate your help man!!!!!!!!
Now need to look into some php IDE's for debugging/errors. I give eclipse a shot, may be a php plugin for it, as i am already familiar with it.

TheFreeElectron (author)  singhdeolji3 months ago
Hi Singhdeolji,
I'm glad to know that your setup is now working (sometimes the smallest errors are the most annoying).
Concerning developing in php/html/JS, I'm personally using Notepad++ and a SFTP client to upload the files. After, I'm also using a Wamp Server on my computer since, as I said it before, it tells you what went wrong (like a debugger) instead of stupidly returning a 500 server error. It is very useful when you are working on a website that doesn't require anything specific to the Rpi. The developer tools of your browser may be very useful too.

Have fun developing, TheFreeElectron.
hxc3 months ago
can u give block diagram?
TheFreeElectron (author)  hxc3 months ago
Hi hxc, Here is one I made quickly:
Block diagram.JPG
thx for the block diagram.....but..i need list of hardware and software for this project....
TheFreeElectron (author)  hxc3 months ago
For this project, you'll need:
*Hardware:
-A Raspberry Pi (obviously)
-8 resistors (270 Ohms or more)
-8 LEDs
-Some cables
-A breadboard

*Software:
-Apache2 Webserver
-PHP5 extension for Apache
-WiringPi library (=>You get the Gpio utility when you build the library)

You'll also need a ssh client and a sftp client on your own computer.
ihrozny3 months ago
hello,
next one great instructable,
i have one question, can be this project somehow changet to "led dimmer" ?
all the functions be the same, eg. web connection, 8ch.. but the dimming mode instead of on/off for each channel ?

Sorry for my english, im only begginer, but hope you understand :)
Ivan
TheFreeElectron (author)  ihrozny3 months ago
Hi Ivan, Thanks for your comment.
As I understood your question, you would like to vary the brightness of each of the 8 LEDs and each LED would be independant.
-The web interface would be changed into 8 sliders (and maybe a submit button to reduce network usage).
-I'm not sure that all the pins support PWM (Pulse Width Modification to vary the brightness) so you may need another chip to add more.
-Concerning the PHP code you can use the "gpio pwm pin value" command (See this page for more information.) but if you are using another chip, you better be running a python script (The wiringPi library has its equivalent in python) waiting for incoming TCP connections and then transmitting the data to the chip, the PHP script would receive the data from the HTTP request and then transmit it to the python script by a TCP socket on the localhost port. Here is a little chain to explain better:
HTML slider => JavaScript => HTTP request => PHP script => TCP socket => Python script => Wiring Pi library => (chip =>) LEDs. The two underlined expressions are the protocols used to transmit data.
This method may seem a lot harder and slower but it is in fact really fast and this avoids commands to overlap (Apache can run two or more php scripts at the same time).

I hope I answered your question and if you have any other request, you can reply or send me a message.
Greetings, TheFreeElectron.

PS: You're not the only one who's learning english ;)

Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!