シカケコンテスト2015で発表した「水分補給お知らせペットボトルホルダー」
Dependencies: MPR121 NokiaLCD SDFileSystem mbed-rtos mbed wave_player
Revision 0:01f630b61d0f, committed 2015-07-10
- Comitter:
- mia_0032
- Date:
- Fri Jul 10 09:19:15 2015 +0000
- Commit message:
- initial commit
Changed in this revision
diff -r 000000000000 -r 01f630b61d0f MARMEX_OB_oled.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MARMEX_OB_oled.h Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,485 @@ +/** MARMEX_OB OLED screen drawing library + * + * @class MARMEX_OB_oled + * @author tedd + * @version 0.51 + * @date 08-Apr-2011 + * + * Released under the MIT License: http://mbed.org/license/mit + * + * MARMEX_OB_oled OLED screen drawing library for mbed + * This code has been written based on sample code and advises + * from Ochiai-san (Marutsu-Elec). Thank you! + * + * SPI mode: + * 9bit or 8bit SPI mode can be selected by disabling/enabling "#define MARMEX_OB_SPI_8BIT_MODE". + * See source code in this (MARMEX_OB_oled.h) file. + */ + +#ifndef MBED_MARMEX_OB_OLED +#define MBED_MARMEX_OB_OLED + +#include "mbed.h" +#include "NokiaLCD.h" + +/** @def MARMEX_OB_SPI_8BIT_MODE + * + * MARMEX_OB_oled_oled OLED screen SPI access length setting + * Enabling "MARMEX_OB_SPI_8BIT_MODE" makes 9bit SPI access by 8bit * 2 times. + * This may be useful if other 8bit access SPI device on same SPI bus. + * + * If disabled (just coment out the "#define MARMEX_OB_SPI_8BIT_MODE"), SPI access willbe done by 9 bit format. + */ +//#define MARMEX_OB_SPI_8BIT_MODE + +/** MARMEX_OB_oled OLED screen drawing class + * + * This is a driver code for MARMEX_OB_oled board OLED screen. + * This class inherits NokiaLCD class of mbed.org. + * To use this class, import the NokiaLCD class from here.. + * http://mbed.org/users/simon/libraries/NokiaLCD/ + * + * Example: + * @code + * #include "mbed.h" + * #include "MARMEX_OB_oled.h" + * + * // oled1 is for MARMEX_OB_oled board on MAPLE slot 1 + * // oled1 is for MARMEX_OB_oled board on MAPLE slot 2 + * + * MARMEX_OB_oled oled1( p5, p7, p8, p30, p11 ); // mosi, sclk, cs, rst, power_control + * //MARMEX_OB_oled oled2( p5, p7, p26, p21, p17 ); // mosi, sclk, cs, rst, power_control + * + * + * int main() { + * oled1.background( 0x000000 ); + * oled1.cls(); + * + * int colorbar_width = MARMEX_OB_oled::WIDTH / 8; + * + * for ( int i = 0; i < 8; i++ ) + * oled1.fill( colorbar_width * i, 0, colorbar_width, MARMEX_OB_oled::HEIGHT, ((i & 0x4) ? 0xFF0000 : 0x000000) | ((i & 0x2) ? 0x00FF00 : 0x000000) | ((i & 0x1) ? 0x0000FF : 0x000000) ); + * + * oled1.fill( 50, 50, 64, 64, 0xCCCCCC );; + * + * oled1.locate( 0, 3 ); + * oled1.printf( "Hello World!" ); + * oled1.locate( 0, 4 ); + * oled1.printf( "SPI = %s", MERMEX_OB_SPI_MODE_STR ); + * + * for (int i = 0; i < MARMEX_OB_oled::WIDTH; i++ ) { + * oled1.pixel( i, 80 + sin( (float)i / 5.0 ) * 10, 0x000000 ); + * } + * } * @endcode + */ + +class MARMEX_OB_oled : public NokiaLCD { + +public: + + /** General parameters for MARMEX_OB_oled */ + enum { + ROWS = 15, /**< # of rows (lines) for displaying characters */ + COLS = 16, /**< # of columns (width) for displaying characters */ + WIDTH = 128, /**< screen width [pixels] */ + HEIGHT = 128, /**< screen height [pixels] */ + SPI_FREQUENCY = 16000000 /**< SPI (sclk) SPI_FREQUENCY */ + }; + + /** Constants for power() function */ + enum { + OFF = 0, /**< : to turning-OFF */ + ON /**< : to turning-ON */ + }; + + /** Create a MARMEX_OB_oled object connected to specified SPI and DigitalOut pins + * + * @param mosi SPI-MOSI pin (for MAPLE board, use p5) + * @param sclk SPI-SCLK pin (for MAPLE board, use p8) + * @param cs chip select signal (for MAPLE board, use p8(slot1), p26(slot2)) + * @param rst reset signal (for MAPLE board, use p30(slot1), p21(slot2)) + * @param power_pin backlight power control signal (for MAPLE board, use p11(slot1), p17(slot2)) + * + * Example of MARMEX_OB_oled on MAPLE board: + * @code + * #include "mbed.h" + * #include "MARMEX_OB_oled.h" + * + * MARMEX_OB_oled oled_on_maple_slot1( p5, p7, p8, p30, p11 ); // mosi, sclk, cs, rst, power_control + * MARMEX_OB_oled oled_on_maple_slot2( p5, p7, p26, p21, p17 ); // mosi, sclk, cs, rst, power_control + * ... + * .. + * @endcode + */ + + MARMEX_OB_oled( PinName mosi, PinName sclk, PinName cs, PinName rst, PinName power_pin ) : NokiaLCD( mosi, sclk, cs, rst, NokiaLCD::LCD6100 ), _power_pin( power_pin ) { + power( ON ); + reset(); + } + +#if DOXYGEN_ONLY + /** Write a character to the LCD + * + * @param c The character to write to the display + */ + int putc( int c ); + + /** Write a formated string to the LCD + * + * @param format A printf-style format string, followed by the + * variables to use in formating the string. + * + * !!! 16th character in the string will be disappeared + * !!! This problem is due to difference of screen size NokiaLCD library and its internal mechanism... + */ + int printf( const char* format, ... ); + + /** Set the foreground colour + * + * @param c 24-bit colour + */ + void foreground(int c); + + /** Set the background colour + * + * @param c 24-bit colour + */ + void background(int c); + +#endif + + /** reset MARMEX_OB_oled + * + * Executes hardware reset and initialize. + * See MARMEX_OB_oled manual for the initialization sequence and values + * For gamma correction table, using math function to make the code simple + */ + + void reset( void ) { + +#define GAMMA_LUT_SIZE 63 + unsigned char gamma_LUT[ GAMMA_LUT_SIZE ]; + + for ( int i = 0; i < GAMMA_LUT_SIZE; i++ ) + gamma_LUT[ i ] = (unsigned char)(powf( ((float)i / 62.0), (1.0 / 0.58) ) * 178.0 + 2.0); + + // setup the SPI interface and bring display out of reset + _cs = 1; + _rst = 0; +#ifdef MARMEX_OB_SPI_8BIT_MODE + _spi.format( 8 ); +#else + _spi.format( 9 ); +#endif + + _spi.frequency( SPI_FREQUENCY ); + wait_ms( 1 ); + _rst = 1; + wait_ms( 1 ); + + _cs = 0; + + command( SET_DISPLAY_MODE_ALL_OFF ); + command( SET_COMMAND_LOCK ); + data( 0x12 ); + + command( SET_COMMAND_LOCK ); + data( 0xb1 ); + + command( SET_SLEEP_MODE_ON ); + + command( FRONT_CLOCK_DRIVER_OSC_FREQ ); + data( 0xF1 ); + + command( SET_MUX_RATIO ); + data( 0x7F ); + + command( SET_DISPAY_OFFSET ); + data( 0x00 ); + + command( SET_DISPAY_START_LINE ); + data( 0x00 ); + + command( SET_REMAP_COLOR_DEPTH ); + data( 0x74 ); + + command( SET_GPIO ); + data( 0x00); + + command( FUNCTION_SELECTION ); + data( 0x01 ); + + command( SET_SEGMENT_LOW_VOLTAGE ); + data( 0xA0 ); + data( 0xB5 ); + data( 0x55 ); + + command( SET_CONTRAST_CURRENT_FOR_COLOR_ABC ); + data( 0xC8 ); + data( 0x80 ); + data( 0xC8 ); + + command( MASTER_CONTRAST_CURRENT_CONTROL ); + data( 0x0F ); + + command( LOOKUP_TABLE_FOR_GRAYSCALE_PULSE_WIDTH ); + for ( int i = 0; i < GAMMA_LUT_SIZE; i++ ) + data( gamma_LUT[ i ] ); + + command( SET_RESET_PRECHARGE_PERIOD ); + data( 0x32 ); + + command( ENHANCE_DRIVING_SCHEME_CAPABILITY ); + data( 0x04 ); + data( 0x00 ); + data( 0x00 ); + + command( SET_PRECHARGE_VOLTAGE ); + data( 0x17 ); + + command( SET_SECOND_PRECHARGE_VOLTAGE ); + data( 0x01 ); + + command( SET_VCOMH_VOLTAGE ); + data( 0x05 ); + + command( SET_DISPLAY_MODE_RESET ); + +#if 0 + command( SET_COLUMN_ADDRESS ); + data( 0x00 ); + data( 0x7F ); + + command( SET_ROW_ADDRESS ); + data( 0x00 ); + data( 0x7F); + + command( WRITE_RAM_COMMAND ); + for ( int i = 0; i < WIDTH * HEIGHT; i++ ) + data( 0x00 ); +#endif + _cs = 1; + + cls(); + wait_ms( 200 ); + + command( SET_SLEEP_MODE_OFF ); + } + + /** Clear the screen and locate to 0,0 */ + + void cls( void ) { + fill( 0, 0, WIDTH , HEIGHT, _background ); + _row = 0; + _column = 0; + } + + /** Set a pixel on te screen + * + * @param x horizontal position from left + * @param y vertical position from top + * @param colour 24-bit colour in format 0x00RRGGBB + */ + + virtual void pixel( int x, int y, int colour ) { + _cs = 0; + _window( x, y, 1, 1 ); + _putp( colour ); + _cs = 1; + } + + /** Fill an area of the screen + * + * @param x horizontal position from left + * @param y vertical position from top + * @param width width in pixels + * @param height height in pixels + * @param colour 24-bit colour in format 0x00RRGGBB + */ + + void fill( int x, int y, int width, int height, int colour ) { + _cs = 0; + _window( x, y, width, height ); + + for (int i = 0; i < width * height; i++ ) { + _putp( colour ); + } + + _window( 0, 0, WIDTH, HEIGHT ); + _cs = 1; + } + + void blit( int x, int y, int width, int height, const int* colour ) { + _cs = 0; + _window( x, y, width, height ); + + for (int i = 0; i < width * height; i++ ) { + _putp( colour[i] ); + } + _window( 0, 0, WIDTH, HEIGHT ); + _cs = 1; + } + + void bitblit( int x, int y, int width, int height, const char* bitstream ) { + _cs = 0; + _window( x, y, width, height ); + + for (int i = 0; i < height * width; i++ ) { + int byte = i / 8; + int bit = i % 8; + int colour = ((bitstream[ byte ] << bit) & 0x80) ? _foreground : _background; + _putp( colour ); + } + _window( 0, 0, _width, _height ); + _cs = 1; + } + + /** Screen width + * + * @return screen width [pixel] + */ + int width() { + return WIDTH; + } + + /** Screen height + * + * @return screen height [pixel] + */ + int height() { + return HEIGHT; + } + /** Columns + * + * @return screen columns + */ + int columns() { + return COLS; + } + + /** Rows + * + * @return screen rows + */ + int rows() { + return ROWS; + } + + /** Power switch for OLED backlight + * + * @param sw argument can be MARMEX_OB_oled::ON or MARMEX_OB_oled::OFF + */ + + void power( unsigned char sw ) { + _power_pin = sw; + } + +private: + /** Command list for the OLED controller */ + enum { + SET_DISPLAY_MODE_ALL_OFF = 0xA4, + SET_COMMAND_LOCK = 0xFD, + SET_SLEEP_MODE_ON = 0xAE, + FRONT_CLOCK_DRIVER_OSC_FREQ = 0xB3, + SET_MUX_RATIO = 0xCA, + SET_DISPAY_OFFSET = 0xA2, + SET_DISPAY_START_LINE = 0xA1, + SET_REMAP_COLOR_DEPTH = 0xA0, + SET_GPIO = 0xB5, + FUNCTION_SELECTION = 0xAB, + SET_SEGMENT_LOW_VOLTAGE = 0xB4, + SET_CONTRAST_CURRENT_FOR_COLOR_ABC = 0xC1, + MASTER_CONTRAST_CURRENT_CONTROL = 0xC7, + LOOKUP_TABLE_FOR_GRAYSCALE_PULSE_WIDTH = 0xB8, + SET_RESET_PRECHARGE_PERIOD = 0xB1, + ENHANCE_DRIVING_SCHEME_CAPABILITY = 0xB2, + SET_PRECHARGE_VOLTAGE = 0xBB, + SET_SECOND_PRECHARGE_VOLTAGE = 0xB6, + SET_VCOMH_VOLTAGE = 0xBE, + SET_DISPLAY_MODE_RESET = 0xA6, + SET_COLUMN_ADDRESS = 0x15, + SET_ROW_ADDRESS = 0x75, + WRITE_RAM_COMMAND = 0x5C, + SET_SLEEP_MODE_OFF = 0xAF + }; + +#ifdef MARMEX_OB_SPI_8BIT_MODE + void command( int value ) { + int tmp = value & 0x00ff; + _cs = 0; + _spi.write( tmp >> 1 ); + _spi.write( tmp << 7 ); + _cs = 1; + } + + void data( int value ) { + int tmp = value & 0x00ff; + tmp |= 0x0100; + _cs = 0; + _spi.write( tmp >> 1 ); + _spi.write( tmp << 7 ); + _cs = 1; + } +#else + void command( int value ) { + _cs = 0; + _spi.write( value & 0xFF ); + _cs = 1; + } + + void data(int value) { + _cs = 0; + _spi.write( value | 0x100 ); + _cs = 1; + } +#endif + + virtual void _window( int x, int y, int width, int height ) { + int x1 = x + 0; + int y1 = y + 0; + int x2 = x1 + width - 1; + int y2 = y1 + height - 1; + + command( SET_COLUMN_ADDRESS ); + data( x1 ); + data( x2 ); + command( SET_ROW_ADDRESS ); + data( y1 ); + data( y2 ); + command( WRITE_RAM_COMMAND ); + } + + void window( int x, int y, int width, int height ) { + _cs = 0; + _window( x, y, width, height ); + _cs = 1; + } + + virtual void _putp( int colour ) { + int cnv = 0; + + cnv = (colour >> 8) & 0xf800; + cnv |= (colour >> 5) & 0x07e0; + cnv |= (colour >> 3) & 0x001f; + + data( cnv >> 8); + data( cnv ); + } + + DigitalOut _power_pin; +} +; + +#ifdef MARMEX_OB_SPI_8BIT_MODE +#define MERMEX_OB_SPI_MODE_STR "8bit mode" +#else +#define MERMEX_OB_SPI_MODE_STR "9bit mode" +#endif +#endif // MBED_MARMEX_OB_OLED + +/* + * history: + * 0.5 (2011-Apr-07) : initial published version + * 0.51 (2011-Apr-08) : a. "virtual" had been added on "_putp()" function definition to surpress warning when compiling (is this correct way?) + * b. sample code (for Doxygen) is changed from new "main.cpp (ver 0.51)" + */
diff -r 000000000000 -r 01f630b61d0f MPR121.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MPR121.lib Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/sam_grove/code/MPR121/#eb4012317732
diff -r 000000000000 -r 01f630b61d0f NokiaLCD.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NokiaLCD.lib Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/NokiaLCD/#2d1b23692cbb
diff -r 000000000000 -r 01f630b61d0f SDFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
diff -r 000000000000 -r 01f630b61d0f main.cpp --- /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); + } +}
diff -r 000000000000 -r 01f630b61d0f mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#ef0a22cdf839
diff -r 000000000000 -r 01f630b61d0f mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7 \ No newline at end of file
diff -r 000000000000 -r 01f630b61d0f wave_player.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wave_player.lib Fri Jul 10 09:19:15 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/sravet/code/wave_player/#acc3e18e77ad