Bill Eccles / Mbed 2 deprecated WS-2010-PCInterface

Dependencies:   EthernetNetIf mbed

WeatherStationInterface.cpp

Committer:
BillEccles
Date:
2012-01-02
Revision:
0:dfbd7dacdf8c
Child:
1:1972c4310a72

File content as of revision 0:dfbd7dacdf8c:

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#define WAIT_time 0.05
#define D() wait(WAIT_time)

Serial mac(USBTX, USBRX);
Serial ws2010pc(p28, p27); // tx, rx
DigitalOut DTR(p29);
DigitalOut mled0(LED1);
DigitalOut mled1(LED2);
DigitalOut mled2(LED3);
DigitalOut mled3(LED4);

const char *requestDCFtime = "\x01\x30\xCF\x04";
const char *requestData = "\x01\x31\xCE\x04";
const char *requestNextDataset = "\x01\x32\xCD\x04";
const char *requestStatus = "\x01\x35\xCA\x04";

void blink() {
int m0, m1, m2, m3;

    m0 = mled0;
    m1 = mled1;
    m2 = mled2;
    m3 = mled3;

    mled0 = mled1 = mled2 = mled3 = 0;

    mled0 = 1;D();mled1 = 1;D();mled2 = 1;D();mled3 = 1;D();
    mled0 = 0;D();mled1 = 0;D();mled2 = 0;D();mled3 = 0;D();D();D();
    mled3 = 1;D();mled2 = 1;D();mled1 = 1;D();mled0 = 1;D();        
    mled3 = 0;D();mled2 = 0;D();mled1 = 0;D();mled0 = 0;D();D();D();
    
    mled0 = m0;
    mled1 = m1;
    mled2 = m2;
    mled3 = m3;
    
// takes 1s with a delay time of 0.05s
    
    return;
}

int errorHalt( bool L3, bool L2, bool L1, bool L0 ) {
    while (1) {
        mled3 = L0;
        mled2 = L1;
        mled1 = L2;
        mled0 = L3;
        wait(0.5);
        mled3 = false;
        mled2 = false;
        mled1 = false;
        mled0 = false;
        wait(0.5);
    }
    return -1;
}

void showLEDs( bool L3, bool L2, bool L1, bool L0 ) {
        mled3 = L0;
        mled2 = L1;
        mled1 = L2;
        mled0 = L3;
    return;
}

float H( int byte ) {
    return (float)(byte >> 4);
}

float HS( int byte ) {
    return (float)((byte >> 4) & 0x07);
}

float S( int byte ) {
    byte = (byte & 0x0F) >> 3;
    return ((byte==1) ? -1.0 : 1.0);
}

float L( int byte ) {
    byte = (byte & 0x0F);
    return (float)byte;
}

float LS( int byte ) {
    byte = (byte & 0x07);
    return (float)byte;
}

bool wakeup() {
    char aChar;
    bool wokeup = false;

//    mac.printf("Waking up the WS2010...");
    DTR = 1;
    wait(0.05);
    DTR = 0;
    wait(0.05);

    while (ws2010pc.readable()) {
        aChar = ws2010pc.getc();
        if (aChar==3) {
//            mac.printf(" and it's awake.\n\r");
            wokeup = true;
        } else {
//            mac.printf(" and it didn't want to wake up, returning a %i instead of a 3.\n\r",aChar);
            wokeup = false;
        }        
    }
    wait(0.1);
    return wokeup;
}
int sendString( char *theString ) {
    int index = 0;
    while (theString[index]!='\0') {
        ws2010pc.putc((char)theString[index++]);
//        wait(0.005);
    }
    return index;
}

int receiveString( char *theString, int numChars, int timeout_ms ) {
    int index = 0;
    bool done = false;
    int LSRValue;
    Timer aTimer;
    
    theString[0]='\0';
    aTimer.start();
            
    while ((aTimer.read_ms()<=timeout_ms)&&(index<numChars)&&(!done)) {    
//    LSRValue = LPC_UART2-> LSR;
//    if ((LSRValue!=97)&&(LSRValue!=96)) { mac.printf("Receive error? LSR is %i.\n\r",LSRValue); }
        if (ws2010pc.readable()) {
            theString[index] = ws2010pc.getc();
            if (theString[index]==0x03) {
                done = true;
            }
            index++;
            theString[index]='\0';
        }
    }
    aTimer.stop();
    return index;
}

// MAIN

