Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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;
}