thermometer, hygrometer and barometer. Using VFD for display.

Dependencies:   AM2321 LPS331_I2C mbed-rtos mbed EthernetInterface

main.cpp

Committer:
mia_0032
Date:
2014-11-22
Revision:
4:6e0a2e9fe23a
Parent:
2:c036ba032972

File content as of revision 4:6e0a2e9fe23a:

#include "mbed.h"
#include "rtos.h"
#include "EthernetInterface.h"
#include "LPS331_I2C.h"
#include "AM2321.h"
#include <string>

//for debug
DigitalOut led1(LED1, 0);
DigitalOut led2(LED2, 0);
DigitalOut led3(LED3, 0);
DigitalOut led4(LED4, 0);
Serial pc(USBTX, USBRX);

// data
float pressure = 0;
float temperature = 0;
float humidity = 0;

// for ethernet
EthernetInterface eth;
DigitalIn lnk(P1_25);
DigitalIn spd(P1_26);
DigitalOut speed(p29);
DigitalOut link(p30);

void flip(void const *args) {
    speed = !spd;
    link = !lnk;
}

// for fluentd in_http
void send_fluentd(const string host, const int port)
{
    TCPSocketConnection sock;
    sock.connect(host.c_str(), port);

    char post_data[128];
    sprintf(post_data, "json={\"humid\":%d,\"temp\":%d,\"press\":%d}", (int)humidity, (int)temperature, (int)pressure);
    pc.printf("POST Data:\r\n%s\r\n%d", post_data, strlen(post_data));
    char http_cmd[512];
    sprintf(http_cmd, "POST /mbed.climate HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n\r\n", host.c_str(), port, strlen(post_data), post_data);
    pc.printf("Request:\r\n%s\r\n", http_cmd);
    sock.send_all(http_cmd, sizeof(http_cmd)-1);

    char buffer[1024];
    int ret;
    while (true) {
        ret = sock.receive(buffer, sizeof(buffer)-1);
        if (ret <= 0)
            break;
        buffer[ret] = '\0';
        pc.printf("Received %d chars from server:\r\n%s\r\n", ret, buffer);
    }

    sock.close();
}


// for LPS331
LPS331_I2C lps331(p9, p10, LPS331_I2C_SA0_HIGH);

void setup_lps331()
{   
    if(lps331.isAvailable()) {
        pc.printf("LPS331 is available!\r\n");
    } else {
        pc.printf("LPS331 is unavailable!\r\n");
    }
    
    lps331.setResolution(LPS331_I2C_PRESSURE_AVG_512, LPS331_I2C_TEMP_AVG_128);
    lps331.setDataRate(LPS331_I2C_DATARATE_7HZ);
    lps331.setActive(true);
}

void update_pressure()
{
    led2 = !led2;
    pressure = lps331.getPressure();
    pc.printf("press:%f\r\n", pressure);
}

// for AM2321
AM2321 am2321(p9, p10);

void update_temperature_and_humidity()
{
    if(am2321.poll())
    {
        led3 = !led3;
        temperature = am2321.getTemperature();
        humidity = am2321.getHumidity();
        pc.printf("temp:%.1f,humid:%.1f\r\n", temperature, humidity);
    }
}

// for display mode
int mode = 1; // 1: temp, 2: humid, 3: press
void next_mode(void const *args)
{
    mode++;
    if(mode > 3)
    {
        mode = 1;
    }
}

// for VFD
const int ANODE_PINS_NUM = 9;
DigitalOut anode_pins[ANODE_PINS_NUM] = {
    DigitalOut(p28),
    DigitalOut(p27),
    DigitalOut(p26),
    DigitalOut(p25),
    DigitalOut(p24),
    DigitalOut(p23),
    DigitalOut(p22),
    DigitalOut(p16),
    DigitalOut(p21)
};

const int CATHODE_PINS_NUM = 4;
DigitalOut cathode_pins[CATHODE_PINS_NUM] = {
    DigitalOut(p17),
    DigitalOut(p18),
    DigitalOut(p19),
    DigitalOut(p20)
};

