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

Files at this revision

API Documentation at this revision

Comitter:
okini3939
Date:
Wed May 18 15:01:56 2011 +0000
Commit message:

Changed in this revision

Agentbed.lib Show annotated file Show diff for this revision Revisions of this file
BMP085.lib Show annotated file Show diff for this revision Revisions of this file
ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
I2CLCD.lib Show annotated file Show diff for this revision Revisions of this file
I2CLEDDisp.lib Show annotated file Show diff for this revision Revisions of this file
MSCFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
NTPClient.lib Show annotated file Show diff for this revision Revisions of this file
SDHCFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SHT_v1/SHT.cpp Show annotated file Show diff for this revision Revisions of this file
SHT_v1/SHT.h Show annotated file Show diff for this revision Revisions of this file
WeatherMeters.lib Show annotated file Show diff for this revision Revisions of this file
conf.cpp Show annotated file Show diff for this revision Revisions of this file
conf.h Show annotated file Show diff for this revision Revisions of this file
func.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
snmp.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agentbed.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okini3939/code/Agentbed/#9e4369522e03
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okini3939/code/BMP085/#6245372b9179
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigFile.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FATFileSystem.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/fatfilesystem/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClient.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mamezu/code/HTTPClient/#62fac7f06c8d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CLCD.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okini3939/code/I2CLCD/#bc4583ce560e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CLEDDisp.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okini3939/code/I2CLEDDisp/#eae10b76cd72
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MSCFileSystem.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/chris/code/MSCFileSystem/#3e7d2baed4b4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NTPClient.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/NTPClient/#7c3f1199256a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDHCFileSystem.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/davervw/code/SDHCFileSystem/#248d03543f5f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHT_v1/SHT.cpp	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,224 @@
+/* mbed module to use a Sensirion SHT1x /SHT7x sensor
+ * Copyright (c) 2007-2009 Stephen McGarry
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+#include "SHT.h"
+
+#include "mbed.h"
+
+SHT::SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy) : sclk(p_sclk), data(p_data), accuracy(p_accuracy) {
+    sclk=0;
+    data=0;               // data pin will be used as open collector pin
+    data.mode(PullUp);    // with the pull up internally active
+    data.input();        // with line released to go high
+    temperature = humidity = dewpoint=0.0f;
+   printf("constructor\n");
+}
+
+char SHT::write_byte(byte value)
+//----------------------------------------------------------------------------------
+// writes a byte on the Sensibus and checks the acknowledge
+{
+    int i;
+    char error=0;
+
+    for (i=0x80;i>0;i/=2) {           //shift bit for masking
+        if (i & value) data.input();  //masking value with i , write to SENSI-BUS
+        else data.output();
+        wait_us(1);                   //ensure sclk is low for min time
+        sclk=1;                       //clk for SENSI-BUS
+        wait_us(1);                   //pulsewith approx. 2 us
+        sclk=0;
+    }
+    data.input();                     //release DATA-line
+    wait_us(1);                       //ensure sclk is low for min time
+    sclk=1;                           //clk #9 for ack
+    error=data;                       //check ack (DATA will be pulled down by SHT11)
+    wait_us(1);
+    sclk=0;
+    return error;                     //error=1 in case of no acknowledge
+}
+
+byte SHT::read_byte(bool send_ack)
+//----------------------------------------------------------------------------------
+// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
+{
+    byte i,val=0;
+    data.input();                     //release DATA-line
+    for (i=0x80;i>0;i/=2) {           //shift bit for masking
+        wait_us(1);
+        sclk=1;                       //clk for SENSI-BUS
+        if (data) val=(val | i);      //read bit
+        wait_us(1);
+        sclk=0;
+    }
+    wait_us(1);
+    if (send_ack) data.output();      // if ack needed then drive data low
+    sclk=1;                           //clk #9 for ack
+    wait_us(1);
+    sclk=0;
+    data.input();                     //release DATA-line
+    return val;
+}
+
+void SHT::trans_start(void)
+//----------------------------------------------------------------------------------
+// generates a transmission start
+//       _____         ________
+// DATA:      |_______|
+//           ___     ___
+// SCK : ___|   |___|   |______
+{
+    data.input();
+    sclk=0;                   //Initial state
+    wait_us(1);
+    sclk=1;
+    wait_us(1);
+    data.output();            // data low
+    wait_us(1);
+    sclk=0;
+    wait_us(1);
+    sclk=1;
+    wait_us(1);
+    data.input();            // allow data to high
+    wait_us(1);
+    sclk=0;
+    wait_us(1);
+}
+
+void SHT::connection_reset(void)
+//----------------------------------------------------------------------------------
+// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
+//       _____________________________________________________         ________
+// DATA:                                                      |_______|
+//          _    _    _    _    _    _    _    _    _        ___     ___
+// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
+{
+    int i;
+    data.input();            // allow data high
+    sclk=0;                  // and clk low
+    for (i=0;i<9;i++) {      // 9 SCK cycles
+        wait_us(1);
+        sclk=1;
+        wait_us(1);
+        sclk=0;
+    }
+}
+char SHT::soft_reset(void)
+//----------------------------------------------------------------------------------
+// resets the sensor by a softreset
+{
+    char error=0;
+    SHT::connection_reset();                //reset communication
+    trans_start();
+    error+=write_byte(com_reset);       //send RESET-command to sensor
+    return error;                     //error=1 in case of no response form the sensor
+}
+
+char SHT::read_status(byte &value)
+//----------------------------------------------------------------------------------
+// reads the status register with checksum (8-bit)
+{
+    //byte checksum;
+
+    char error=0;
+    trans_start();                     //transmission start
+    error=write_byte(com_read_status_reg); //send command to sensor
+    value=read_byte(send_ack);             //read status register (8-bit)
+    /* checksum= */
+    (void)read_byte(no_ack);         //read checksum (8-bit)
+    // check the checksum ??
+    return error;                      //error=1 in case of no response form the sensor
+}
+
+char SHT::write_status(byte value)
+//----------------------------------------------------------------------------------
+// writes the status register (8-bit)
+{
+    char error=0;
+    trans_start();                        //transmission start
+    error+=write_byte(com_write_status_reg); //send command to sensor
+    error+=write_byte(value);            //send value of status register
+    return error;                          //error>=1 in case of no response form the sensor
+}
+
+char SHT::measure(int &value, byte command)
+//----------------------------------------------------------------------------------
+// makes a measurement (humidity/temperature) with checksum
+{
+    unsigned int i;
+    byte msb;
+    // byte checksum;
+
+    trans_start();                //transmission start
+    if (write_byte(command)) return 1; // if command fails return
+
+    for (i=10000;i;i--) {          //wait until sensor has finished the measurement
+        wait_us(100);
+        if (data==0) break;
+    }
+    if (data) return 1;            // or timeout (~1 sec.) is reached !!
+    msb = read_byte(send_ack);         //read the first byte (MSB)
+    value = msb*256 + read_byte(send_ack);    //read the second byte (LSB)
+    /* checksum= */
+    (void)read_byte(no_ack);    //read checksum
+    return 0;
+}
+
+void SHT::calculate()
+//----------------------------------------------------------------------------------------
+// calculates temperature [°C] and humidity [%RH]
+// input :  hum  [Ticks] (12 bit)
+//          temp [Ticks] (14 bit)
+// output:  humidity [%RH]
+//          temperature [°C]
+{
+    const float C1=-4.0;              // for 12 Bit
+    const float C2=+0.0405;           // for 12 Bit
+    const float C3=-0.0000028;        // for 12 Bit
+    //const float T1=+0.01;             // for 14 Bit @ 5V
+    //const float T2=+0.00008;           // for 14 Bit @ 5V
+
+    float rh;                         // rh:      Humidity [Ticks] 12 Bit
+    float t;                          // t:       Temperature [Ticks] 14 Bit
+    //float rh_lin;                     // rh_lin:  Humidity linear
+    if (accuracy==SHT_low) {
+        rh=hum*16;                    // rescale to high accuracy values - 8 to 12 bits
+        t=temp*4;                     // and 12 to 14 bits
+    } else {
+        rh=hum;
+        t=temp;
+    }
+
+    temperature=t*0.01 - 40;                  //calc. temperature from ticks to [°C]
+    humidity=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
+    // =(temperature-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH] (ignore as never >0.25%)
+    if (humidity>100)humidity=100;      //cut if the value is outside of
+    if (humidity<0.1)humidity=0.1;      //the physical possible range
+}
+
+float SHT::get_temperature() {     // get the most recent temp reading
+    return temperature;
+}
+
+float SHT::get_humidity() {        // get the most recent humidity reading
+    return humidity;
+}
+
+float SHT::get_dewpoint() {        // get the most recent dewpoint value
+    return dewpoint;
+}
+
+void SHT::update(SHT_acc acc) {   // update stored values from sensor
+    int error=0;
+    connection_reset();
+    if (acc!=accuracy) {
+        accuracy=acc;
+        error+=write_status((acc==SHT_low)?0x01:0x00);    //set the status reg to high or low accuarcy
+    }
+    error+=measure(temp,com_measure_temp);
+    error+=measure(hum,com_measure_humid);
+    if (!error) calculate();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHT_v1/SHT.h	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,66 @@
+/* mbed module to use a Sensirion SHT1x /SHT7x sensor
+ * Copyright (c) 2007-2009 Stephen McGarry
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+#ifndef SHT_H
+#define SHT_H
+
+#include "mbed.h"
+
+enum SHT_acc {
+    SHT_low=0,
+    SHT_high=1
+};
+
+typedef unsigned char byte;
+
+class SHT : public Base {
+public:
+    /* Constructor: SHT
+     *  Creates an SHT interface connected to specific pins.
+     *
+     */
+    SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy);
+
+    /* Functions
+     */
+    float get_temperature();     // get the most recent temp reading
+    float get_humidity();        // get the most recent humidity reading
+    float get_dewpoint();        // get the most recent dewpoint value
+    void update(SHT_acc accuracy); // update stored values from sensor
+
+protected:
+    byte read_byte(bool send_ack);
+    char write_byte(byte value);
+    void trans_start(void);
+    void connection_reset(void);
+    char soft_reset();
+    char read_status(byte &value);
+    char write_status(byte value);
+    char measure(int &value, byte mode);
+    void calculate();
+
+    DigitalOut sclk;
+    DigitalInOut data;
+    SHT_acc accuracy;    // will we use high or low accuracy mode on the sensor
+
+    float temperature;    // calculated from sensor reading
+    float humidity;
+    float dewpoint;
+    int temp,hum;        // integer values from sensor before conversion
+
+    enum commands {
+        com_read_status_reg=0x06,
+        com_write_status_reg=0x07,
+        com_measure_temp=0x03,
+        com_measure_humid=0x05,
+        com_reset=0x1E
+    };
+
+    enum acks {
+        no_ack=0,
+        send_ack=1
+    };
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WeatherMeters.lib	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okini3939/code/WeatherMeters/#dc42aeff64e6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/conf.cpp	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,392 @@
+/** @file
+ * @brief mbed Weather Platform
+ */
+#include "mbed.h"
+#include "conf.h"
+#include "ConfigFile.h"
+
+extern Serial xbee;
+extern Config conf;
+extern Sensor sensor, offset, sensor_old;
+
+void int_counter();
+
+char* chop (char *s) {
+    int i;
+
+    for (i = strlen(s) - 1; i >= 0; i --) {
+        if (s[i] == ' ' || s[i] == '\n' || s[i] == '\r') {
+            s[i] = 0;
+        } else {
+            break;
+        }
+    }
+    return s;
+}
+
+int check_action (char type) {
+    int i, j, count;
+    float value, vold;
+    time_t sec = time(NULL) + (60 * 60 * 9);
+    struct tm *tim = localtime(&sec);
+
+    for(i = 0; i < conf.actionscount; i ++) {
+        if (conf.actions[i].action != type) continue;
+        
+        count = 0;
+        for (j = 0; j < conf.actions[i].count; j ++) {
+            switch (conf.actions[i].exps[j].key) {
+            case 'P':
+                value = sensor.pres;
+                vold = sensor_old.pres;
+                break;
+            case 'T':
+                value = sensor.temp;
+                vold = sensor_old.temp;
+                break;
+            case 'H':
+                value = sensor.humi;
+                vold = sensor_old.humi;
+                break;
+            case 'A':
+                value = sensor.anemo;
+                vold = sensor_old.anemo;
+                break;
+            case 'V':
+                value = sensor.vane;
+                vold = sensor_old.vane;
+                break;
+            case 'R':
+                value = sensor.rain;
+                vold = sensor_old.rain;
+                break;
+            case 'L':
+                value = sensor.light;
+                vold = sensor_old.light;
+                break;
+            case 'U':
+                value = sensor.uv;
+                vold = sensor_old.uv;
+                break;
+            case 'M':
+                value = sensor.moist;
+                vold = sensor_old.moist;
+                break;
+
+            case 'y':
+                value = tim->tm_year + 1900;
+                break;
+            case 'm':
+                value = tim->tm_mon;
+                break;
+            case 'd':
+                value = tim->tm_mday;
+                break;
+            case 'h':
+                value = tim->tm_hour;
+                break;
+            case 'i':
+                value = tim->tm_min;
+                break;
+            case 's':
+                value = tim->tm_sec;
+                break;
+
+            default:
+                value = 0;
+                break;
+            }
+
+            switch (conf.actions[i].exps[j].expression) {
+            case EXP_EQ:
+                if (value == conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_NE:
+                if (value != conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_LE:
+                if (value <= conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_LT:
+                if (value < conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_GE:
+                if (value >= conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_GT:
+                if (value > conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_MOD:
+                if ((int)value % (int)conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_NMOD:
+                if (! (int)value % (int)conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_FALL:
+                if (value < conf.actions[i].exps[j].value && vold >= conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+            case EXP_RISE:
+                if (value > conf.actions[i].exps[j].value && vold <= conf.actions[i].exps[j].value) {
+                    count ++;
+                }
+                break;
+
+            default:
+                count ++;
+                break;
+            }
+        }
+        if (count == conf.actions[i].count) {
+            return conf.actions[i].sub ? conf.actions[i].sub : ' ';
+        }
+    }
+    return 0;
+}
+
+void add_actionsub (struct tExpression *exp, char *buf) {
+
+    exp->key = buf[0];
+
+    switch (buf[1]) {
+    case '=':
+        if (buf[2] == '=') {
+            exp->expression = EXP_EQ;
+            exp->value = atof(&buf[3]);
+        }
+        break;
+
+    case '!':
+        if (buf[2] == '=') {
+            exp->expression = EXP_NE;
+            exp->value = atof(&buf[3]);
+        } else
+        if (buf[2] == '%') {
+            exp->expression = EXP_NMOD;
+            exp->value = atof(&buf[3]);
+        }
+        break;
+
+    case '<':
+        if (buf[2] == '=') {
+            exp->expression = EXP_LE;
+            exp->value = atof(&buf[3]);
+        } else {
+            exp->expression = EXP_LT;
+            exp->value = atof(&buf[2]);
+        }
+        break;
+
+    case '>':
+        if (buf[2] == '=') {
+            exp->expression = EXP_GE;
+            exp->value = atof(&buf[3]);
+        } else {
+            exp->expression = EXP_GT;
+            exp->value = atof(&buf[2]);
+        }
+        break;
+        
+    case '%':
+        exp->expression = EXP_MOD;
+        exp->value = atof(&buf[2]);
+        break;
+
+    case '_':
+        exp->expression = EXP_FALL;
+        exp->value = atof(&buf[2]);
+        break;
+    case '^':
+        exp->expression = EXP_RISE;
+        exp->value = atof(&buf[2]);
+        break;
+       
+    default:
+        exp->expression = EXP_NULL;
+        break;
+    }
+}
+
+void add_action (char *buf) {
+    int i, len, count;
+    char c;
+    char *tmp = NULL;
+
+    if (conf.actionscount >= CF_ACTION_NUM) return;
+
+//    conf.actions[conf.actionscount].action = atoi(&buf[0]);
+    conf.actions[conf.actionscount].action = buf[0];
+    conf.actions[conf.actionscount].sub = buf[1];
+
+    count = 0;
+    strcat(buf, "\n");
+    len = strlen(buf);
+    for (i = 1; i < len; i ++) {
+        c = buf[i];
+        if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
+            buf[i] = 0;
+            if (count) {
+                add_actionsub(&conf.actions[conf.actionscount].exps[count - 1], tmp);
+            }
+            if (count >= CF_ACTION_EXPS || c == '\n') break;
+            tmp = &buf[i + 1];
+            count ++;
+        }
+    }
+
+    conf.actions[conf.actionscount].count = count;
+    conf.actionscount ++;
+}
+
+int config (char *file) {
+    int i;
+    ConfigFile cfg;
+    char buf[80], key[20];
+    int ip0, ip1, ip2, ip3;
+    
+    conf.ipaddr = IpAddr(0, 0, 0, 0);
+    conf.netmask = IpAddr(255, 255, 255, 0);
+    conf.gateway = IpAddr(0, 0, 0, 0);
+    conf.nameserver = IpAddr(0, 0, 0, 0);
+    conf.interval = 60;
+    conf.ntpserver[0] = 0;
+    conf.filetype = 0;
+    conf.actionscount = 0;
+    conf.pachube_apikey[0] = 0;
+    conf.pachube_feedid[0] = 0;
+    conf.twitter_user[0] = 0;
+    conf.twitter_pwd[0] = 0;
+    for (i = 0; i < CF_TWITTER_NUM; i ++) {
+        conf.twitter_mesg[i][0] = 0;
+    }
+    conf.stations_id[0] = 0;
+    conf.stations_pin[0] = 0;
+    conf.snmp_commname[0] = 0;
+    conf.leddisp_mesg[0] = 0;
+    conf.lcd_mesg[0] = 0;
+    conf.lcdtype = LCD16x2;
+    conf.lcdconf = LCDCFG_3V;
+    memset(&offset, 0, sizeof(offset));
+    memset(&sensor_old, 0, sizeof(sensor_old));
+
+    if (! cfg.read(file)) {
+        return -1;
+    }
+
+    if (cfg.getValue("INTERVAL", buf, sizeof(buf))) {
+        conf.interval = atoi(chop(buf));
+    }
+    if (cfg.getValue("FILE", buf, sizeof(buf))) {
+        chop(buf);
+        if (strcmp(buf, "SD") == 0) {
+            conf.filetype = 1;
+        } else
+        if (strcmp(buf, "USB") == 0) {
+            conf.filetype = 2;
+        }
+    }
+
+    if (cfg.getValue("IPADDRESS", buf, sizeof(buf))) {
+        chop(buf);
+        if (strcmp(buf, "DHCP") == 0) {
+            conf.ipaddr = IpAddr(255, 255, 255, 255);
+        } else {
+            sscanf(buf, "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
+            conf.ipaddr = IpAddr(ip0, ip1, ip2, ip3);
+        }
+    }
+    if (cfg.getValue("NETMASK", buf, sizeof(buf))) {
+        sscanf(chop(buf), "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
+        conf.netmask = IpAddr(ip0, ip1, ip2, ip3);
+    }
+    if (cfg.getValue("GATEWAY", buf, sizeof(buf))) {
+        sscanf(chop(buf), "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
+        conf.gateway = IpAddr(ip0, ip1, ip2, ip3);
+    }
+    if (cfg.getValue("NAMESERVER", buf, sizeof(buf))) {
+        sscanf(chop(buf), "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
+        conf.nameserver = IpAddr(ip0, ip1, ip2, ip3);
+    }
+
+    cfg.getValue("NTPSERVER", conf.ntpserver, sizeof(conf.ntpserver));
+    chop(conf.ntpserver);
+    cfg.getValue("PACHUBE_APIKEY", conf.pachube_apikey, sizeof(conf.pachube_apikey));
+    chop(conf.pachube_apikey);
+    cfg.getValue("PACHUBE_FEEDID", conf.pachube_feedid, sizeof(conf.pachube_feedid));
+    chop(conf.pachube_feedid);
+    cfg.getValue("TWITTER_USER", conf.twitter_user, sizeof(conf.twitter_user));
+    chop(conf.twitter_user);
+    cfg.getValue("TWITTER_PWD", conf.twitter_pwd, sizeof(conf.twitter_pwd));
+    chop(conf.twitter_pwd);
+    cfg.getValue("TWITTER_MESG", conf.twitter_mesg[0], sizeof(conf.twitter_mesg[0]));
+    chop(conf.twitter_mesg[0]);
+    for (i = 0; i < CF_TWITTER_NUM; i ++) {
+        sprintf(key, "TWITTER_MESG[%d]", i);
+        cfg.getValue(key, conf.twitter_mesg[i], sizeof(conf.twitter_mesg[i]));
+        chop(conf.twitter_mesg[i]);
+    }
+
+    cfg.getValue("STATIONS_ID", conf.stations_id, sizeof(conf.stations_id));
+    chop(conf.stations_id);
+    cfg.getValue("STATIONS_PIN", conf.stations_pin, sizeof(conf.stations_pin));
+    chop(conf.stations_pin);
+    cfg.getValue("SNMP_COMMNAME", conf.snmp_commname, sizeof(conf.snmp_commname));
+    chop(conf.snmp_commname);
+
+    if (cfg.getValue("LCD_TYPE", buf, sizeof(buf))) {
+        conf.lcdtype = (enum I2CLCDType)atoi(chop(buf));
+    }
+    if (cfg.getValue("LCD_CONF", buf, sizeof(buf))) {
+        conf.lcdconf = (enum I2CLCDConfig)atoi(chop(buf));
+    }
+    if (cfg.getValue("LCD_MESG", conf.lcd_mesg, sizeof(conf.lcd_mesg))) {
+        chop(conf.lcd_mesg);
+    }
+    if (cfg.getValue("LEDDISP_MESG", conf.leddisp_mesg, sizeof(conf.leddisp_mesg))) {
+        chop(conf.leddisp_mesg);
+    }
+
+    if (cfg.getValue("XBEE", buf, sizeof(buf))) {
+        xbee.baud(atoi(chop(buf)));
+    }
+
+    if (cfg.getValue("INPUT", buf, sizeof(buf))) {
+        conf.inputtype = (enum eINPUTTYPE)atoi(chop(buf));
+    }
+
+    for (i = 0; i < CF_ACTION_NUM; i ++) {
+        sprintf(key, "ACTION[%d]", i);
+        if (cfg.getValue(key, buf, sizeof(buf))) {
+            add_action(chop(buf));
+        }
+    }
+
+    if (cfg.getValue("OFFSET[P]", buf, sizeof(buf))) {
+        offset.pres = atof(chop(buf));
+    }
+    if (cfg.getValue("OFFSET[T]", buf, sizeof(buf))) {
+        offset.temp = atof(chop(buf));
+    }
+    if (cfg.getValue("OFFSET[H]", buf, sizeof(buf))) {
+        offset.humi = atof(chop(buf));
+    }
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/conf.h	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,72 @@
+/** @file
+ * @brief mbed Weather Platform
+ */
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "I2CLEDDisp.h"
+#include "I2CLCD.h"
+
+#define CONFIG_FILE "weather.cfg"
+
+
+#define CF_MAXLEN_VALUE 128
+#define CF_ACTION_EXPS 10
+#define CF_ACTION_NUM 10
+#define CF_TWITTER_NUM 5
+
+enum eEXPRESSION {
+    EXP_NULL,
+    EXP_EQ,
+    EXP_NE,
+    EXP_LE,
+    EXP_LT,
+    EXP_GE,
+    EXP_GT,
+    EXP_MOD,
+    EXP_NMOD,
+    EXP_FALL,
+    EXP_RISE,
+};
+
+enum eINPUTTYPE {
+    INPUT_MOIST = 0,
+    INPUT_FALL = 1,
+    INPUT_RISE = 2,
+    INPUT_CPM = 4,
+};
+
+struct tExpression {
+    char key;
+    enum eEXPRESSION expression;
+    float value;
+};
+
+struct tAction {
+    char action;
+    char sub;
+    int count;
+    struct tExpression exps[CF_ACTION_EXPS];
+};
+
+struct Sensor {
+    float pres, temp, humi, light, anemo, vane, rain, uv, moist, temp2;
+};
+
+struct Config {
+    int interval;
+    IpAddr ipaddr, netmask, gateway, nameserver;
+    char ntpserver[32];
+    int filetype, actionscount;
+    struct tAction actions[CF_ACTION_NUM];
+    char pachube_apikey[70], pachube_feedid[8];
+    char twitter_user[30], twitter_pwd[30], twitter_mesg[CF_TWITTER_NUM][CF_MAXLEN_VALUE];
+    char stations_id[8], stations_pin[34];
+    char snmp_commname[30];
+    char lcd_mesg[CF_MAXLEN_VALUE];
+    enum I2CLCDType lcdtype;
+    enum I2CLCDConfig lcdconf;
+    char leddisp_mesg[CF_MAXLEN_VALUE];
+    enum eINPUTTYPE inputtype;
+};
+
+int config (char *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/func.cpp	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,274 @@
+#include "mbed.h"
+#include "ConfigFile.h"
+#include "SDHCFileSystem.h"
+#include "EthernetNetIf.h"
+#include "NTPClient.h"
+#include "HTTPClient.h"
+#include "conf.h"
+
+#define TIMEZONE 9
+//#define NONBLOCKING
+/** @file
+ * @brief mbed Weather Platform
+ */
+
+#define STATION_URL "http://weather.sugakoubou.com/p"
+#define TWITTER_URL "http://api.supertweet.net/1/statuses/update.xml"
+
+extern Serial pc;
+extern int seq;
+extern char filename[];
+extern Config conf;
+extern DigitalOut led_y, led2;
+
+extern EthernetNetIf *eth; 
+extern NTPClient *ntp;
+extern HTTPClient *clientP, *clientT;
+extern Sensor sensor;
+
+void writefile (char *buf) {
+    FILE *fp;
+
+    fp = fopen(filename, "a");
+    if (fp) {
+        fprintf(fp, buf);
+        fclose(fp);
+    } else {
+        led2 = 0;
+        conf.filetype = 0;
+    }
+}
+
+void weatherstations () {
+    char post_data[200];
+    HTTPResult ret;
+    HTTPText postContent("application/x-www-form-urlencoded");
+
+    led_y = 0;
+    strcpy(post_data, "fcd=");
+    strcat(post_data, conf.stations_id);
+    strcat(post_data, "&pin=");
+    strcat(post_data, conf.stations_pin);
+    sprintf(&post_data[strlen(post_data)], "&d0=%.2f&d1=%.2f&d2=%.2f&d3=%.2f&d4=%.2f&d5=%.2f&d6=%.2f&d7=%.2f&d8=%.2f&d9=%.2f",
+      sensor.pres, sensor.temp, sensor.humi, sensor.anemo, sensor.vane, sensor.rain, sensor.light, sensor.uv, sensor.moist, sensor.temp2);
+    postContent.puts(post_data);
+
+#ifdef NONBLOCKING
+    Net::poll();
+    ret = clientP->post(STATION_URL, postContent, NULL, &cb_clientP);
+    Net::poll();
+#else
+    ret = clientP->post(STATION_URL, postContent, NULL);
+#endif
+
+    if (ret != HTTP_OK && ret != HTTP_PROCESSING) {
+        pc.printf("error: Weather Statuons %d\r\n", ret);
+    }
+}
+
+void pachube (char *buf) {
+    char uri[100];
+    HTTPResult ret;
+    HTTPText csvContent("text/csv");
+
+    led_y = 0;
+    clientP->setRequestHeader("X-PachubeApiKey", conf.pachube_apikey);
+    csvContent.set(buf);
+    strcpy(uri, "http://api.pachube.com/v1/feeds/");
+    strcat(uri, conf.pachube_feedid);
+    strcat(uri, ".csv?_method=put");
+#ifdef NONBLOCKING
+    Net::poll();
+    ret = clientP->post(uri, csvContent, NULL, &cb_clientP);
+    Net::poll();
+#else
+    ret = clientP->post(uri, csvContent, NULL);
+#endif
+
+    if (ret != HTTP_OK && ret != HTTP_PROCESSING) {
+        pc.printf("error: Pachube %d\r\n", ret);
+    }
+}
+
+void cb_clientP (HTTPResult status) {
+    if (status != HTTP_OK) {
+        pc.printf("Pachube failure (%d)\r\n", status);
+//        pc.printf("Pachube failure (%d, %d)\r\n", status, clientP->getHTTPResponseCode());
+    }
+}
+
+char *fmtstr (char *fmt, char *buf, int len) {
+    int i, j, flg;
+    char c;
+    float value;
+    time_t sec = time(NULL);
+    struct tm *tim = localtime(&sec);
+
+    j = 0;
+    for (i = 0; i < strlen(fmt) && j < len; i ++) {
+        c = fmt[i];
+        if (c == '%') {
+            flg = 0;
+            i ++;
+            c = fmt[i];
+            
+            if (c == '.') {
+                // float format
+                if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') {
+                    flg = fmt[i + 1] - '0';
+                    i ++;
+
+                    c = fmt[i + 1];
+                    i ++;
+                }
+            }
+
+            switch (c) {
+            case 'P':
+                value = sensor.pres;
+                break;
+            case 'T':
+                value = sensor.temp;
+                break;
+            case 'H':
+                value = sensor.humi;
+                break;
+            case 'A':
+                value = sensor.anemo;
+                break;
+            case 'V':
+                value = sensor.vane;
+                break;
+            case 'R':
+                value = sensor.rain;
+                break;
+            case 'L':
+                value = sensor.light;
+                break;
+            case 'U':
+                value = sensor.uv;
+                break;
+            case 'M':
+                value = sensor.moist;
+                break;
+
+            case 'y':
+                value = tim->tm_year + 1900;
+                break;
+            case 'm':
+                value = tim->tm_mon;
+                break;
+            case 'd':
+                value = tim->tm_mday;
+                break;
+            case 'h':
+                value = tim->tm_hour;
+                break;
+            case 'i':
+                value = tim->tm_min;
+                break;
+            case 's':
+                value = tim->tm_sec;
+                break;
+
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                // Ascii
+                c = c - '0';
+                if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') {
+                    c = (c << 3) | (fmt[i + 1] - '0');
+                    i ++;
+                    if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') {
+                        c = (c << 3) | (fmt[i + 1] - '0');
+                        i ++;
+                    }
+                }
+                buf[j] = c;
+                j ++;
+                continue;
+
+            default:
+                buf[j] = c;
+                j ++;
+                continue;
+            }
+
+            switch (flg) {
+            case 1:
+                sprintf(&buf[j], "%.1f", value);
+                break;
+            case 2:
+                sprintf(&buf[j], "%.2f", value);
+                break;
+            default:
+                sprintf(&buf[j], "%02d", (int)value);
+                break;
+            }
+            j = strlen(buf);
+        } else {
+            buf[j] = c;
+            j ++;
+        }
+    }
+    buf[j] = 0;
+    return buf;
+}
+
+void twitter (int num) {
+    HTTPMap msg;
+    HTTPResult ret;
+    char buf[170];
+
+    led_y = 0;
+    fmtstr(conf.twitter_mesg[num], buf, sizeof(buf));
+    msg["status"] = buf;
+
+    clientT->basicAuth(conf.twitter_user, conf.twitter_pwd);
+#ifdef NONBLOCKING
+    Net::poll();
+    ret = clientT->post(TWITTER_URL, msg, NULL, &cb_clientT); 
+    Net::poll();
+#else
+    ret = clientT->post(TWITTER_URL, msg, NULL); 
+#endif
+
+    if (ret != HTTP_OK && ret != HTTP_PROCESSING) {
+        pc.printf("error: Twitter %d\r\n", ret);
+    }
+}
+
+void ntpdate () {
+    ntp = new NTPClient;
+    Host ntpserver(IpAddr(), 123, conf.ntpserver);
+
+    led_y = 0;
+#ifdef NONBLOCKING
+    Net::poll();
+    ntp->setTime(ntpserver, &cb_settime);
+    Net::poll();
+#else
+    ntp->setTime(ntpserver);
+    time_t sec = time(NULL) + (60 * 60 * TIMEZONE);
+    set_time(sec);
+#endif
+}
+
+void cb_settime (NTPResult status) {
+    if (status == NTP_OK) {
+        led_y = 0;
+        time_t sec = time(NULL) + (60 * 60 * TIMEZONE);
+        set_time(sec);
+        pc.printf("Ntp success: %s\r\n", ctime(&sec));
+    } else {
+        pc.printf("Ntp failure (%d)\r\n", status);
+    }
+//    ntp->close();
+}
--- /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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/snmp.cpp	Wed May 18 15:01:56 2011 +0000
@@ -0,0 +1,179 @@
+/**
+* Agentbed SNMP Server
+*  Modified for mbed, 2011 Suga.
+*
+* Agentuino SNMP Agent Library Prototyping...
+* Copyright 2010 Eric C. Gionet <lavco_eg@hotmail.com>
+*/
+#include "mbed.h"
+#include "Agentbed.h"
+#include "EthernetNetIf.h"
+#include "ConfigFile.h"
+#include "conf.h"
+
+AgentbedClass Agentbed;
+
+// RFC1213-MIB OIDs
+// .iso (.1)
+// .iso.org (.1.3)
+// .iso.org.dod (.1.3.6)
+// .iso.org.dod.internet (.1.3.6.1)
+// .iso.org.dod.internet.mgmt (.1.3.6.1.2)
+// .iso.org.dod.internet.mgmt.mib-2 (.1.3.6.1.2.1)
+// .iso.org.dod.internet.mgmt.mib-2.system (.1.3.6.1.2.1.1)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysDescr (.1.3.6.1.2.1.1.1)
+const char sysDescr[]    = "1.3.6.1.2.1.1.1.0";  // read-only  (DisplayString)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysObjectID (.1.3.6.1.2.1.1.2)
+const char sysObjectID[] = "1.3.6.1.2.1.1.2.0";  // read-only  (ObjectIdentifier)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysUpTime (.1.3.6.1.2.1.1.3)
+const char sysUpTime[]   = "1.3.6.1.2.1.1.3.0";  // read-only  (TimeTicks)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysContact (.1.3.6.1.2.1.1.4)
+const char sysContact[]  = "1.3.6.1.2.1.1.4.0";  // read-write (DisplayString)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysName (.1.3.6.1.2.1.1.5)
+const char sysName[]     = "1.3.6.1.2.1.1.5.0";  // read-write (DisplayString)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysLocation (.1.3.6.1.2.1.1.6)
+const char sysLocation[] = "1.3.6.1.2.1.1.6.0";  // read-write (DisplayString)
+// .iso.org.dod.internet.mgmt.mib-2.system.sysServices (.1.3.6.1.2.1.1.7)
+const char sysServices[] = "1.3.6.1.2.1.1.7.0";  // read-only  (Integer)
+//
+// Arduino defined OIDs
+// .iso.org.dod.internet.private (.1.3.6.1.4)
+// .iso.org.dod.internet.private.enterprises (.1.3.6.1.4.1)
+// .iso.org.dod.internet.private.enterprises.arduino (.1.3.6.1.4.1.36582)
+const char enterprises[] = "1.3.6.1.4.1.36582.";  // read-only  (Integer)
+//
+//
+// RFC1213 local values
+static char locDescr[]              = "mbed Weather Platform";  // read-only (static)
+static char locObjectID[]           = "1.3.6.1.4.1.36582";                       // read-only (static)
+uint32_t locUpTime           = 0;                                        // read-only (static)
+static char locContact[]            = "<root@weather>";                            // should be stored/read from EEPROM - read/write (not done for simplicity)
+static char locName[]               = "weather.mbed";                              // should be stored/read from EEPROM - read/write (not done for simplicity)
+static char locLocation[]           = "weather";                        // should be stored/read from EEPROM - read/write (not done for simplicity)
+static int32_t locServices          = 7;                                        // read-only (static)
+
+uint32_t prevMillis = 0;
+char oid[SNMP_MAX_OID_LEN];
+SNMP_API_STAT_CODES api_status;
+SNMP_ERR_CODES status;
+
+extern DigitalOut led_y;
+extern Sensor sensor;
+
+void pduReceived()
+{
+  SNMP_PDU pdu;
+  //
+  led_y = 1;
+  api_status = Agentbed.requestPdu(&pdu);
+  //
+  if ( pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET
+    && pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
+    //
+    pdu.OID.toString(oid);
+    //
+    pdu.error = SNMP_ERR_READ_ONLY;
+    //
+    if ( strcmp(oid, sysDescr ) == 0 ) {
+      // handle sysDescr (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locDescr
+        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysObjectID ) == 0 ) {
+      // handle sysName (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locUpTime
+        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locObjectID);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysUpTime ) == 0 ) {
+      // handle sysName (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locUpTime
+        status = pdu.VALUE.encode(SNMP_SYNTAX_TIME_TICKS, locUpTime);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysName ) == 0 ) {
+      // handle sysName (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locName
+        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locName);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysContact ) == 0 ) {
+      // handle sysContact (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locContact
+        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locContact);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysLocation ) == 0 ) {
+      // handle sysLocation (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locLocation
+        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locLocation);
+        pdu.error = status;
+      }
+    } else if ( strcmp(oid, sysServices) == 0 ) {
+      // handle sysServices (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - locServices
+        status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locServices);
+        pdu.error = status;
+      }
+    } else if ( strncmp(oid, enterprises, strlen(enterprises)) == 0 ) {
+      // handle enterprises (set/get) requests
+      if ( pdu.type == SNMP_PDU_GET ) {
+        // response packet from get-request - enterprises
+        switch (oid[strlen(enterprises)]) {
+        case '0':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.pres);
+            break;
+        case '1':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.temp);
+            break;
+        case '2':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.humi);
+            break;
+        case '3':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.anemo);
+            break;
+        case '4':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.vane);
+            break;
+        case '5':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.rain);
+            break;
+        case '6':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.light);
+            break;
+        case '7':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.uv);
+            break;
+        case '8':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.moist);
+            break;
+        case '9':
+            status = pdu.VALUE.encode(SNMP_SYNTAX_OPAQUE_FLOAT, sensor.temp2);
+            break;
+        }
+        pdu.error = status;
+      }
+    } else {
+      // oid does not exist
+      //
+      // response packet - object not found
+      pdu.error = SNMP_ERR_NO_SUCH_NAME;
+    }
+    //
+    pdu.type = SNMP_PDU_RESPONSE;
+
+    Agentbed.responsePdu(&pdu);
+  }
+  //
+  Agentbed.freePdu(&pdu);
+  //
+  //Serial << "UDP Packet Received End.." << " RAM:" << freeMemory() << endl;
+}