シカケコンテスト2015で発表した「水分補給お知らせペットボトルホルダー」

Dependencies:   MPR121 NokiaLCD SDFileSystem mbed-rtos mbed wave_player

main.cpp

Committer:
mia_0032
Date:
2015-07-10
Revision:
0:01f630b61d0f

File content as of revision 0:01f630b61d0f:

#include "mbed.h"
#include "rtos.h"
#include "SDFileSystem.h"
#include "MPR121.h"
#include "wave_player.h"
#include "MARMEX_OB_oled.h"
#include <string>

// for debug
DigitalOut  mbed_leds[]  = {
    DigitalOut(LED1),
    DigitalOut(LED2),
    DigitalOut(LED3),
    DigitalOut(LED4)
};
Serial pc(USBTX, USBRX);

// sensors
AnalogIn accelerometer[] = {
    AnalogIn(p17),
    AnalogIn(p16),
    AnalogIn(p15)
};
float x_value, y_value, z_value;

InterruptIn irq(p26);
I2C i2c(p9, p10);
MPR121 touch_pad(i2c, irq, MPR121::ADDR_VSS);

// sd card
SDFileSystem sd(p5, p6, p7, p8, "sd");

// LED
DigitalOut  leds[6]  = {
    DigitalOut(p22),
    DigitalOut(p23),
    DigitalOut(p24),
    DigitalOut(p25),
    DigitalOut(p27),
    DigitalOut(p28)
};
int counter_num = 6;

// speaker
AnalogOut aout(p18);
wave_player waver(&aout);

void play_sound(string file_path) {
    pc.printf("Play : %s\r\n", file_path.c_str());
    FILE *wave_file = fopen(file_path.c_str(), "r");
    if(wave_file == NULL) {
        pc.printf("Could not open wave file.\r\n");
    }
    waver.play(wave_file);
    fclose(wave_file);
}

// oled
MARMEX_OB_oled oled_s(p11, p13, p30, p14, p29); // mosi, sclk, cs, rst, power_control
uint8_t c[3];
string current_image;

void display_bmp(string file_path) {
    if(current_image == file_path) {
        pc.printf("Specify same bmp file.\r\n");
        return;
    }
    pc.printf("Display : %s\r\n", file_path.c_str());
    current_image = file_path;
    FILE *f = fopen(file_path.c_str(), "rb");
    if(f == NULL) {
        pc.printf("Could not open bmp file.\r\n");
    }
    fseek(f, 54, 1);
    int color;
    for(int y=127; y >= 0; y--){
        for(int x=127; x >= 0; x--){
            for(int i=0;i < 3;i++){
                c[i] = fgetc(f);
            }
            color = c[0] | (c[1] << 8) | (c[2] << 16);
            oled_s.pixel(x, y, color);
        }
    }
    fclose(f);
}

// switch
DigitalIn sw(p21);

void update_acceleration() {
    mbed_leds[1] = !mbed_leds[1];
    float x, y, z;
    x = y = z = 0.0;
    for (int i=0 ; i < 100 ; i++) {
          x = x + accelerometer[0].read();
          y = y + accelerometer[1].read();
          z = z + accelerometer[2].read();
    }
    x_value = x / 100;
    y_value = y / 100;
    z_value = z / 100;
}

bool is_drinking() {
    if(z_value > 0.35){
        if(touch_pad.isPressed()) {
            uint16_t button_val = touch_pad.buttonPressed();
            pc.printf("button = 0x%04x\r\n", button_val);
            if(button_val > 0){
                mbed_leds[0] = 1;
                pc.printf("Drinking...\r\n");
                return true;
            }
        }
    }
    mbed_leds[0] = 0;
    return false;
}

void update_leds() {
    for(int i=0; i < 6; i++){
        leds[i] = (i < counter_num) ? 1 : 0;
    }
}

void decreament_counter(void const *args) {
    mbed_leds[2] = !mbed_leds[2];
    counter_num--;
    if(counter_num < 0) {
        counter_num = 0;
    }
    update_leds();
}

void reset_counter() {
    if(counter_num != 6) {
        pc.printf("Reset...\r\n");
        display_bmp("/sd/default.bmp");
        counter_num = 6;
        update_leds();
    }
}

void notify_drinking() {
    pc.printf("Notify...\r\n");
    display_bmp("/sd/sad.bmp");
    play_sound("/sd/elephant.wav");
}

int main() {
    sw.mode(PullUp);

    oled_s.background( 0xFFFFFF );
    oled_s.cls();
    display_bmp("/sd/default.bmp");
    
    touch_pad.init();
    touch_pad.enable();
    
    RtosTimer counter_timer(decreament_counter, osTimerPeriodic, NULL);
    counter_timer.start(60000 * 5); // 5min * 6LEDs = 30min
    update_leds();

    while(1) {
        update_acceleration();
        pc.printf("X:%f Y:%f Z:%f\r\n", x_value, y_value, z_value);
        if(is_drinking()) {
            reset_counter();
            play_sound("/sd/drinking.wav");
        }
        if(sw == 0) { // for demo
            decreament_counter(NULL);
        }
        if(counter_num <= 0) {
            notify_drinking();
        }
        Thread::wait(500);
    }
}