June 30, 2006
This describes a simple embedded web server application that receives data from Oregon Scientific WMR968 Weather Station, and reformats it for web (html) and machine (rss) presentation. The embedded web server was implemented with a Modtronix SBC65EC single-board computer, and with modifications to their existing web server code.
Downloadable source files are located here.
I wanted to make the data from my Oregon Scientific WMR968 Weather Station available for viewing from web browsers, and also to other machine processing systems (in my case my XBox Media Center).
It made sense to do this with an embedded web server because I didn't want to have a dedicated PC committed to serving the data round the clock.
The Oregon Scientific WMR968 (or 918 or 928) receives telemetry data from various sensors and then retransmits it via the serial port periodically (it's not the raw sensor data, but no matter).
The code I produced is a finite state machine that accepts that serial stream and emits interpreted packets when they are fully received. It was the original intent that client code could then bind implementation-defined callbacks, but the -sco option in the C18 compiler prevents that. Instead, I implemented handlers for the packets which simply store the data in a global struct. That struct is essentially a record of the latest values emitted from the weather station.
The web pages are simple, and use the CGI variable substitution mechanism to present the weather station data. There are two web pages, one producing HTML output for use with a browser, the other producing XML output to serve as an rss feed to other systems.
I concentrated on getting the serial FSM working and skimped on some other functionality, like serial port and network setup. Those can be cut-and-pasted from the modtronix code if desired. What I did, however, is simply set up those values in EEPROM from the default web pages before uploading the new web server. If you upload the new server and uncheck the 'update EEPROM data' then those settings will stick. You will need to configure the serial port for:
and set the IP address to whatever you like. (I'll probably integrate that setup into the modified web server one day, but not today. The serial configuration can be hard-coded as it's the only form that the WMR968 will use. Really, only the IP address needs to be made user-configurable.)
Upload the new web server code and web pages, and you should be able to access it like this:
You can also access the data directly:
http://220.127.116.11/wmrhttp.cgi (for the human-readable version)
http://18.104.22.168/wmrrss.cgi (for the machine-processing version)
You should get a web page presenting data like this:
WMR968 Weather Station Current Results
The web pages use the variable substitution 'cgi' method, so you can make whatever fancy web page you like.
You will need to wire a DB-9 connector to the board. Also, the SBC65EC provides a 3-wire (RX,TX,SGND) connection, but the WMR968 requires that RTS be also asserted for it transmit data. You could wire it to an unused T output on IC3, tieing the input to the appropriate level. This would be strictly RS-232 compliant. I was a bit lazier and simply tied the RTS to VCC which worked fine. So, in sum:
|2 (RD)||CON5-3 (rs_rx)|
|3 (TD)||CON5-1 (rs_tx)|
|5 (SGND)||CON5-2 (gnd)|
|7 (RTS)||CON3-8 (vcc)|
There are three remote sensors that I don't have to test with, so there will be some additional work if they are to be supported. I did provide packet definitions for these sensors, so it shouldn't be too hard to accomodate them if needed. The handlers for these packets should be added to _impl_OnNewPkt() in spots that are marked with XXX. Then you can add items to the global structure g_wse for these additional records.
I translated the raw data into Imperial units commonly used here in the USA. Others will probably want metric, so the various conversions in httpexec.c will need to be changed for that.
I have put all the source in a zip file which can be downloaded here. This is the entire web server, which is mostly the Modtronix code. I posted the entire project rather than just posting the modified files so that it would be something immediately buildable.
If you want to rework or otherwise adapt this code it will be useful to know what parts were modified/added. Also, I marked the areas I modified with the tag of HHH so it will be easy to do a text search to find those areas. And of course you can also just do a diff.
|httpexec.c||added handlers for all the additional cgi variables.|
|mxwebsrvr.c||added initialization and task code to the main() routine.|
Added code and web pages:
|src\WMR928_FSM\WMR928_FSM.c, .h||The finite state machine for handling WMR928 serial info, and a global record of the various telemetry data after interpretation.|
|webpages\wmr928\wmrhttp.cgi, wmrrss.cgi||html and rss presentations of the weather station data|
also, there are some test packets I recorded located in:
You probably won't need them but I used them for testing by connecting via a null modem and using HyperTerminal to do an 'upload text file'.
|%w00||count of bad packets received. typically will be 0 unless your electrical connection is glitchy, or if you have some sensors emitting new kinds of packets.|
|Indoor Unit data ('extended barao-thermo-hygo')|
|%w14||percent relative humidity|
|%w16||sea-level compensated pressure|
|outdoor unit (aka 'mushroom')|
|%w34||start date/time of total accumulation|
|%w41||bearing; degrees off of North|
|minutes packet (emitted approximately once per minute)|
|%w50||battery status of weather station|
|date-time packet (emitted approximately hourly)|
|%w60||battery status of weather station|
|%w66||all the information formatted as a timestamp|