int main() {
    int i, j, dataLength, strippedLength, LSRValue;
    int db, dt, spreadraw;
    float t1c, t1f, h1, hif, hic;
    float tic, tif, hi;
    float sp, dir, spread, wc;
    float pr;
    float rn;
    string n1, ni, nwin, nr;
    HTTPText txt;
    HTTPResult r;
    bool error, firstTime, haveData, dataPostedOK;
    char theData[1024], strippedData[1024], httpQuery[1024];
    EthernetNetIf eth;
    HTTPClient http;
    EthernetErr ethErr;
    IpAddr myIpAddr;
    
    firstTime = true;

// Setup Ethernet
    showLEDs( false, false, false, true );

//    mac.printf("Setting up Ethernet...\n\r");
    ethErr = eth.setup();
    if (ethErr) {
//        mac.printf("Error %d in setup.\n\r", ethErr);
        ethernetOK = false;
        errorHalt( false, false, false, true );                
    } else {
//        mac.printf("Ethernet setup was successful.\n\r");
    }
    
    while (1) {
        error = false;
        
// Setup serial port

        showLEDs( false, false, true, false );

//        mac.printf("Opening serial port...\n\r");
        ws2010pc.baud(9600);
        ws2010pc.format(8, Serial::Even, 2);

// Wait six minutes unless this is the first time through this
    
        showLEDs( false, false, true, true );

        if (!firstTime) {
            DTR = 1;
            mac.printf("Sleeping for six minutes... ");
            i=6;
            while (i>=1) {
                mac.printf("%i...",i--);
                for (j=0; j<12; j++) {
                    blink();
                    wait(4);
                }
            }
            mac.printf("\n\r");
        }

        firstTime = false;

// Wakeup the 2010

        showLEDs( false, true, false, false );

        error = !wakeup();
        
// Ask the 2010 for data until there is no more to be had.


        haveData = true;
        while (haveData&&(!error)) {
            showLEDs( false, true, false, true );
            mac.printf("Requesting data.... ");
            dataLength = sendString((char *)requestData);
            dataLength = receiveString(theData, 128, 500);
            mac.printf("Received %i characters.\n\r",dataLength);
            if (dataLength<2) {
                mac.printf("No data received.\n\r");
                haveData=false;
            } else if ((theData[0]!=2)||(theData[dataLength-1]!=3)) {
                mac.printf("Bad dataset received.\n\r");
                haveData = false;
            } else if ((theData[1]==1)&&(theData[2]==16)) {
                mac.printf("No data available at the moment. Will retry later.\n\r");
                haveData = false;
            }

            if (haveData) {
/*
                mac.printf("The raw dataset has %i characters: ",dataLength);
                i=0;
                while (i<dataLength) {
                    mac.printf("%02X ",theData[i++]);
                }
                mac.printf("\n\r");
*/
// We have some data. Now strip out the ENQ escape sequences                        
            
                strippedLength=0;
                for (j=0; j<dataLength; j++) {
                    if (theData[j]==5) {
                        strippedData[strippedLength++]=theData[j+1]-16;
                        j++;
                    } else {
                        strippedData[strippedLength++]=theData[j];
                    }
                }
/*
                mac.printf("No ENQ  dataset has %i characters: ",strippedLength);
                i=0;
                while (i<strippedLength) {
                    mac.printf("%02X ",strippedData[i++]);
                }
                mac.printf("\n\r");
*/          
// Get rid of leading STX, and trailing checksum and ETX. (Leave the length as a pad in [0].

                for (j=2; j<strippedLength-2; j++) {
                    strippedData[j-2]=strippedData[j];
                }
                strippedLength = strippedLength-4;
            
// Show the user what we have.
/*
                mac.printf("SOHless dataset has %i characters: ",strippedLength);
                i=0;
                while (i<strippedLength) {
                    mac.printf("%02X ",strippedData[i++]);
                }
                mac.printf("\n\r");
*/
// Now decode everything.

// dataset ID and time before now (in minutes)
                db = strippedData[1]*256+strippedData[0];
                dt = strippedData[3]*256+strippedData[2];
                
// remove the header bytes (note that I'm leaving one byte in strippedData[0] so that the index value lines up with
// the index values of the bytes in the WS-2010 documentation, i.e., L25 will correspond to the low nybble of strippedData[25])

                for (j=3; j<=strippedLength; j++) {
                    strippedData[j-3]=strippedData[j];
                }
                strippedLength = strippedLength - 3;
/*
                mac.printf("Hdrless dataset has %i characters: ",strippedLength);
                i=0;
                while (i<strippedLength) {
                    mac.printf("%02X ",strippedData[i++]);
                }
                mac.printf("\n\r");
*/
//                mac.printf("Read dataset id %i from %i minutes ago.\n\r", db, dt);
                                                             
// reading: temperature 1, humidity 1 and heat index

                t1c = (LS(strippedData[2])*10.0+H(strippedData[1])+L(strippedData[1])/10.0)*S(L(strippedData[2]));
                t1f = 9.0/5.0*t1c+32.0;
                h1 = LS(strippedData[3])*16.0+H(strippedData[2]);
                n1 = (S(L(strippedData[3]))==-1) ? "NEW" : "OLD";
                
                if (t1f>70) {
                    hif = -42.379+2.04901523*t1f+10.14333127*h1-0.22475541*t1f*h1-((6.83783e-3)*t1f*t1f)-((5.481717e-2)*h1*h1)+((1.22874e-3)*t1f*t1f*h1)+((8.5282e-4)*t1f*h1*h1)-((1.99e-6)*t1f*t1f*h1*h1);
                    hic = (hif-32.0)*5.0/9.0;
                } else {
                    hif = t1f;
                    hic = t1c;
                }
                
//                mac.printf("    T1C:%5.2f T1F:%5.2f H1:%5.2f HIF:%5.2f HIC:%5.2f %s \n\r", t1c, t1f, h1, hif, hic, n1);

// reading: indoor temperature and humidity

                tic = (LS(strippedData[29])*10+H(strippedData[28])+L(strippedData[28])/10)*S(L(strippedData[29]));
                tif = 9.0/5.0*tic+32;
                hi = LS(strippedData[30])*16+H(strippedData[29]);
                ni = (S((int)L(strippedData[30]))==-1) ? "NEW" : "OLD";

//                mac.printf("    TIC:%3.2f TIF:%3.2f HI:%3.2f %s \n\r", tic, tif, hi, ni);
                
// reading: wind speed, direction and directional spread, wind chill

                sp = (HS(strippedData[24])*100.0+L(strippedData[24])*10.0+H(strippedData[23])+L(strippedData[23])/10.0)*0.6215;
                dir = (float)((int)L(strippedData[26])%4)*100.0+H(strippedData[25])*10.0+L(strippedData[25]);
                spreadraw = (int)(L(strippedData[26])/4);
                switch (spreadraw) {
                case 1:
                    spread = 22.5;
                    break;
                case 2:
                    spread = 45;
                    break;
                case 3:
                    spread = 67.5;
                    break;
                default:
                    spread = 0;
                }
                nwin = (S((int)H(strippedData[24]))==-1) ? "NEW" : "OLD";
                
//                mac.printf("    SP: %5.2f DIR:%5.2f SPREADRAW:%i SPREAD:%5.2f %s \n\r", sp, dir, spreadraw, spread, nwin);
                
                if ((t1f<=50)&&(sp>3)) {
                    wc = 35.74+(0.6215*t1f)-(35.75*pow(sp,(float)0.16))+(0.4275*t1f*pow(sp,(float)0.16));
                } else {
                    wc = t1f;
                }
                
//                mac.printf("    WC: %5.2f\n\r",wc);

// reading: air pressure

                pr = (H(strippedData[27])*100.0+L(strippedData[27])*10.0+H(strippedData[26])+200.0)/33.775;
//                mac.printf("    PR: %6.3f\n\r",pr);
                
// Ah, rain. The see-saw tips, and each tip represents 0.0145636 inches of rain.

                rn = (strippedData[22]&0x7F)*256+strippedData[21];
                nr = (S((int)H(strippedData[22]))==-1) ? "NEW" : "OLD";
                
//                mac.printf("    RN: %7.1f NR %s\n\r",rn,nr);

// Generate the query string

                j = sprintf(httpQuery, "http://www.example.com/yourquery.php?datasetnumber=%06d&timedelta=%06d&t1=%.1f&h1=%.1f&n1=%s&hif=%.1f&hic=%.1f&ti=%.1f&hi=%.1f&ni=%s&sp=%.1f&dir=%.1f&spread=%.1f&nwin=%s&wc=%.1f&pr=%.7f&rn=%.1f&nr=%s",db,dt,t1f,h1,n1,hif,hic,tif,hi,ni,sp,dir,spread,nwin,wc,pr,rn,nr);
//                mac.printf("The query is \"%s\"\n\r",httpQuery);
                            
// Now try and post the data. Make sure the response from the server doesn't exceed capacity of the buffer "txt".

                showLEDs( false, true, true, false );

                r = http.get(httpQuery, &txt);
                if(r==HTTP_OK) {
//                    mac.printf("HTTP result:\"%s\"\n\r", txt.gets());
                    dataPostedOK = true; 
                } else {
//                    mac.printf("HTTP error #%d\n\r", r);
                    dataPostedOK = false;
                }

                if (dataPostedOK) {
                    showLEDs( false, true, true, true );
                    error = !wakeup();
                    mac.printf("Requesting next dataset.... ");
                    dataLength = sendString((char *)requestNextDataset);
                    dataLength = receiveString(theData, 128, 300);
                    mac.printf("Received %i characters.\n\r",dataLength);
                    if (dataLength<2) {
                        mac.printf("No data received.\n\r");
                        haveData=false;
                        error = true;
                    } else if ((theData[0]!=2)||(theData[dataLength-1]!=3)) {
                        mac.printf("Bad dataset received.\n\r");
                        haveData = false;
                        error = true;
                    } else if ((theData[1]==1)&&(theData[2]==16)) {
                        mac.printf("No data available at the moment. Will retry later.\n\r");
                        haveData = false;
                    }
                }
            } // end of "if (haveData)"
        }      
    }

    errorHalt( true, true, true, true );
    return 0;
  
}