Deprecated: Assigning the return value of new by reference is deprecated in /home/nicholas/public_html/ggnew/components/libraries/cmslib/spframework.php on line 101

Deprecated: Assigning the return value of new by reference is deprecated in /home/nicholas/public_html/ggnew/components/libraries/cmslib/spframework.php on line 644
Web Clicker
Web Clicker
All News -> Projects
Written by Nicholas McClanahan   
Tuesday, 07 September 2010 12:08
web_clicker_icoMake an embedded webserver for Home Automation projects


The Web Clicker is an embedded webserver connected to an IR transceiver.  I've put up an Instructable on how to build it, and here's a video demo;

The Instructable documents how to build it and includes links to the code and schematic, but I thought it would be useful to share my experiences developing it.

HARDWARE

The Web Clicker is built on a Propeller Platform USB and an E-Net module.  A few additional components were added (an IR LED and receiver), but that circuit is very simple.  I built it on a ProtoPlus, but it will fit on any Protoboard.

The Circuit
The Circuit

D1 is an IR LED (mouser part 638-IR333-A), and U1 is an IR receiver (mouser part 782-TSOP4838).  95% of devices use 38kHz modulation, but the IR receiver can be swapped out with another receiver sensitive to a different modulation easily.

Overall, the hardware is very straightforward.  No tricks in reading the IR signal or re-transmitting were necessary.

Firmware: IR Transmit / Receive

I started by grabbing a few objects from the Propeller Object Exchange that were created for IR receive / transmit.  I quickly ran into a problem: my downstairs TV is a JVC, and my upstairs TV is a Sharp.  Neither used the RC5 remote control format or the SIRCS format.  After extended google-ing, I found some documentation on JVC's format.

web_remote_bg1
From Davshomepage

This looked easy enough, although you need to invert it because the IR receiver goes low when it senses an IR signal.  I implemented a basic signal recorder in SPIN: It would wait until the signal went low, then test each 'cell', recording the bit value.  I ran into some problems with this approach — I'm pretty sure SPIN is too slow to catch all the transitions (I would put it in a loop, wait for a transition, then do a few tests on the transition length & how many transitions had been received), and playing back the code wouldn't activate the TV.  Another problem was the repeat portion of the code.  It would broadcast the whole code once, then wait 30-40ms and re-broadcast a portion of the code.

I knew it was time to switch to assembly, but on reflection, I decided to implement something more generic.  I wanted to be able to control multiple devices without understanding their (possibly undocumented) signal format.  I built a generic capture object in Propeller Assembly.

web_remote_bg2
Code with notes

Click on the link above to see the full code with documentation.  It is built to wait until the IR pin goes low, start a timer and note every transition time into a series of longs (32-bit values).  I've uploaded the object to the Object Exchange for others to use.  Development took a while, but using ViewPort helped a lot.  It also was useful using my camera to see when the IR LED was firing.  Because the playback loop only requires a few instructions, that was done in SPIN and should be fast enough for nearly all IR codes.

This worked to record IR commands and play them back.  Now the webserver.

Firmware: Webserver

I started with PropTCP by Harrison Pham.  His code is easy to use.  I started with his AJAX server demo and modified it until I could get an LED to blink.  Once I figured out how to get any arbitrary command running from a CGI request, I was ready to go.  I implemented a few methods;

  • storecommand, start a new cog and record the code received
  • sendcode, transmit an IR command stored at a specific location
  • showcodes, generate HTML displaying currently stored commands
  • clearcommand, clear all the currently stored commands

For ease of coding, I designed it so when the browser requests exec.cgi, it will execute the IR command in the URL string. /exec.cgi?1- would execute the first stored command, the - (minus) served as the end of line character.  This also makes it easy to script IR commands on a PC.  Just request exec.cgi?x- and that command will run.  Requesting stor.cgi started the storecommand method.  And showcodes ran when the browser requested stor.cgi.  That HTML is updated asynchronously (ajax).

One note on using PropTCP: You'll need to set your TCP/IP settings in the program first,

PropTCP settings

  • mac_addr doesn't really matter, you should be able to keep it as is
  • ip_addr The Web Clicker doesn't use DHCP, just pick an IP address on your local network that isn't being used.
  • IP_subnet probably 255.255.255.0.  If that doesn't work, take a look at your PC and see what the subnet setting is — use the same setting on the Web Clicker
  • ip_gateway IP address of your router
  • ip_dns IP address of your router

For my setup, it was pretty easy — just set the gateway and dns to your router, the subnet to 255.255.255.0 and pick an IP address that isn't being used.

Also, PropTCP takes about 16kB, leaving you with 16kB left for your program.  This is a pretty large memory requirement, but you can get around that (somewhat) by using the SD card to store codes, files, etc.

Firmware: HTML & Javascript

The HTML & Javascript are built into the firmware, although they coudl also be stored on an SD card.  The starting point for the code was Harrison's demo, that got me started and I changed the code to fit my needs.

web_remote_bg3
Full Size

On the Propeller, characters are stored in bytes — each byte stores 1 character.  Text strings are zero-terminated, that's why you see a 'byte 0' at the end of each set of lines.  To use a set of lines, you refer to the address where the text is stored.  sock[1].str(@ajax) will return the text stored starting at label 'ajax' all they way until it reaches a zero byte.

The Javascript consists of 3 functions;

  • dupdate, runs onload and updates every 500ms running the ajax function,
  • ajax, updates the listing of stored commands,
  • newcomm, stores a new command

Each of those functions makes a page request, and the webserver watches for the page request, executing a command based on it.

The HTML is pretty basic.  Again, it's stored as a text string, just like the Javascript and it displays the result of the javascript and a basic UI.  There's plenty of room to pretty things up, but the UI is functional.

Summary

I had a lot of fun with this project and I learned a few things;

  • IR control is complicated by all the different signalling formats.  A dumb approach can be more effective.
  • Propeller Assembly is very fast and simple.  Compared to other Assembly on other chips, it's easy to understand what's going on and debug the code.
  • ViewPort saved me a ton of time and helped me to see what was going on inside the chip.
If you've got a Propeller Platform & E-Net, give the Web Clicker a try and let me know what you think!
 

Other Stuff

Get Our RSS Feed

Cool Project