Kansai Electric Power usage meter (Denki-yohou) for GainSpan Wi-Fi http://mbed.org/users/okini3939/notebook/denki-yohou/

Dependencies:   mbed GSwifi (old)

main.cpp

Committer:
okini3939
Date:
2012-10-17
Revision:
2:8646918ffff2
Parent:
1:beff52210994
Child:
3:4bf32f60a770

File content as of revision 2:8646918ffff2:

#include "mbed.h"
#include "GSwifi.h"
#include "7seg.h"
#include "WDT.h"

#define HTTP_HOST "www.jma.go.jp"
#define HTTP_URI "/en/yoho/331.html"
#define NTP_HOST "ntp1.sakura.ad.jp"

#define SECURE GSSEC_WPA2_PSK
#define SSID "SSID"
#define PASS "password"

#define VREF 3.3
#define B 3435 // thermistor B
#define T0 25.0
#define R0 10000.0 // R0 ohm
#define RU 10000.0 // pullup ohm

#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
Serial pc(USBTX, USBRX);
GSwifi gs(p13, p14, p12, P0_22); // TX, RX, CTS, RTS
DigitalOut gs_reset(p9), gs_wakeup(p10);
DigitalOut led1(LED1);
PwmOut led2(LED2), led3(LED3), led4(LED4);
DigitalOut bz(p13);
#elif defined(TARGET_LPC11U24)
GSwifi gs(p9, p10, p21, p22); // TX, RX, CTS, RTS
DigitalOut gs_reset(P1_14), gs_wakeup(P1_3);
//DigitalOut gs_reset(p15), gs_wakeup(p14);
DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
DigitalOut bz(p13);
#endif

volatile int weather_count = 0, weather_data = 0, weather_flg = 0;
volatile int year, month, day, hour, minute;
volatile int remote_flg = 0;

AnalogIn adtemp(p20);
Watchdog wdt;

extern "C" void HardFault_Handler() {
    register unsigned int _msp __asm("msp");
    printf("Hard Fault! address: %08x\n", *((unsigned int *)(_msp + 24)));
    while(1); 
}  

int weather_info (char *buf) {
    int i, w = 0;
    char *tmp = NULL;

    for (i = 0; i < strlen(buf); i ++) {
        if (buf[i] == ',') {
            buf[i] = 0;
            tmp = &buf[i + 1];
        } else
        if (buf[i] == '<') {
            buf[i] = 0;
            break;
        }
    }

    if (tmp) {
    } else
    if (strstr(buf, "PARTLY CLOUDY")) {
        return 0x73; // WY
    } else
    if (strstr(buf, "MOSTLY CLOUDY")) {
        return 0x37; // YW
    }

    if (strstr(buf, "CLEAR")) {
        w = 0x70; // W
    } else
    if (strstr(buf, "CLOUDY")) {
        w = 0x30; // Y
    } else
    if (strstr(buf, "RAIN") || strstr(buf, "SHOWERS")) {
        w = 0x40; // B
    } else
    if (strstr(buf, "SNOW")) {
        w = 0x60; // P
    }

    if (tmp) {
        if (strstr(tmp, "CLEAR") || strstr(tmp, "PARTLY CLOUDY")) {
            w |= 0x07; // W
        } else
        if (strstr(tmp, "CLOUDY")) {
            w |= 0x03; // Y
        } else
        if (strstr(tmp, "RAIN") || strstr(tmp, "SHOWERS")) {
            w |= 0x04; // B
        } else
        if (strstr(tmp, "SNOW")) {
            w |= 0x06; // P
        }
    } else {
        w |= (w >> 4);
    }

    return w;
}

void callback_http (int cid, int len) {
    static int n = 0;
    static char buf[20], data[100];
    int i;
    int last = len;

    while (last) {
      len = gs.recv(cid, buf, last < sizeof(buf) ? last : sizeof(buf));
      if (len == 0) break;
      last = last - len;

      for (i = 0; i < len; i ++) {
        if (buf[i] == '\r') continue;

        // body        
        if (buf[i] == '\n') {
            // end of line
            data[n] = 0;
            if (strstr(data, "class=\"info")) {
                n = weather_info(&data[17]);
                weather_flg ++;
                if (n && weather_flg == 2) {
                    weather_data = n;
                }
            }
            n = 0;
        } else {
            // data
            if (n < sizeof(data) - 1) {
                data[n] = buf[i];
                n ++;
            }
        }

      }

    }
}

