mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/

Dependencies:   EthernetNetIf SDHCFileSystem I2CLEDDisp Agentbed NTPClient_NetServices mbed BMP085 HTTPClient ConfigFile I2CLCD

Revision:
0:d7b4484099bf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,431 @@
+/*
+ * mbed Weather Platform
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief mbed Weather Platform
+ */
+
+#define VERSION "mbed Weather Platform 0.2.1 (C) 2011 Suga koubou Co.,Ltd."
+
+//#define NONBLOCKING // ethernet function non-bloking
+ 
+#include "mbed.h"
+#include "BMP085.h"
+#include "SHT.h"
+#include "WeatherMeters.h"
+#include "SDHCFileSystem.h"
+#include "MSCFileSystem.h"
+#include "EthernetNetIf.h"
+#include "NTPClient.h"
+#include "HTTPClient.h"
+#include "Agentbed.h"
+#include "conf.h"
+#include "I2CLEDDisp.h"
+#include "I2CLCD.h"
+
+Serial pc(USBTX, USBRX), xbee(p13, p14);
+int seq = 0;
+char filename[20];
+struct Config conf;
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+LocalFileSystem local("local");
+SDFileSystem sd(p5, p6, p7, p8, "sd"); 
+MSCFileSystem *usb;
+
+// Sensors
+struct Sensor sensor, offset, sensor_old;
+I2C i2c(p9, p10);
+BMP085 bmp085(i2c, BMP085_oss4);
+SHT sht15(p12, p11, SHT_high); // sclock, data
+WeatherMeters wmeters(p21, p15, p22); // anemo, vane, rain
+AnalogIn ailight(p16), aiuv(p17);
+AnalogIn *aimoist;
+InterruptIn *intcounter;
+int count_counter;
+unsigned long lastCountTime;
+
+DigitalOut swout1(p29), swout2(p30);
+I2CLEDDisp *leddisp;
+I2CLCD *lcd;
+int ledpos, ledflg;
+char ledbuf[200];
+Ticker ticker;
+
+// Ethernet
+EthernetNetIf *eth; 
+NTPClient *ntp;
+HTTPClient *clientP, *clientT;
+DigitalOut led_g2(p24),led_g(p25), led_y(p26);
+DigitalIn eth_link(P1_25), eth_speed(P1_26);
+
+extern AgentbedClass Agentbed;
+extern uint32_t locUpTime;
+
+void writefile (char *);
+void pachube (char *);
+char *fmtstr (char *, char *, int);
+void twitter (int);
+void weatherstations ();
+void ntpdate ();
+int check_action (char);
+void pduReceived ();
+
+float get_photo (AnalogIn &ain) {
+    float f;
+    
+    f = ain * 5.0 / 1000; // A
+    return f / 0.0000026; // lx
+}
+
+float get_moist (AnalogIn &ain) {
+    float f;
+    
+    f = ain * 5.0; // V
+    f = f / ((3.3 - f) / 10.0); // k ohm
+    if (f < 0) f = 0;
+    return f;
+}
+
+float get_uv (AnalogIn &ain) {
+    float f;
+    
+    f = ain * 5.0 / 100000; // A
+    f = f / 0.000384; // mW/cm2
+    if (f < 0) f = 0;
+    return f;
+}
+
+void int_counter () {
+    count_counter ++;
+}
+
+float get_counter (char flg) {
+    float t;
+
+    if (flg) {
+        t = (float)count_counter;
+    } else {
+        if (locUpTime > lastCountTime) {
+            t = (float)(locUpTime - lastCountTime) / 6000.0;
+        } else {
+            t = (float)(0xffffffff - lastCountTime + locUpTime) / 6000.0;
+        }
+        t = (float)count_counter / t;
+    }
+    lastCountTime = locUpTime;
+    count_counter = 0;
+    return t;
+}
+
+
+void ledscroll () {
+
+    if (conf.leddisp_mesg[0]) {
+        int i, addr, len;
+        
+        len = strlen(ledbuf);
+        leddisp->locate(0, 0);
+        for (i = 0; i < 4; i ++) {
+            addr = ledpos + i;
+            if (addr >= 0 && addr < len) {
+                leddisp->putc(ledbuf[addr]);
+            } else {
+                leddisp->putc(' ');
+            }
+        }
+        ledpos ++;
+        if (ledpos >= len + 4) {
+            ledpos = -4;
+        }
+    }
+
+    locUpTime = locUpTime + 40; // 0.4s
+    led_y = 1;
+}
+
+void action (char *buf) {
+    int i;
+    
+    i = check_action('A');
+    if (i) {
+        swout1 = (i == ' ' ? 1 : i - '0');
+        led3 = swout1;
+    }
+    i = check_action('B');
+    if (i) {
+        swout2 = (i == ' ' ? 1 : i - '0');
+        led4 = swout2;
+    }
+    if (check_action('P')) {
+        if (conf.ipaddr[0] && conf.pachube_apikey[0] && conf.pachube_feedid[0]) {
+            pachube(buf);
+        }
+    }
+    i = check_action('T');
+    if (i) {
+        if (conf.ipaddr[0] && conf.twitter_user[0] && conf.twitter_pwd[0]) {
+            twitter(i == ' ' ? 0 : i - '0');
+        }
+    }
+    if (check_action('S')) {
+        if (conf.ipaddr[0] && conf.stations_id[0] && conf.stations_pin[0]) {
+            weatherstations();
+        }
+    }
+    if (check_action('X')) {
+        xbee.printf(buf);
+    }
+    sensor_old = sensor;
+}
+
+void init () {
+    FILE *fp;
+
+    if (config("/sd/" CONFIG_FILE) == -1) {
+        pc.printf("local strage\r\n", conf.interval);
+        config("/local/" CONFIG_FILE);
+    }
+
+    pc.printf("\r\nInterval: %d sec\r\n", conf.interval);
+
+    if (conf.lcd_mesg[0]) {
+        // use I2C LCD
+        lcd = new I2CLCD(i2c, I2CLCD_ADDR, conf.lcdtype, conf.lcdconf);
+    }
+
+    if (conf.leddisp_mesg[0]) {
+        // use I2C LED Display
+        leddisp = new I2CLEDDisp(i2c);
+    }
+
+    if (conf.ipaddr[0]) {
+        // use ethernet
+
+        eth_link.mode(PullUp);
+        eth_speed.mode(PullUp);
+        led_g = eth_link ? 1 : 0;
+        led_g2 = 1;
+        led_y = 0;
+        if (conf.ipaddr[0] == 255) {
+            // dhcp
+            eth = new EthernetNetIf;
+        } else {
+            // static
+            eth = new EthernetNetIf(conf.ipaddr, conf.netmask, conf.gateway, conf.nameserver);
+        }
+
+        EthernetErr ethErr = eth->setup();
+        if(ethErr) {
+            // error
+            conf.ipaddr = IpAddr(0, 0, 0, 0);
+        } else
+        if (conf.ipaddr[0] == 255) {
+            // succeed dhcp
+            conf.ipaddr = eth->getIp();
+        }
+        pc.printf("Ethernet: %d.%d.%d.%d\r\n", eth->getIp()[0], eth->getIp()[1], eth->getIp()[2], eth->getIp()[3]);
+
+        if (conf.ipaddr[0]) {
+
+            if (conf.ntpserver[0]) {
+                // ntp
+                pc.printf("Ntp: %s\r\n", conf.ntpserver);
+                ntpdate();
+            }
+        
+            clientP = new HTTPClient;
+            clientT = new HTTPClient;
+
+            if (conf.snmp_commname[0]) {
+                Agentbed.begin(conf.snmp_commname, "None", SNMP_DEFAULT_PORT, eth);
+                Agentbed.onPduReceive(pduReceived);
+                pc.printf("Snmp community name: %s\r\n", conf.snmp_commname);
+            }
+        }
+    } else {
+        // not use ethernet
+        led_g = eth_link ? 0 : 1;
+        led_g2 = 0;
+    }
+
+    if (conf.filetype) {
+        // seq num
+        
+        if (conf.filetype == 1) {
+            strcpy(filename, "/sd");
+        } else
+        if (conf.filetype == 2) {
+            usb = new MSCFileSystem("usb");
+            strcpy(filename, "/usb");
+        }
+        strcat(filename, "/weather.seq");
+
+        // load
+        fp = fopen(filename, "r");
+        if (fp) {
+            fscanf(fp, "%d", &seq);
+            fclose(fp);
+        }
+        seq ++;
+        // save
+        fp = fopen(filename, "w");
+        if (fp) {
+            fprintf(fp, "%d", seq);
+            fclose(fp);
+            // csv filename
+            if (conf.filetype == 1) {
+                sprintf(filename, "/sd/w%05d.csv", seq);
+            } else
+            if (conf.filetype == 2) {
+                sprintf(filename, "/usb/w%05d.csv", seq);
+            }
+            pc.printf("Filename: %s\r\n", filename);
+            led2 = 1;
+        }
+    }
+
+    pc.printf("Actions: %d\r\n", conf.actionscount);
+
+    if (conf.inputtype & INPUT_FALL) {
+        intcounter = new InterruptIn(p18);
+        intcounter->fall(&int_counter);
+    } else
+    if (conf.inputtype & INPUT_RISE) {
+        intcounter = new InterruptIn(p18);
+        intcounter->rise(&int_counter);
+    } else {
+        aimoist = new AnalogIn(p18);
+    }
+
+    count_counter = 0;
+    lastCountTime = 0;
+}
+
+int main () {
+    Timer timer;
+    time_t sec;
+    char buf[100];
+    
+    swout1 = 0;
+    swout2 = 0;
+    led1 = 1;
+    ledpos = -4;
+    ledflg = 0;
+    strcpy(ledbuf, VERSION);
+    ticker.attach(&ledscroll, 0.4);
+    init();
+    pc.printf("%s\r\n\r\n", VERSION);
+
+    if (conf.filetype) {
+        strcpy(buf, "date,pres(hPa),temp(`C),humi(%%),anemo(m/s),vane(`),rain(mm),light(lx),uv(mW/cm2),moist(kohm),\r\n");
+        writefile(buf);
+    }
+    
+    if (conf.leddisp_mesg[0]) {
+        ledpos = -4;
+        sec = time(NULL);
+        strftime(ledbuf, sizeof(ledbuf), "%H:%M", localtime(&sec));
+        sprintf(&ledbuf[5], " %ds %s", conf.interval, filename);
+        if (conf.ipaddr[0]) {
+            sprintf(&ledbuf[strlen(ledbuf)], " %d.%d.%d.%d", conf.ipaddr[0], conf.ipaddr[1], conf.ipaddr[2], conf.ipaddr[3]);
+            if (conf.pachube_apikey[0] && conf.pachube_feedid[0]) {
+                strcat(ledbuf, " P");
+            }
+            if (conf.twitter_user[0] && conf.twitter_pwd[0]) {
+                strcat(ledbuf, " T");
+            }
+        }
+    }
+    
+    timer.start();
+#ifdef NONBLOCKING
+    while (timer.read() < 5) {
+        wait_ms(1);
+        Net::poll();
+    }
+    timer.reset();
+#endif
+
+    while(1) {
+        led1 = 0;
+
+        sec = time(NULL);
+        strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&sec));
+
+        // sensors
+        __disable_irq();
+        bmp085.update();
+        sensor.pres = bmp085.get_pressure() + offset.pres;
+        sensor.temp2 = bmp085.get_temperature();
+
+        sht15.update(SHT_high);
+        sensor.temp = sht15.get_temperature() + offset.temp;
+        sensor.humi = sht15.get_humidity() + offset.humi;
+
+        sensor.anemo = wmeters.get_windspeed();
+        sensor.vane = wmeters.get_windvane();
+        sensor.rain = wmeters.get_raingauge();
+
+        sensor.light = get_photo(ailight);
+        if (conf.inputtype == INPUT_MOIST) {
+            sensor.moist = get_moist(*aimoist);
+        } else {
+            sensor.moist = get_counter(conf.inputtype & INPUT_CPM ? 0 : 1);
+        }
+        sensor.uv = get_uv(aiuv);
+
+        sprintf(&buf[strlen(buf)], ",%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",
+          sensor.pres, sensor.temp, sensor.humi, sensor.anemo, sensor.vane, sensor.rain, sensor.light, sensor.uv, sensor.moist, sensor.temp2);
+        if (conf.filetype) {
+            // csv
+            writefile(buf);
+        }
+        __enable_irq();
+        pc.printf(buf);
+
+        action(&buf[20]);
+
+        if (conf.leddisp_mesg[0]) {
+            if (ledflg) {
+                ledpos = -4;
+                fmtstr(conf.leddisp_mesg, ledbuf, sizeof(ledbuf));
+            }
+            ledflg = 1;
+        }
+        if (conf.lcd_mesg[0]) {
+            fmtstr(conf.lcd_mesg, buf, sizeof(buf));
+            lcd->cls();
+            lcd->puts(buf);
+        }
+
+        led1 = 1;
+
+        while (timer.read() < conf.interval) {
+//            wait(1);
+//            pc.putc('.');
+            wait_ms(1);
+            if (conf.ipaddr[0]) {
+                led_g = eth_link ? 1 : 0;
+                led_g2 = 1;
+            } else {
+                led_g = eth_link ? 0 : 1;
+                led_g2 = 0;
+            }
+            Net::poll();
+            
+            if (pc.readable()) {
+                int i;
+                i = pc.getc();
+                if (i == ' ') {
+                    break;
+                } else {
+                    pc.printf("( %d )\r\n", (int)timer.read());
+                }
+            }
+        }
+        timer.reset();
+    }
+}