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

main.cpp

Committer:
okini3939
Date:
2011-01-12
Revision:
5:9fa79cb5ec98
Parent:
3:60f5f6d5f765
Child:
6:060cb9725ce3

File content as of revision 5:9fa79cb5ec98:

/*
 * mbed Weather Platform
 * Copyright (c) 2010 Hiroshi Suga
 * Released under the MIT License: http://mbed.org/license/mit
 */

/** @file
 * @brief mbed Weather Platform
 */

#define VERSION "mbed Weather Platform 0.1.1 (C) 2010 Suga koubou Co.,Ltd."
#define USE_I2CLEDDISP // I2C LED Display
//#define NONBLOCKING // ethernet function non-bloking
 
#include "mbed.h"
#include "BMP085.h"
#include "SHT.h"
#include "WeatherMeters.h"
#include "ConfigFile.h"
#include "SDFileSystem.h"
#include "MSCFileSystem.h"
#include "EthernetNetIf.h"
#include "NTPClient.h"
#include "HTTPClient.h"
#include "Agentbed.h"

#ifdef USE_I2CLEDDISP
#include "I2CLEDDisp.h"
#endif

Serial pc(USBTX, USBRX);
int seq = 0;
char filename[20];
ConfigFile conf;
DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
SDFileSystem sd(p5, p6, p7, p8, "sd"); 
MSCFileSystem *usb;

// Sensors
float pres, temp, humi, light, anemo, vane, rain, uv, moist, temp2;
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), aimoist(p18), aiuv(p17);

#ifdef USE_I2CLEDDISP
I2CLEDDisp leddisp(i2c);
Ticker ticker;
int ledpos, ledflg;
char ledbuf[100];
#endif

// Ethernet
EthernetNetIf *eth; 
NTPClient *ntp;
HTTPClient *clientP, *clientT;
DigitalOut 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 *);
void twitter ();
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;
}

#ifdef USE_I2CLEDDISP
void ledscroll () {
    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;
    }
}
#endif

void action (char *buf) {
    if (check_action('H')) {
        led4 = 1;
    }
    if (check_action('L')) {
        led4 = 0;
    }
    if (check_action('P')) {
        if (conf.ipaddr[0] && conf.pachube_apikey[0] && conf.pachube_feedid[0]) {
            pachube(buf);
        }
    }
    if (check_action('T')) {
        if (conf.ipaddr[0] && conf.twitter_user[0] && conf.twitter_pwd[0]) {
            twitter();
        }
    }
    if (check_action('S')) {
        if (conf.ipaddr[0] && conf.stations_id[0] && conf.stations_pin[0]) {
            weatherstations();
        }
    }
}

void init () {
    FILE *fp;

    conf.load("/sd/weather.cf");

    pc.printf("Interval: %d sec\r\n", conf.interval);

    if (conf.ipaddr[0]) {
        // use ethernet

        eth_link.mode(PullUp);
        eth_speed.mode(PullUp);
        led_g = eth_link ? 1 : 0;
        led_y = eth_speed ? 1 : 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);
            }
        }
    }

    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;
        }
    }
}

int main () {
    Timer timer;
    time_t sec;
    char buf[100];
    
    led1 = 1;
#ifdef USE_I2CLEDDISP
    ledflg = 0;
    ledpos = -4;
    strcpy(ledbuf, VERSION);
    ticker.attach(&ledscroll, 0.4);
#endif
    init();
    pc.printf(VERSION "\r\n\r\n");

    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);
    }
    
#ifdef USE_I2CLEDDISP
    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");
        }
    }
#endif
    
    timer.start();
#ifdef NONBLOCKING
    while (timer.read() < 5) {
        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
        bmp085.update();
        pres = bmp085.get_pressure();
        temp2 = bmp085.get_temperature();

        sht15.update(SHT_high);
        temp = sht15.get_temperature();
        humi = sht15.get_humidity();

        anemo = wmeters.get_windspeed();
        vane = wmeters.get_windvane();
        rain = wmeters.get_raingauge();

        light = get_photo(ailight);
        moist = get_moist(aimoist);
        uv = get_uv(aiuv);

        sprintf(&buf[strlen(buf)], ",%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\r\n", pres, temp, humi, anemo, vane, rain, light, uv, moist, temp2);
        pc.printf(buf);
        if (conf.filetype) {
            // csv
            writefile(buf);
        }

        action(&buf[20]);

#ifdef USE_I2CLEDDISP
        if (ledflg) {
            ledpos = -4;
            strftime(ledbuf, sizeof(ledbuf), "%H:%M", localtime(&sec));
            sprintf(&ledbuf[5], " %dhPa %d\x1b %d%% %dm/s %d' %dmm/h", (int)pres, (int)temp, (int)humi, (int)anemo, (int)vane, (int)rain);
        }
        ledflg = 1;
#endif
        led1 = 1;

        while (timer.read() < conf.interval) {
//            wait(1);
//            pc.putc('.');
            led_g = eth_link ? 1 : 0;
            led_y = eth_speed ? 1 : 0;
            Net::poll();
        }
        timer.reset();
        locUpTime = locUpTime + (conf.interval * 100);
    }
}