float get_temp () {
    float v, r, t;

    v = adtemp * VREF;
    r = v / ((VREF - v) / RU);
    t = (1.0 / ((1.0 / (T0 + 273.15)) + (log(r / R0) / B))) - 273.15;
    if (t < -50) t = 0;
    return t;
}

void Sleep () {
    __WFI();
}

int main() {
    int flg = 0, r;
    Host host, ntp;
    int count = 0;
    time_t time;
    struct tm *t;

    initled();
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
    pc.baud(115200);
#endif
    bz = 1;
    gs_reset = 0;
    gs_wakeup = 1;
    wait_ms(100);
    gs_reset = 1;
    wait_ms(500);
    led1 = 1;

    startled();
    writeled5(0, 18, 1); // i
    writeled5(1, 23, 1); // n
    writeled5(2, 18, 1); // i
    writeled5(3, 29, 1); // t

    if (gs.connect(SECURE, SSID, PASS, 1)) {
        writeled5(0, 14, 1); // e
        writeled5(1, 27, 1); // r
        writeled5(2, 27, 1); // r
        writeled5(3, 0, 0); //
        writeled5(4, 2, 0); // R
        writeled5(5, 2, 0); // R
        for (;;) Sleep();
    }

    wdt.init(8);

    host.setName(HTTP_HOST);
    ntp.setName(NTP_HOST);

    gs.ntpdate(ntp, 0);
    wait(10);
    gs.ntpdate(ntp, 3 * 60 * 60);

#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
    pc.printf("Denki-yohou: %s\r\n", HTTP_HOST);
#endif

    while(1) {
        gs.poll();
        wdt.kick();
        
        if (flg == 0) {
          if (gs.isConnected()) {
            flg = 180;
            led2 = 1;
            
            // Weather
            if (weather_count == 0) {
                weather_flg = 0;
                r = gs.httpGet(host, HTTP_URI, 0, &callback_http);
                if (r >= 0) {
                    led3 = 0;
                } else {
                    led3 = 1;
                }
                gs.poll();
                weather_count = 20;
            } else {
                weather_count --;
            }

            wdt.kick();
            wait(3);
            gs.poll();
            wdt.kick();
            
            // NTP date
            r = gs.getTime();
            if (r) {
                time = r + (9 * 3600); // JST
            }

            led2 = 0;
            wdt.kick();
          } else {
            // re-connected
            led2 = 1;
            if (gs.connect(SECURE, SSID, PASS, 1)) {
              led4 = 1;
            } else {
              led4 = 0;
            }
            led2 = 0;
          }
        }

        if (count == 0) { // 0sec
            // time
            t = localtime(&time);
            writeled(t->tm_hour * 100 + t->tm_min, 2, 0x0f, 0x0f);
            writeled5(4, weather_data & 0x07, 0);
            writeled5(5, (weather_data >> 4) & 0x07, 0);
            remote_flg = 0;
        } else
        if (count > 0 /* && count < 6000 */ && !remote_flg) {
            // time blink
            if (count % 400 == 0) { // 0sec
                writeled(t->tm_hour * 100 + t->tm_min, 2, 0x0f, 0x0f);
            } else
            if (count % 400 == 200) { // 0.1sec
                writeled(t->tm_hour * 100 + t->tm_min, 0, 0x0f, 0x0f);
            }
/*
        } else
        if (count == 6000) { // 15sec
            // temp.
            writeled(get_temp() * 100, 2, 0x0e, 0);
            writeled5(3, 12, 1);
*/
        }

        if (count % 400 == 0) { // every 0sec
            led1 = 1;

            // oclock buzzer
            t = localtime(&time);
            if (t->tm_min == 0) {
                if (t->tm_sec == 0) {
                    bz = 0;
                } else
                if (t->tm_sec == 1) {
                    bz = 1;
                }
            }
        } else
        if (count % 400 == 10) { // every 0.1sec
            led1 = 0;

            time ++;
            if (flg) flg --;
        }

        count ++;
        if (count >= 8000) count = 0; // 20sec

        Sleep();
    }
}