const int DOT_PIN_POS = 8;
const int VFD_LIGHT_MAP[][ANODE_PINS_NUM] = {
    {1, 1, 1, 1, 1, 1, 0, 0, 0}, // 0
    {0, 1, 1, 0, 0, 0, 0, 0, 0}, // 1
    {1, 1, 0, 1, 1, 0, 1, 0, 0}, // 2
    {1, 1, 1, 1, 0, 0, 1, 0, 0}, // 3
    {0, 1, 1, 0, 0, 1, 1, 1, 0}, // 4
    {1, 0, 1, 1, 0, 1, 1, 0, 0}, // 5
    {1, 0, 1, 1, 1, 1, 1, 0, 0}, // 6
    {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 7
    {1, 1, 1, 1, 1, 1, 1, 0, 0}, // 8
    {1, 1, 1, 1, 0, 1, 1, 0, 0}, // 9
    {1, 1, 1, 0, 1, 1, 1, 0, 0}, // A
    {0, 0, 1, 1, 1, 1, 1, 0, 0}, // B
    {1, 0, 0, 1, 1, 1, 0, 0, 0}, // C
    {0, 1, 1, 1, 1, 0, 1, 0, 0}, // D
    {1, 0, 0, 1, 1, 1, 1, 0, 0}, // E
    {1, 0, 0, 0, 1, 1, 1, 0, 0}, // F
    {1, 1, 0, 0, 1, 1, 1, 0, 0}, // P
    {0, 0, 1, 0, 1, 1, 1, 0, 0}  // h
};

void vfd_display_number(int pos, int number, int add_dot)
{
    cathode_pins[pos] = 1;
    for(int i = 0; i < DOT_PIN_POS; i++) {
        anode_pins[i] = VFD_LIGHT_MAP[number][i];
    }
    anode_pins[DOT_PIN_POS] = add_dot;
    Thread::wait(2);
    for(int i = 0; i < ANODE_PINS_NUM; i++) {
        anode_pins[i] = 0;
    }
    cathode_pins[pos] = 0;
}

void vfd_display_numbers(void const *args)
{
    int ones_place, tens_place, hundreds_place, thousands_place, use_dot;
    int display_number;
    led1 = !led1;
    
    switch(mode)
    {
        case 1:
            display_number = (int)(temperature * 10);
            ones_place = 12;
            tens_place = display_number % 10;
            thousands_place = (int)(display_number / 100);
            hundreds_place = (int)((display_number - thousands_place * 100 - tens_place) / 10);
            use_dot = 1;
            break;
        case 2:
            display_number = (int)(humidity * 10);
            ones_place = 16;
            tens_place = display_number % 10;
            thousands_place = (int)(display_number / 100);
            hundreds_place = (int)((display_number - thousands_place * 100 - tens_place) / 10);
            use_dot = 1;
            break;
        default:
            display_number = (int)pressure;
            if(display_number < 1000)
            {
                ones_place = 17;
                tens_place = display_number % 10;
                thousands_place = (int)(display_number / 100);
                hundreds_place = (int)((display_number - thousands_place * 100 - tens_place) / 10);
            }
            else
            {
                ones_place = display_number % 10;
                thousands_place = (int)(display_number / 1000);
                hundreds_place = (int)((display_number - thousands_place * 1000) / 100);
                tens_place = (int)((display_number - thousands_place * 1000 - hundreds_place * 100) / 10);
            }
            use_dot = 0;
    }

    vfd_display_number(3, thousands_place, 0);
    vfd_display_number(2, hundreds_place, use_dot);
    vfd_display_number(1, tens_place, 0);
    vfd_display_number(0, ones_place, 0);
}

int main()
{
    // start ethernet
    RtosTimer flipper(flip, osTimerPeriodic, NULL);
    flipper.start(50);
    eth.init();
    eth.connect();

    // start auto mode change
    RtosTimer mode_changer(next_mode, osTimerPeriodic, NULL);
    mode_changer.start(7000);

    // start vfd
    RtosTimer vfd_timer(vfd_display_numbers, osTimerPeriodic, NULL);
    vfd_timer.start(16); //60fps
    
    // start LPS331
    setup_lps331();
    Thread::wait(2000);

    while(1) {
        for(int i=0;i < 30;i++){
            update_pressure();
            update_temperature_and_humidity();
            Thread::wait(1000);
        }
        send_fluentd("192.168.10.100", 8888);
    }
}