mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/
Dependencies: ChaNFSSD EthernetNetIf I2CLEDDisp Agentbed ChaNFSUSB ILinterpreter mbed BMP085 WeatherMeters ConfigFile ChaNFS I2CLCD
Diff: sensor.cpp
- Revision:
- 0:bdb53686c194
- Child:
- 1:6c7141895545
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sensor.cpp Mon Jul 04 15:16:45 2011 +0000 @@ -0,0 +1,273 @@ +#include "mbed.h" +#include "weather.h" +#include "BMP085.h" +#include "SHT.h" +#include "WeatherMeters.h" + +#define AREF 3.3 // V + +Sensor sensor, offset, sensor_old; +I2C i2c(p9, p10); +static BMP085 bmp085(i2c, BMP085_oss4); +static SHT sht15(p12, p11, SHT_high); // sclock, data +static WeatherMeters wmeters(p21, p15, p22); // anemo, vane, rain +static AnalogIn ailight(p16), aiuv(p17); +static AnalogIn *aimoist; +static InterruptIn *intin; +static volatile int count_counter; +static volatile unsigned long lastCountTime; +static volatile int inputtype; + +float get_light (AnalogIn &ain) { + float f; + + f = ain * AREF / 1000; // A + return f / 0.0000026; // lx +} + +float get_uv (AnalogIn &ain) { + float f; + + f = ain * AREF / 100000; // A + f = f / 0.000384; // mW/cm2 + if (f < 0) f = 0; + return f; +} + +float get_moist (AnalogIn &ain) { + float f; + + f = ain * AREF; // V + f = f / ((AREF - f) / 10.0); // k ohm + if (f < 0) f = 0; + return f; +} + +void isr_counter () { + count_counter ++; +} + +float get_counter (char flg) { + float t; + + if (flg) { + // count + t = (float)count_counter; + } else { + // count/min + 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; +} + +int update_sensor () { + + sensor.sec = time(NULL); + + 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_light(ailight); + sensor.uv = get_uv(aiuv); + + if (inputtype) { + // counter + sensor.moist = get_counter(inputtype & INPUT_CPM ? 0 : 1); + } else { + // moist sensor + sensor.moist = get_moist(*aimoist); + } + + return 0; +} + +int init_sensor () { + char buf[20]; + + memset(&sensor, 0, sizeof(sensor)); + sensor.sec = time(NULL); + sensor_old = sensor; + offset = sensor; + + // moist sensor or counter + if (cfg.getValue("INPUT", buf, sizeof(buf))) { + // counter + inputtype = atoi(buf); + intin = new InterruptIn(p18); + if (inputtype & INPUT_FALL) { + intin->fall(&isr_counter); + } + if (inputtype & INPUT_RISE) { + intin->rise(&isr_counter); + } + } else { + // moist + aimoist = new AnalogIn(p18); + } + + if (cfg.getValue("OFFSET[P]", buf, sizeof(buf))) { + offset.pres = atof(buf); + } + if (cfg.getValue("OFFSET[T]", buf, sizeof(buf))) { + offset.temp = atof(buf); + } + if (cfg.getValue("OFFSET[H]", buf, sizeof(buf))) { + offset.humi = atof(buf); + } + + return 0; +} + +char *format_str (const 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 'p': + value = sensor.temp; + break; + + case 'y': + value = tim->tm_year + 1900; + flg = -1; + break; + case 'm': + value = tim->tm_mon; + flg = -1; + break; + case 'd': + value = tim->tm_mday; + flg = -1; + break; + case 'h': + value = tim->tm_hour; + flg = -1; + break; + case 'i': + value = tim->tm_min; + flg = -1; + break; + case 's': + value = tim->tm_sec; + flg = -1; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // Ascii code + 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; + case -1: + sprintf(&buf[j], "%02d", (int)value); + break; + default: + sprintf(&buf[j], "%d", (int)value); + break; + } + j = strlen(buf); + } else { + // plain + buf[j] = c; + j ++; + } + } + buf[j] = 0; + return buf; +}