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

Dependencies:   MPR121 NokiaLCD SDFileSystem mbed-rtos mbed wave_player

Revision:
0:01f630b61d0f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jul 10 09:19:15 2015 +0000
@@ -0,0 +1,180 @@
+#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);
+    }
+}