Decode routine for weather station WT440H or WT450H

Dependencies:   mbed

This piece of software decode Weahter station temperature and humidity freeware, by Lotfi BAGHLI, March, 2013

I hacked the TX WT440H, got 2 wires out (GND and DATA), http://www.upm-marketing.com/products/wd633+wt440h.html

I still want to get the data from a RX one (WS738) or a simple 433 MHz RX but signal pbs not yet solved In fact, from the builtin RX of the Weather station, it is ok, but from the external RX, the range is very small : 20 cm :-(

thanks to Jaakko Ala-Paavola, http://ala-paavola.fi/jaakko/doku.php?id=wt450h

for the protocol and decode routine

Connect 2 wires to the MBED : GND and Data Signal to p18

Temperature and Humidity are displayed on the Serial via USB of the MBED /media/uploads/lotfi_baghli/protocol_wt440.png

main.cpp

Committer:
lotfi_baghli
Date:
2013-03-30
Revision:
6:74430c7239b7
Parent:
5:71e7b4276a31

File content as of revision 6:74430c7239b7:

#include "mbed.h"
// This piece of software decode Weahter station temperature and humidity
// freeware, by Lotfi BAGHLI, March, 2013
// I hacked the TX WT440H, got 2 wires out (GND and DATA)
// I still want to get the data from a RX one (WS738) or a simple 433 MHz RX but signal pbs not yet solved
//
// thanks to Jaakko Ala-Paavola, http://ala-paavola.fi/jaakko/doku.php?id=wt450h
// for the protocol and decode routine
//
// Connect 2 wires to the MBED : GND and Data Signal to p18
// Temperature and Humidity are displayed on the Serial via USB of the MBED

DigitalOut myled(LED1);
DigitalOut led2(LED2);
DigitalIn Rx433(p18);
InterruptIn Rx433NotifyChange(p18);
Serial pc(USBTX, USBRX);
Timer T3;

#define TIMEOUT 1000
#define BIT0_LENGTH 2000
#define BIT1_LENGTH 1000
#define VARIATION 500
#define DATA_LENGTH 5
#define SENSOR_COUNT 4
#define NETWORK_COUNT 2
#define MSGLENGTH 36

//#define DEBUG
struct sensor {
    unsigned char humidity;
    signed char   temp_int;
    unsigned char temp_dec;
    signed char   min_int;
    unsigned char min_dec;
    signed char   max_int;
    unsigned char max_dec;
    time_t timestamp;
};
unsigned long T3saved_us;
unsigned char bitcount = 0;
unsigned char bytecount = 0;
unsigned char second_half = 0;
unsigned char data[DATA_LENGTH];
struct sensor measurement[NETWORK_COUNT][SENSOR_COUNT];
unsigned char minmaxday = 0;
// make var global
time_t t;
unsigned char net, id;
int t_int;
unsigned char rh, t_dec;

unsigned int i,j, oldj;

void NCInterrupt()
{
    unsigned char i;
    unsigned char bit;
    unsigned long current = T3.read_us();
    unsigned long diff = current-T3saved_us;
    myled = ! myled;
    j++;
    T3saved_us=current;


    if ( diff < BIT0_LENGTH + VARIATION && diff > BIT0_LENGTH - VARIATION ) {
        bit = 0;
        second_half = 0;
    } else if ( diff < BIT1_LENGTH + VARIATION && diff > BIT1_LENGTH - VARIATION ) {
        if (second_half) {
            bit = 1;
            second_half = 0;
        } else {
            second_half = 1;
            return;
        }
    } else {
        goto reset;
    }

    data[bitcount/8] = data[bitcount/8]<<1;
    data[bitcount/8] |= bit;
    bitcount++;

    if ( bitcount == 4 ) {
        if ( data[0] != 0x0c )
            goto reset;
        bitcount = 8;
#ifdef DEBUG
        pc.print('#');
#endif
    }

    if ( bitcount >= MSGLENGTH ) {

#ifdef DEBUG
        for (i=0; i<DATA_LENGTH; i++) {
            pc.print(data[i], HEX);
            pc.print(' ');
        }
#endif
//       pc.print("Data: NET:");
        net = 0x07 & (data[1]>>4)-1;
//       pc.print(net,DEC);
//       pc.print(" ID:");
        id = 0x03 & (data[1]>>2);
//       pc.print(id, DEC);
//       pc.print(" RH:");
        rh = data[2];
//       pc.print(rh, DEC);
//       pc.print(" T:");
        t_int = data[3]-50;
//       pc.print(t_int, DEC);
        t_dec = data[4]>>1;
//       pc.print('.');
//       pc.print(t_dec,DEC);

        t = time(NULL);

        /* Do not store all sensors */

        if ( net <= NETWORK_COUNT ) {
            measurement[net][id].temp_int = t_int;
            measurement[net][id].temp_dec = t_dec;
            measurement[net][id].humidity = rh;
            /*
                        if ( !measurement[net][id].timestamp ||
                                day(t) != minmaxday ) {
                            minmaxday = day(t);
                            measurement[net][id].max_int = t_int;
                            measurement[net][id].max_dec = t_dec;
                            measurement[net][id].min_int = t_int;
                            measurement[net][id].min_dec = t_dec;
                        }

                        if ( t_int > measurement[net][id].max_int ||
                                ( t_int == measurement[net][id].max_int && t_dec > measurement[net][id].max_dec ) ) {
                            measurement[net][id].max_int = t_int;
                            measurement[net][id].max_dec = t_dec;
                        }

                        if ( t_int < measurement[net][id].min_int ||
                                ( t_int == measurement[net][id].min_int && t_dec < measurement[net][id].min_dec ) ) {
                            measurement[net][id].min_int = t_int;
                            measurement[net][id].min_dec = t_dec;
                        }
            */

            measurement[net][id].timestamp = t;
        }

        goto reset;
    }
    return;

reset:
    for (i=0; i<DATA_LENGTH; i++)
        data[i] = 0;

    bytecount = 0;
    bitcount = 0;
    second_half = 0;
    return;
}

int main()
{
    j=0;
    T3.start();
    pc.baud(115200);
    Rx433NotifyChange.mode(PullNone);
    Rx433NotifyChange.rise(&NCInterrupt);
    Rx433NotifyChange.fall(&NCInterrupt);
    while(1) {
        led2 = !led2;
        wait(1);
        if (oldj != j)
            {
        pc.printf("j:%d, Data: NET:%d ID:%d RH:%d T:%d.%d  TIME:%s\r", j, net, id, rh, t_int, t_dec, ctime(&t));
        oldj=j;
        }

    }
}