Web Page Controlled LED Lights

An HTML page that can send “hello” or “bye” to the Propeller can just as easily control circuits.  For example, with the LEDs connected to P26 and P27 as shown, the web page can send io=pin26state1 to make an LED connected to P26 turn on.  The other three possible combinations are: io=pin27state1, io=pin26state0, io=pin27state0.

Instead of a text field, this example gets its user input from textboxes.  Click the checkbox once, and a checkmark appears and the light turns on.  Click it again, and the checkbox disappears and the light turns off.  With each click of a checkbox, the message the page sends the Propeller (like io=pin26,state1) gets displayed in the page too.

Keep in mind: If you followed the instructions in the Join Another Wi-Fi Network section, you’ll have to replace 192.168.4.1 with the Wi-Fi module’s station IP address.

  • Go to your Wi-Fi module’s Files page at http://192.168.4.1/update-ffs.html.
  • Use the Choose File button to upload page-controls-light.html to your Wi-Fi module and then click Upload.
  • In your web browser, open 192.168.4.1/files/page-controls-light.html.
  • Use SimpleIDE to open Page Controls Light Host.side.
  • Connect your Activity Board to power and your computer, and set PWR to 1.
  • Click SimpleIDE's Run with Terminal button.
  • Verify that SimpleIDE Terminal displays ledId = 1 (any value greater than zero will be fine).
  • Try clicking each checkbox to set a checkmark, and verify that the corresponding P26/P27 LED on the Activity Board emits light.
  • Try clicking each checkbox again and verify that each LED stops emitting light.

 

How it Works - the Web Page

The HTML and JavaScript is very similar to the previous example.  Aside from some variable and function name changes, the main differences are in how the checkboxes are handled. 

When a given checkbox is clicked, the onclick event calls the ledVals function, passing the button’s id -either 26 or 27.  The paragraph with the ledval ID will hold a copy of the text that gets sent to the Propeller through the Wi-Fi module.

The C program running in the Propeller will have a listener filtering for HTTP POSTs with a path named “/leds”.  It also has code that expects a message like “io=pin26state1” to turn the P26 LED on, “io=pin26state0” to turn it off, and so on.  So the ledVals function has to assemble a string with the io=pin#state# information, and pass that and the “/leds” path to the httpPost function.

When you click one of the checkboxes, the browser detects the onclick event and calls ledVals function, passing the html's checkbox id (either 26 or 27) to the ledVals pinId parameter.  Then, var state = document.getElementById(pinId).checked copies the state of that checkbox (true or false) into a variable named state.  Next, var nameVal = “io=pin” + pinId “ “state” + Number(state) uses all that information to put together the “io=pin#state#”.  After printing the nameVal string to the ledval paragraph with document.getElementById…, the httpPost(“/leds”, nameVal) function call passes the “/leds” path and the nameVal variable to the httpPost function.  Remember, the nameVal variable is the one that contains a string that’s something like “io=pin26state1”.  

The checked property is Boolean, that’s true or false. Number(led) converts it to a 1 or 0.  The JavaScript responds to the fact that strings are being added together by automatically converting to “1” or “0” before appending the string.Here’s the httpPost function.  It transmits the “/leds” path and the param string, which will contain a string like “io=pin26state1” to the Parallax Wi-Fi module that’s hosting the web page, and the module in turn relays that information to the Propeller.  

The string “io=pin26state1” is considered a post parameter that consists of a name-value pair.  The name is “io” and the value is “pin26state1”.

 

How it Works - the Propeller C Code

The fourth line is where this program starts to differ from the previous example.  Instead of just declaring postFromPageId, this program instead declares a variable named ledId, along with variables named pin and state.  The main function starts off the same, calling wifi_start.  In the previous program, the second line in the main function was postFromPageId = wifi_listen(HTTP, "/fptm").  That's because the previous page's JavaScript sent its POST requests with the "/fptm" path.  The JavaScript in this example sends its POST requests to a different path: "/leds".  So, this program uses ledId = wifi_listen(HTTP, "/leds") to:

  • Set up a listener that monitors for HTTP requests with a path of "/leds"
  • Store the listener ID in a variable named ledId

After that, it uses simpletools library set_direction function calls to set P26 and P27 to outputs (since the main loop will need to turn those lights on/off). 

#include "simpletools.h"
#include "wifi.h"

int event, id, handle;
int ledId, pin, state;

int main()
{
  wifi_start(31, 30, 115200, WX_ALL_COM);
  ledId = wifi_listen(HTTP, "/leds");
  print("ledId = %d\n", ledId);
 
  set_direction(26, 1);
  set_direction(27, 1);

  while(1)
  {
    wifi_poll(&event, &id, &handle);
    print("event = %c, id = %d, handle = %d\r", event, id, handle);
    if(event == 'P')
    {
      if(id == ledId)
      {
        print("Incoming POST request\r");
        wifi_scan(POST, handle, "io%d%d", &pin, &state);
        print("pin=%d, state=%d\n", pin, state);
        set_output(pin, state);
      }        
    }
    pause(500);
  }    
}

Every time through the while(1) loop, wifi_poll(&event, &id, &handle) checks if any listeners reported events.  If there are no events, the event variable will store 'N', and handle & id will both store 0.  When a POST request from the browser comes through with a path of "/leds" wifi_poll will set event to 'P', id to whatever value ledId stored during the initialization, and handle to a value the program will use to retrieve the post body.  When event stores 'P' and id matches ledId, the program prints the incoming POST request message, then calls wifi_scan

Instead of the previous example's wifi_scan(POST, handle, "txt%s", &s), this program uses wifi_scan(POST, handle, "io%d%d, &pin &state).  The io tells the Wi-Fi module to reply with the value part of a POST that contain something like io=pin26state1.  In this example, the Wi-Fi module sends "pin26state1".  The %d%d places the first two text strings that represent integer values (like 26 and 1) into the two variable parameters in the list that follows the format string: &pin and &state.  This happens in about the same way that the scan statement from Print and Scan Function Review captured that string when you typed it into the SimpleIDE terminal.  

With the pin and state variables containing meaningful values, print("pin = %d, state = %d\r", pin, state) displays those values in the terminal.  Then, set_output(pin, state) from the simpletools library uses those values to turn P26 or P27 on or off.  The pause(500) before repeating the while(1) loop mainly prevents sending data to the SimpleIDE Terminal faster than a human could follow along.