Keep in mind this is a work in progress and the calcRain() function is not finished.
Eventually I will remove most or all of the print statements.
/*
* A sketch that uses WiServer to send weather data to Cosm.com (Pachube)
* sprintf() cannot handle floats
* dtostrf() assistance from Jon at http://dereenigne.org/electronics/arduino/arduino-float-to-string#comment-3831
* 17 - added insertion sort
*/
#include <WiServer.h>
char * email;
float sensor1;
int sensor2;
int sensor3;
int sensor4;
int r;
int t;
int a[10];
int results;
// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {
192,168,1,2}; // IP address of WiShield
unsigned char gateway_ip[] = {
192,168,1,1}; // router or gateway IP address
unsigned char subnet_mask[] = {
255,255,255,0}; // subnet mask for the local network
char ssid[] = {
"MyNetwork"}; // max 32 bytes
unsigned char security_type = 0; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
//IP Address for Cosm.com
uint8 ip[] = {
216,52,233,121};
char hostName[] = "api.cosm.com\nX-PachubeApiKey: "your pachube key here"\nConnection: close";
//char url[] = "/api/58529.csv?_method=put";
char url[] = "/v1/feeds/58529.csv?_method=put";
POSTrequest postPachube(ip, 80, hostName, url, feedData);
const prog_char security_passphrase[] PROGMEM = {
"12345678"}; // max 64 characters
// WEP 128-bit keys
prog_uchar wep_keys[] PROGMEM = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, // Key 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
// setup the wireless mode; infrastructure - connect to AP; adhoc - connect to another WiFi device
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
void printData(char* data, int len) {
// Print the data returned by the server
while (len-- > 0) {
Serial.print(*(data++));
}
}
#define PIN_TEMP 0
#define PIN_ANEMOMETER 3
#define PIN_RAINFALL 2
#define PIN_VANE 5
#define NUMDIRS 8
unsigned long adc[NUMDIRS] = {
26, 45, 77, 118, 161, 196, 220, 256};
volatile int numRevsAnemometer = 0;
volatile int numBucketTips = 0;
// Modify 'dirOffset
// to which direction is 'away' (it's West here).
//char *strVals[NUMDIRS] = {
//"W","NW","N","SW","NE","S","SE","E"};
int windDir[NUMDIRS] = {
1,2,3,4,5,6,7,8};
byte dirOffset=-1;
#define MSECS_CALC_WIND_SPEED 30000
void setup() {
WiServer.init(NULL);
pinMode(PIN_RAINFALL, INPUT);
digitalWrite(PIN_RAINFALL, HIGH);
pinMode(PIN_ANEMOMETER, INPUT);
digitalWrite(PIN_ANEMOMETER, HIGH);
attachInterrupt(0, countBucketTips, CHANGE);
attachInterrupt(1, countAnemometer, FALLING);
Serial.begin(57600);
Serial.println(F("Starting up..."));
WiServer.enableVerboseMode(true);
}
long updateTime = 0;
void loop(){
if (millis() >= updateTime) {
Serial.println(F("Calculating weather..."));
calcRain();
calcWindSpeed();
calcWindDir();
calcTemp();
postPachube.submit();
// Get another update one 30 sec from now
updateTime += 1000 * 30;
}
// Run WiServer
WiServer.server_task();
delay(10);
}
void feedData()
{
static char sprintfbuffer[15];
static char dtostrfbuffer[6];
static char mergedbuffer[15];
dtostrf(sensor1,5, 2, dtostrfbuffer);
sprintf(sprintfbuffer, "%d,%d,%d", sensor2, sensor3, sensor4);
memcpy(mergedbuffer, dtostrfbuffer, 5);
*(mergedbuffer+5) = ',';
memcpy(mergedbuffer+6, sprintfbuffer, 10);
WiServer.print(mergedbuffer);
}
void calcWindDir() {
int val;
byte x, reading;
val = analogRead(PIN_VANE);
val >>=2; // Shift to 255 range
reading = val;
// Look the reading up in directions table. Find the first value
// that's >= to what we got.
for (x=0; x<NUMDIRS; x++) {
if (adc[x] >= reading)
break;
}
x = (x + dirOffset) % 8; // Adjust for orientation
Serial.print(F("Sensor 3 (vane dir) = "));
Serial.println(windDir[x]);
sensor3= windDir[x];
}
void calcWindSpeed() {
int s, iSpeed;
// This will produce mph * 10
// (didn't calc right when done as one statement)
long speed = 14920;
speed *= numRevsAnemometer;
speed /= MSECS_CALC_WIND_SPEED;
iSpeed = speed;
numRevsAnemometer = 0;
s = iSpeed / 10;
sensor2 = s;
Serial.print(F("Sensor 2 (wind speed) = "));
s = iSpeed % 10;
if (s>=.5){
sensor2 = sensor2 +1;
}
Serial.print(sensor2);
Serial.print(F(" round up # ="));
Serial.println(s);
}
void calcRain() {
r = r+ numBucketTips;
numBucketTips=0;
int rain =r*.011;
t++;
// 30 sec *120 = 1 hour
Serial.print(F("Sensor 1 Rain = "));
Serial.print(rain);
Serial.println(F(" inches per hour"));
sensor1=rain;
if (t>=120)
{
t=0;
r=0;
rain=0;
}
}
void calcTemp()
{
float reading;
for (int i=0; i <= 9; i++){
reading=analogRead(PIN_TEMP);
a[i]=reading;
}
insertionSort(a,10);
reading=results;
results=0;
float voltage = reading * 5.0;
voltage /= 1024.0;
float temperatureC = (voltage - 0.5) * 100 ;
int temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print("Sensor 4 ");
Serial.print(temperatureF);
Serial.println(" degrees F");
sensor4 = temperatureF;
}
void countAnemometer() {
numRevsAnemometer++;
}
void countBucketTips() {
numBucketTips++;
}
void insertionSort(int arr[], int length) {
int i;
int j;
int tmp;
for (i = 1; i < length; i++) {
j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
j--;
}
}
// array sorted, now lose low and high values for better average
a[0]=0;
a[9]=0;
for (i = 1; i < 9; i++){
results= results+a[i];
Serial.print(a[i]);
Serial.print(" + ");
}
Serial.print(" = ");
Serial.println(results);
results/=8; // divide by 8 as places 0 and 9 = 0
Serial.print(F("Average = "));
Serial.println(results);
}