Weatherstation based on WebControl8

rossw

Active Member
I wasn't going to put this in the public eye just yet, but who knows when I'll get back to it.
 
This is definitely a "work in progress", and will probably need substantial additional work but for anyone who's interested, here's the guts of a working system.
 
This is designed as an extensible system that can handle a great number of weatherstations. Each station initiates the communication with the server, but the server then controls what is sent and how often. The version presented here supports only a precision barometric pressure and temperature sensor, wind direction, average windspeed and 3-second-wind-gust speed. The system can easily support rain gauge, pyranometer, UV sensor, multiple temperature sensors (eg, soil temperature, shaded, direct exposure, inside) and pretty much anything else you can connect to a WC8.
 
The URL it submits to isn't being made public at this point, because each station will need a unique identifier and I haven't set up a system to provide them. The server-side code isn't being released.
 
Basically, on power-up, the system waits for the board and attached devices to settle, then initiates a call to the server. The server will identify the IP address of the station. If it isn't already known, the server sends back a response that causes the station to return a number of parameters including the stations ID, altitude, sensor calibration details etc. The server then instructs the station to send each of its sensor values, one at a time, and finally, tells the station when to call again. This lets the server synchronise all remote stations to send data when it's needed.
 
The server will never initiate communications with the station, thus the station can be behind a NAT router, or firewall, with no problems.
 
Assuming there's any interest, I'll post circuits of the interface etc. I've used over-the-counter spare parts, and inexpensive common parts from ebay.
 
Enjoy...
 

Code:
START    

tsync:

        tstle CYEAR 2013        ; has time synchronised yet?

        goto tsync              ; wait until it has



        set COUNTER 0           ; clear wind counter

        set var8 0

        add cts 10 var1         ; wait before calling home.

        delay 30                ; wait for chip to settle



loop:                           ; loop entry after an action is completed

        set wsrply 0            ; clear webreply flag

wait:

        sub cts ram6 ram1       ; time from last to now

        bz notsec               ; not a new second, check other stuff

        set ram6 cts

        sub COUNTER ram8H ram1  ; current counter-(3secAgo)

        tstgt ram1 ram7L        ; higher than last highest?

        set ram7L ram1          ; save highest per-3-seconds value

        set ram8H ram8L         ; ripple

        set ram8L ram7H

        set ram7H COUNTER       ; current 3 seconds ago in 8H, 2 in 8L 1 in 7H.

        set var7 ram7L     ; for debugging



notsec:

        andb wsrply 255 ram1    ; get reply code

        set var2 cts      ; also for debugging

        tstne ram1 1            ; reply ?

        goto n1

        div wsrply 256 ram1     ; shift answer to get seconds

        add cts ram1 var1       ; set next response time

        goto loop               ; clear flag and wait



n1:

        tstne ram1 2            ; is it cmd2 ? (send avg wind speed)

        goto n2

        set ram1 wsrply

        sub cts var8 ram2       ; seconds since last windspeed

        mul COUNTER 10 ram3     ; *10 for a extra precision

        div ram3 ram2 ram1H     ; pulses/second = metres/second

        webset url3 ram1        ; send

        goto loop



n2:

        tstne ram1 3            ; is it cmd3 ? (send wind gust)

        goto n3

        set ram1 wsrply

        mul ram7L 10 ram2       ; *10 for extra precision

        div ram2 3 ram1H        ; but it was over 3 seconds

        webset URL3 ram1        ; send

        goto loop



n3:

        tstne ram1 4            ; is it cmd4 ? (wind direction)

        goto n4

        mul aip1 360 ram2       ; input 0-5V = 360 degrees.

        div ram2 500 ram2       ; scale

        mod ram2 359 ram1H      ; angle is 0-359 degrees

        set ram1L wsrply

        webset url3 ram1        ; and clear counters

        set COUNTER 0

        set ram7L 0             ; clear high

        set var8 cts            ; and set timestamp

        goto loop



n4:

        tstne ram1 20           ; is it cmd20 ? (send my ID)

        goto n20

        set ram1 wsrply

        set ram1H urom1         ; build reply

        webset url3 ram1

        goto loop



n20:

        tstle ram1 20           ; is reply 21 or upwards?

        goto ncal

        tsteq ram1 21           ; cal21 = UROM1 (ID)

        set ram2H urom1

        tsteq ram1 22           ; cal22 = UROM2 (altitude in m AMSL)

        set ram2H urom2

        tsteq ram1 23           ; cal23 = UROM3 (wind direction offset from north in degrees)

        set ram2H urom3

        tsteq ram1 24           ; cal24 = UROM4 (unused for now)

        set ram2H urom4

        tstle ram1 24           ; send UROM cal now

        goto sendurom

        sub ram1 25 ram1        ; convert to offset

        mul ram1 2 ram1         ; double byte offset as required

        add ram1 0xaa ram1      ; convert to calibration offset 11->0xaa (1st word), 12->0xab (2nd word) etc

        callsub get             ; read calibration data specified word

        set ram2H ram1L

sendurom:

        set ram2L wsrply

        webset URL3 ram2        ; send back cal data in upper 16 bits, ID in lower 16 bits

        goto loop               ; send data, clear flag and wait



