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

sensor.cpp

Committer:
okini3939
Date:
2012-03-16
Revision:
8:bed0b81794ba
Parent:
7:f7c98d836f81

File content as of revision 8:bed0b81794ba:

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

/** @file
 * @brief Weather Station
 */

#include "mbed.h"
#include "weather.h"
#include "BMP085.h"
#include "SHT.h"
#include "WeatherMeters.h"

#define AREF 3.3 // V

struct 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 = 0;
static volatile unsigned long lastCountTime = 0;

float get_light (AnalogIn &ain) {
    float f;
    
    f = ain * AREF / REG_LIGHT; // A
    return f / 0.0026; // lx
}

float get_uv (AnalogIn &ain) {
    float f;
    
    f = ain * AREF / REG_UV; // 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) / REG_MOIST); // 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() + offset.vane;
    sensor.rain = wmeters.get_raingauge();

    sensor.light = get_light(ailight);
    sensor.uv = get_uv(aiuv);

    if (conf.inputtype == INPUT_MOIST) {
        // moist sensor
        sensor.moist = get_moist(*aimoist);
    } else
    if (conf.inputtype & (INPUT_FALL|INPUT_RISE)) {
        // counter
        sensor.moist = get_counter(conf.inputtype & INPUT_CPM ? 0 : 1);
    }

    return 0;
}

int init_sensor () {

    memset(&sensor, 0, sizeof(sensor));
    sensor.sec = time(NULL);
    sensor_old = sensor;

    // moist sensor or counter
    if (conf.inputtype == INPUT_MOIST) {
        // moist
        aimoist = new AnalogIn(p18);
    } else
    if (conf.inputtype & (INPUT_FALL|INPUT_RISE)) {
        // counter
        intin = new InterruptIn(p18);
        if (conf.inputtype & INPUT_FALL) {
            intin->mode(PullUp);
            intin->fall(&isr_counter);
        }
        if (conf.inputtype & INPUT_RISE) {
            intin->mode(PullDown);
            intin->rise(&isr_counter);
        }
    }

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

                    // next char
                    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.temp2;
                break;

            case 'y':
                value = tim->tm_year + 1900;
                flg = -1;
                break;
            case 'm':
                value = tim->tm_mon + 1;
                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;

            case 'n':
                buf[j] = '\n';
                j ++;
                continue;
            case 'r':
                buf[j] = '\r';
                j ++;
                continue;
            default:
                buf[j] = c;
                j ++;
                continue;
            }

            switch (flg) {
            case 1:
                snprintf(&buf[j], len - j, "%.1f", value);
                break;
            case 2:
                snprintf(&buf[j], len - j, "%.2f", value);
                break;
            case -1:
                snprintf(&buf[j], len - j, "%02d", (int)value);
                break;
            default:
                snprintf(&buf[j], len - j, "%d", (int)value);
                break;
            }
            j = strlen(buf);
        } else {
            // plain
            buf[j] = c;
            j ++;
        }
    }
    buf[j] = 0;
    return buf;
}