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
Diff: main.cpp
- 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(); + } +}