ncal:

        tstlt cts var1          ; time to call home yet?

        goto wait               ; no



        i2cwrite 1 0 0xee       ; set up for temperature conversion

        i2cwrite 0 0 0xf4

        i2cwrite 0 1 0x2e

        delay 10                ; brief pause for conversion to complete

        set ram1 0xf6           ; read back uncompensated temperature

        callsub get

        set ram2H ram1L         ; save temp into high byte of ram2



        i2cwrite 1 0 0xee       ; set up for pressure conversion

        i2cwrite 0 0 0xf4

        i2cwrite 0 1 0x34       ; OSS x34 for single read, xf4 for max oversample

        delay 80                ; brief pause for conversion to complete

        set ram1 0xf6           ; read back uncompensated pressure

        callsub get

        set ram2L ram1L         ; add pressure

        webset URL3 ram2        ; log

        add cts 30 var1         ; do not loop too fast

        goto loop

        end    



get:

        i2cwrite 1 0 0xee

        i2cwrite 0 0 ram1

        i2cwrite 1 0 0xef

        i2cread 0 0 ram11

        i2cread 1 1 ram10

        ret
 
Ross,
 
This is an interesting project.  You could let user using the MAC address as unique ID, since each board has unique MAC address.
 
Ross,
 
I see you are using BMP180 I2C pressure sensor in it now.  Do you still have calibration done on server or in PLC code?
I think you could have user to set its location data in UROM, so that for different location, same PLC code will still work.
 
CAI_Support said:
I see you are using BMP180 I2C pressure sensor in it now.  Do you still have calibration done on server or in PLC code?

I think you could have user to set its location data in UROM, so that for different location, same PLC code will still work.
 
Yes, UROM2 contains the altitude offset for the station. I've only used two of these sensors so far, but they seem to be very close to absolute pressure.
I considered using the MAC address, but it still doesn't give me a way to "tie in" the station to a physical location - without which, it's quite pointless.
 
CAI_Support said:
There is a IP address to physical location database,  but that needs to be updated all the time.  I am sure our NSA has latest updates :)
 
Go check out http://www.ip2location.com
 
It's utterly useless. None of these services is any better than a rough guess.
I just checked a handful of my own addresses and while some are within a few miles, others are more than a thousand miles out.
Yes, it can be updated, but if less than 1% of the ones I checked were accurate, how many of the addresses in it are any better?
 
In US, we use zip code for mailman to manage delivery mails. Normally within the same zip code, the geographical condition is similar.  But could be huge different in mountain areas.
 
CAI_Support said:
In US, we use zip code for mailman to manage delivery mails. Normally within the same zip code, the geographical condition is similar.  But could be huge different in mountain areas.
 
Most places have zip or postcodes, but that would preclude two people in one area from using a station each. (Here, one postcode can cover quite large areas, within very different climatic zones, some up to 100km apart - so still not helpful in this instance)
 
You could have zip code plus something.  In US, we have 5 digit zip code, also have additional 4 digit to identify the mail to address.  You could have country code, zip code, then further identifier to identify unique area in that zip code zone.
 
Unless there is something already existing, you can just create a system of your own, by collecting information from each user.  For example, once user installed BMP180 pressure sensor, by comparing with weather.com data, you can find out the geographical condition for that particular user.  Those data gathered could be very useful for other science research later on.
 
This is a great project, we have heard some customers interested in this already.  We do want to support features that is goal driven for making something useful in daily life. 
 
Awesome!
 
I have a  CAI board on order for almost exactly the same project. Values will be injected into my ISY for further usage.
 
Thanks for making the effort to share that. Your efforts  will make a great springboard for me, saving a lot of time.
 
Please let us know if you need any device support for this weatherstation project, we can work out our firmware to support you.
 
Thanks!
 
I don't own a board yet but anxiously await one I have ordered. I see the bit amalgamation function is a newer feature in the PLC. Hopefully it will be there.
 
 
Looking at the PLC opcodes  and this weather station code, and as a newbie, I can already see a feature that IMHO would really improve the level of the language though.
 
Constants. Just plain and simple string substitution. Something like:
 
CONST total ram1
CONST average ram2
CONST tcount 2
 
so now the code could be more self-documenting
 
Instead of
set ram1 ram3
add ram1 ram3 ram1
div ram1 2 ram2
 
 
Now we could use
set total ram3
add total ram4 total
div total tcount average
 
Storage locations could be changed with one line of code change by changing the CONST statement.
Lines could be much more readable, less cryptic, and self documenting.
Constants could be designated to the compiler with a $ prefix or other char. for ease of parsing.
 
set $total ram3
add $total ram4 $total
div $total $tcount $average
 
Other languages use this simple string substitution to great advantages and I feel it could be implemented fairy easily in the Webcontrol bringing the language up a large notch.
 
All the best!
 
Hi Larry,
 
Thanks for your suggestion.  There is a gentleman by name Lars who planned to make a standalone utility that include features like you mentioned.  However, he has been busy.  He made a few very useful utilities, like logger, like utility to duplicate configuration from one board to another.  They can all be downloaded from this forum.
 
Currently, PLC program in our latest firmware does allow comments.  Anything started with '#' to the end of line will be removed.  Old PLC board did not support that, but updating to the latest firmware, that comment removal feature is available to all 2.2.2 PLC board users.
 
Back
Top