Barometer for EA LPC11U35 QuickStart Board see: https://mbed.org/users/okini3939/notebook/barometer/

Dependencies:   BMP085 PCF2119 WDT mbed

main.cpp

Committer:
okini3939
Date:
2014-07-11
Revision:
0:ac9cb7d35d0c

File content as of revision 0:ac9cb7d35d0c:

/*
 * Barometer for EA LPC11U35 QuickStart Board
 */
#include "mbed.h"
#include "PCF2119.h"
#include "BMP085.h"
#include "WDT.h"

DigitalOut myled(LED1), led_r(P0_22), led_g(P1_15), led_b(P0_23);
I2C i2c(P0_5, P0_4);
PCF2119 lcd(i2c, P0_21);
BMP085 bmp(i2c, BMP085_oss8);
Watchdog wdt;
AnalogIn vsens(P0_11);
DigitalOut vpwr(P0_12);

float p, t, b;
float vals[35];
float ave = 0;
int count = 0, ud = 0;

char gaiji[5][8] = {
    {0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x1f, 0},
    {0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0},
    {0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0},
    {0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0},
    {0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0},
};
char graph[16][8];
char updown[3] = {0x12, 0x32, 0x10};

// draw screen
void draw () {
    int i, n;
    float min, max, v;
    int bit, byte;

    // check min/max
    min = vals[0];
    max = vals[0];
    for (i = 0; i < 35; i ++) {
        if (vals[i] > 800 && vals[i] < 1200) {
            if (vals[i] < min) min = vals[i];
            if (vals[i] > max) max = vals[i];
        }
    }
    min -= 0.5;
    max += 0.5;
    v = max - min;

    // create graph
    memset(&graph, 0, sizeof(graph));
    bit = 1;
    byte = 6;
    for (i = 0; i < 35; i ++) {
        n = (vals[i] - min) / v * 15.0;
        if (n >= 0 && n <= 7) {
            graph[7 + byte][7 - n] |= bit;
        } else
        if (n >= 8 && n <= 15) {
            graph[byte][15 - n] |= bit;
        }

        bit = bit << 1;
        if (bit & 0x20) {
            bit = 1;
            byte --;
            if (byte < 0) break; 
        }
    }

    // graph to font
    for (i = 0; i < 7; i ++) {
        lcd.cgram(i, graph[i], 8);
        lcd.cgram(7 + i, graph[7 + i], 8);
    }

    // battery to font
    i = (b - 2.8) / 0.1 + 0.05;
    if (i < 0) i = 0;
    if (i > 4) i = 4;
    lcd.cgram(15, gaiji[i], 8);

    lcd.cls();
    // graph, pressure
    lcd.locate(0, 0);
    lcd.printf("\xf0\xf1\xf2\xf3\xf4\xf5\xf6%4.1fhPa", p + 0.05);
    lcd.locate(0, 1);
    lcd.printf("\x07\xf8\xf9\xfa\xfb\xfc\xfd  %2.1fc", t + 0.05);
    // up/down mark
    lcd.raw = 1;
    lcd.locate(7, 1);
    lcd.putc(updown[ud + 1]);
    lcd.raw = 0;
    // battery gauge
    lcd.locate(15, 1);
    lcd.printf("\xff");
}

// up/down
void check () {
    int i;
    float sum;

    sum = 0;
    for (i = 0; i < 34; i ++) {
        if (vals[i + 1] < 800 || vals[i + 1] > 1200) break;
        sum += (vals[i] - vals[i + 1]);
        if (sum > 1) {
            ud = 1; // up
            break;
        } else
        if (sum < -1) {
            ud = -1; // down
            if (i < 10) ud = -2;
            break;
        }
    }
}

void sample () {
    int i;

    // BMP180
    bmp.update();
    p = bmp.get_pressure();
    t = bmp.get_temperature();

    ave += p;
    count ++;
    if (count >= 6) {
        // average 6 min.
        count = 0;
        ave = ave / 6;
        // shift buffer
        for (i = 34; i >= 1; i --) {
            vals[i] = vals[i - 1];
        }
        vals[0] = ave;
        ave = 0;

        // ADC (battery)
        vpwr = 1;
        wait_ms(10);
        b = 2.495 / vsens;
        vpwr = 0;

        check();
        draw();
    } else {
        lcd.locate(7, 0);
        lcd.printf("%4.1fhPa", p + 0.05);
        lcd.locate(9, 1);
        lcd.printf("%2.1fc", t + 0.05);
    }
}

int main() {
    int w;

    myled = 0;
    led_r = led_g = led_b = 1;
    memset(&vals, 0, sizeof(vals));
    i2c.frequency(400000);

    lcd.cls();
    lcd.printf("Barometer");
    led_r = 0;
    wait_ms(300);
    led_r = 1;
    led_g = 0;
    wait_ms(300);
    led_g = 1;
    led_b = 0;
    wait_ms(300);
    led_b = 1;

    sample();
    vpwr = 1;
    wait_ms(10);
    b = 2.495 / vsens; // battery
    vpwr = 0;
    draw();

    for (;;) {
        if (ud > 0) {
            led_r = 0; // up
        } else
        if (ud < 0) {
            led_b = 0; // down
            if (ud < -1) led_g = 0;
        } else {
            led_g = 0;
        }

        w ++;
        if (w >= 20) {
            w = 0;
            sample(); // 1 min.
        } else {
            wait_ms(1);
        }
        led_r = led_g = led_b = 1;
        wdt.attach(NULL, 3); // wdt interrupt
        wdt.deepSleep();
    }
}