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-03-19
Revision:
13:20c0f845df68
Parent:
12:d9264218a5e9
Child:
14:ee6cc1632166

File content as of revision 13:20c0f845df68:

/*
 * 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.0 (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 "SDFileSystem.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];
Config 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), 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 ();
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) {
    if (check_action('h')) {
        swout1 = 1;
        led3 = 1;
    }
    if (check_action('l')) {
        swout1 = 0;
        led3 = 0;
    }
    if (check_action('H')) {
        swout2 = 1;
        led4 = 1;
    }
    if (check_action('L')) {
        swout2 = 0;
        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();
        }
    }
    if (check_action('X')) {
        xbee.printf(buf);
    }
}

void init () {
    FILE *fp;

    config(CONFIG_FILE);

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

    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.ipaddr[0]) {
        led_g = eth_link ? 0 : 1;
        led_g2 = 0;
    }
    
    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();
        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);
        if (conf.inputtype == INPUT_MOIST) {
            moist = get_moist(*aimoist);
        } else {
            moist = get_counter(0);
        }
        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);
        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();
    }
}