/* Program by Christopher Nafis Written October 2005 Measure snow and water depths using an inexpensive ultrasonic sensor (Parallax PING). The sensor data is posted to an Internet website. Copyright 2005 Christopher Nafis */ #define TCPCONFIG 3 // DHCP //#define PROXY "proxyserver.com" #define DEST "www.howmuchsnow.com" #define PORT 80 #define MAX_PULSE 0.0185 #define MAXINTERVAL 0.0001 // define max time in seconds. #define Rth 10000.0 // thermistor T25 resistance #define Bth 3964.0 // thermistor B value #define Cap 0.100 // capacitor in uF #define RCPIN HB_PF1 // pin for RC network #define WUID "xxxxxxx" // Sensor ID (use Weather Underground ID) #define WUPASSWORD "xxxxxx" // Sensor password (use Weather Underground password) #use "dcrtcp.lib" #use "HOBBYIST.LIB" void main() { float PW, R, A, T; // pulse width, computed resistance, constant A and computed temperature int i; float time1; float time2; float speedofsound; int rangesamples; float timesum; int tempsamples; float tempsum; // network variables char buffer[300]; int bytes_read; longword destIP; tcp_Socket socket; // HTTP/TELNET request variables char request[300]; char request2[300]; // time related variables struct tm rtc; int hungcheck; // Thermistor values A = 1/298.0 - ((1/Bth) * log(Rth)); // multiple sample data rangesamples = 0; timesum = 0; tempsamples = 0; tempsum = 0; /* Initialize Network Connection */ printf("attempting network connection\n"); sock_init(); while (ifpending(IF_DEFAULT) <= IF_COMING_UP) { tcp_tick(NULL); } /* Initialize ultrasonic PING ranger */ HBpinLow(HB_PG2); HBtimerSet(1, 0.05); while(!HBtimerCheck(1)); /* Continuously sample temperature, calculate range to the ground, and post data to the Internet */ loopinit(); while (1) { loophead(); /* Get Temperature */ costate { waitfor(DelaySec(1)); // seems like thermistor heats up if you sample too often? HBpinOut(RCPIN, 0); // reset capacitor HBtimerSet(2, 0.01); while(!HBtimerCheck(2)); //wait 10msec for reset PW = HBrcRiseTime(RCPIN, MAXINTERVAL); // measure RC time interval if ( PW < 0.0 ) { printf("Timeout !\n"); continue; } PW = PW * 1.0e6; // scale to usec R = PW / ( 0.40 * Cap ); // comnpute resistance T = 1 / (A + ((1/Bth)*log(R))); // compute Temp in Kelv. tempsamples++; // take multiple samples tempsum = tempsum + T; } /* Get depth range Take two measurements and make sure they are within a tolerance */ costate { HBpulseSetup(MAX_PULSE); // Need to reset because of HBrcRiseTime HBpinHigh(HB_PG2); // Send trigger pulse to Ultrasonic Module HBpinLow(HB_PG2); // End trigger pulse HBpinRead(HB_PC1); // Make sure port pins PC1/PG2 are inputs HBpinRead(HB_PG2); HBpulseListen1(HB_PC1, HB_HIGHPULSE); HBtimerSet(1, 0.02); // set watchdog incase return isn't found while (1) { time1 = HBpulseLastTime1(); if ( time1 != 0) break; if (HBtimerCheck(1) == 1) break; } if ( time1 < 0.0 ) { printf("Ultrasonic Timeout !\n"); continue; } HBtimerSet(1, 0.01); // wait between pings while(!HBtimerCheck(1)); HBpinHigh(HB_PG2); // Send prigger pulse to Ultrasonic Module HBpinLow(HB_PG2); // End trigger pulse HBpinRead(HB_PC1); // Make sure port pins PC1/PG2 are inputs HBpinRead(HB_PG2); HBpulseListen1(HB_PC1, HB_HIGHPULSE); HBtimerSet(1, 0.02); // set watchdog incase return isn't found while (1) { time2 = HBpulseLastTime1(); if ( time2 != 0) break; if (HBtimerCheck(1) == 1) break; } if ( time2 < 0.0 ) { printf("Ultrasonic Timeout !\n"); continue; } if (((time1-time2)>-0.00003) && ((time1-time2)<0.00003)) // check that samples are within 0.4" { rangesamples++; timesum = timesum + time1; } } /****************************************************************************** Post Data to the web site ******************************************************************************/ costate { waitfor(DelaySec(60)); #ifdef WUID tm_rd(&rtc); printf("Network condition is %d\n",ifpending(IF_DEFAULT)); printf("Trying to post data\n"); #ifdef PROXY if( 0L == (destIP = resolve(PROXY)) ) { printf( "ERROR: Cannot resolve \"%s\" into an IP address\n", PROXY ); abort; } #else if( 0L == (destIP = resolve(DEST)) ) { printf( "ERROR: Cannot resolve \"%s\" into an IP address\n", DEST ); abort; } #endif printf("finished resolve\n"); if (!tcp_open(&socket,0,destIP,PORT,NULL)) { printf("failed to open\n"); abort; } printf("open socket successfully\n"); waitfor(DelaySec(1)); if (!sock_established(&socket)) { printf("problem with socket connection\n"); sock_close(&socket); abort; } #ifdef PROXY sprintf(request,"GET http://%s/cgi-bin/",DEST); #else sprintf(request,"GET http://%s/cgi-bin/",DEST); #endif sprintf(request2,"postrange.pl?sensor=%s&password=%s",WUID,WUPASSWORD); strcat(request,request2); sprintf(request2,"&temp=%g",(((tempsum/(float)tempsamples)-273.0)*(9.0/5.0))+32); strcat(request,request2); sprintf(request2,"&flighttime=%g&tempsamples=%d&rangesamples=%d",timesum/(float)rangesamples,tempsamples,rangesamples); strcat(request,request2); speedofsound = 331.4 + 0.6 * ((tempsum/(float)tempsamples) -273.0); sprintf(request2,"&range=%g",((timesum/(float)rangesamples) /(1.0/(speedofsound/0.0254))/2.0)); strcat(request,request2); rangesamples = 0; // reset data samples timesum = 0; tempsamples = 0; tempsum = 0; strcat(request," HTTP/1.0\r\n\r\n"); printf("writing HTTP request\n"); if (sock_write(&socket,request,strlen(request))!= strlen(request)) { printf("socket write failed\n"); sock_close(&socket); abort; } printf("waiting for HTTP response\n"); hungcheck = 0; while(tcp_tick(&socket)) { bytes_read=sock_fastread(&socket,buffer,sizeof(buffer)-1); if (bytes_read == -1) { printf("socket read error\n"); sock_close(&socket); abort; } if (bytes_read > 0) { buffer[bytes_read] = '\0'; if (strstr(buffer,"success") != NULL) { printf("data successfully posted\n"); break; } } /* we could be hung */ if (bytes_read == 0) { waitfor(DelaySec(5)); hungcheck++; if (hungcheck > 10) { printf("never got an HTTP response\n"); sock_close(&socket); abort; } } yield; } printf("closing socket\n"); sock_close(&socket); while (tcp_tick(&socket)) { yield; } #endif } costate { tcp_tick(NULL); } } }