キッチンタイマーのプログラムです

Dependencies:   mbed SevenSegLed Sound_pwmToDig SwAnalog

回路やプログラムについての詳しい説明は、下記のblogにまとめました。 http://suupen-make.blogspot.jp/2013/11/lpc1114fn28mbedkitchen-timer.html

main.cpp

Committer:
suupen
Date:
2013-11-25
Revision:
2:269bb751dd19
Parent:
1:f638c70e028c

File content as of revision 2:269bb751dd19:

//#define debug
//===========================================================================
// LPC1114FN28(mbed) kitchen timer 
//
// kitchen timer
//
// <schematic>
// 1.seven segment numeric LED Display : OSL40562-IRA
//       http://akizukidenshi.com/download/OSL40562-IRA.pdf
//
//  OSL40562-IRA                          Resister        LPC1114FN28
//  Pin No     Function                   [ohm]           PinNo
//  ---------------------------------------------------------------------------
//   1         segment E                   680            dp28 
//   2         segment D                   680            dp27
//   3         segment Dp                  680            dp26
//   4         segment C                   680            dp25
//   5         segment G                   680            dp18
//   6         common  4                   -              dp17  
//   7         segment B                   680            dp11
//   8         common  3                   -              dp13 
//   9         common  2                   -              dp14
//  10         segment F                   680            dp5
//  11         segment A                   680            dp6 
//  12         common  1                    -             dp4
// 
// 2.sound speaker
//                                               /
//   mbed                 --------------      --/
//   dp1(pwmOut)     -----| R:100[ohm] |-----|  |  speaker(8[ohm])
//                        --------------     |  |
//                                           |  |
//   dp2(pwmOut)     ------------------------|  |
//      (digitalOut)                          --\
//                                               \
// 3.sw
//   -.- Vcc(+3.3[V])
//    |                                               |--------------------> dp9(ADinput)
//    |   ---------       ---------       ---------   |   ---------
//    .---| Rsw2  |---.---| Rsw1  |---.---| Rsw0  |---.---| Rout  |----|
//    |   ---------   |   ---------   |   ---------   |   ---------    |
//    |     ----      |     -----     |     -----     |                |
//    |-----o  o------.-----o  o------.-----o  o------|              -----
//           LeftSW         DowmSW           UpSW                  GND(0[V])
// 
//  Rsw2 : 8.2[kohm], Rsw1 = 3.9[kohm], Rsw0 = 2.0[kohm], Rout = 1.0[kohm] (R no seido ha +-1[%])
//
//   -.- Vcc(+3.3[V])
//    |                                               |--------------------> dp10(ADinput)
//    |   ---------       ---------       ---------   |   ---------
//    .---| Rsw2  |---.---| Rsw1  |---.---| Rsw0  |---.---| Rout  |----|
//    |   ---------   |   ---------   |   ---------   |   ---------    |
//    |     ----      |     -----     |     -----     |                |
//    |-----o  o------.-----o  o------.-----o  o------|              -----
//          RightSW          BSW           ASW                      GND(0[V])
// 
//  Rsw2 : 8.2[kohm], Rsw1 = 3.9[kohm], Rsw0 = 2.0[kohm], Rout = 1.0[kohm] (R no seido ha +-1[%])
//
// V1.0 131106
// 
//
//===========================================================================
#include "mbed.h"

//#define DBG

#ifdef DBG
Serial pc(dp16, dp15);
#endif //DBG


#include "SevenSegLed.h"
#include "Sound.h"
#include "SwAnalog.h"




Ticker timeout100ms;     // 100ms interrupt

Sound sound(dp1, dp2);    // pwm, pwm(digitalOut)


SwAnalog sw(dp9, dp10);
enum{
    upSw,
    downSw,
    leftSw,
    aSw,
    bSw,
    rightSw
};

SevenSegLed sevenSegLed(0, 1, dp6, dp11, dp25, dp27, dp28, dp5, dp18, dp26, dp4, dp14, dp13, dp17);   // OSL40562-IRA


uint8_t D_7seg[4] = {0, 0, 0, 0};
uint8_t D_dot[4] = {0, 1, 0, 0};

uint8_t C_flicker; // timer setti ji no henko keta flicker kyoka (100[ms]/count) 0:flicker request ohter:kinsi
#define Z_flicker (5 * 10)

int16_t D_timerSec = 3 * 60; // timer no settai chi (1/1 [s]/count)
int16_t C_timerSec; // timer keiji jikan (1/1[s]/count)

enum timer_t{
    stop,
    set1min,
    set10min,
    count,
    chime,
    timeup
};
timer_t M_timer = stop;

uint8_t F_flip100ms;    // 100ms keika goto ni 0 or 1 
uint8_t F_flip500ms;    // 500ms keika goto ni 0 or 1


// "beep" merody data
    const Sound::sound_t BEEP[] = {
    {1,0x95,200,100},
    {1,0xFF,10,0}    // end
    };

void beep(void){
// tone1 
//    Sound::sound_t oto = {1,0x95,200,100};
//    sound.sound_sound(oto);
  
 
    sound.sound_enso((Sound::sound_t*)BEEP);
    sound.sound_enso(true);
}


// "westminster chime" merody data
    const Sound::sound_t WESTMINSTER[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xA4,1200,1000},
        {1,0xF4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xC4,2400,1000},

        {1,0xC4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xA4,1200,1000},
        {1,0xF4,2400,1000},
 
        {1,0xA4,1200,1000},
        {1,0xF4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xC4,2400,1000},

        {1,0xC4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xA4,1200,1000},
        {1,0xF4,2400,1000},
               
        {1,0xFF,1000,0},    // end
    };
// "ramen chime" merody data
    const Sound::sound_t RAMEN[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xC5,300,500},
        {1,0xD5,300,500},
        {1,0xE5,1200,500},
        {1,0xD5,600,500},
        {1,0xC5,1200,500},

        {1,0xC5,300,500},
        {1,0xD5,300,500},
        {1,0xE5,300,500},
        {1,0xD5,300,500},
        {1,0xC5,300,500},
        {1,0xD5,1800,500},

        
        {1,0xFF,1000,500},    // end
    };

// "demekin no uta" merody data
    const Sound::sound_t DEMEKIN[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x95,600,500},     // no
        {1,0x95,150,500},     // shi
        {1,0x00,900,500},
        {1,0xE5,750,500},     // po
        {1,0x00,450,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0x95,600,500},     // ju
        {1,0xE5,600,500},     // go
        {1,0xD5,600,500},     // n
        {1,0xC5,600,500},     // no
        {1,0xE5,150,500},     // shi
        {1,0x00,900,500},
        {1,0xC5,750,500},     // po
        {1,0x00,1350,500},

        {1,0xFF,1000,0},    // end (1s keika go sai enso)
//                                {1,0xFF,0},        // end    (1kaino enso de teisi suru baai)
};

//=============================
// timer SW seni
//=============================
void timerSeni(void){

    // bSw(stop SW)
    if(sw.checkEdgeOn(bSw) == 1){
        beep();
        M_timer = stop;
    }
    
    // aSw(start SW)
    if((sw.checkEdgeOn(aSw) == 1)
     &&(M_timer != count)
    ){
        beep();
        M_timer = count;
        C_timerSec = D_timerSec;
    }    

    switch(M_timer){
    case stop:
        // other aSw,bSw then set1min
        if((sw.checkEdgeOn(upSw) == 1)
         ||(sw.checkEdgeOn(downSw) == 1)
         ||(sw.checkEdgeOn(leftSw) == 1)
         ||(sw.checkEdgeOn(rightSw) == 1)
         ){
            beep();
            M_timer = set1min;
            C_flicker = 0;
        }
        break;
    case set1min:
        if(sw.checkEdgeOn(leftSw) == 1){
            beep();
            M_timer = set10min;
            C_flicker = 0;
        }
        break;
    case set10min:
        if(sw.checkEdgeOn(rightSw) == 1){
            beep();
            M_timer = set1min;
            C_flicker = 0;
        }
        break;
    case count:
      if(C_timerSec == 0){
            M_timer = chime;
      }
      break;
    
    case chime: // 120115 bug fix
        if(D_timerSec == (3 * 60)){
            sound.sound_enso((Sound::sound_t*)RAMEN);
        }
        else if(D_timerSec < (60 * 60)){
            sound.sound_enso((Sound::sound_t*)WESTMINSTER);
        }
        else{
            sound.sound_enso((Sound::sound_t*)DEMEKIN);
        }
            
        sound.sound_enso(true);
        M_timer = timeup;
        
        break;
    
    case timeup:
        // other aSw,bSw then set1min
        if((sw.checkEdgeOn(upSw) == 1)
         ||(sw.checkEdgeOn(downSw) == 1)
         ||(sw.checkEdgeOn(leftSw) == 1)
         ||(sw.checkEdgeOn(rightSw) == 1)
         ){
            beep();
            M_timer = set1min;
            C_flicker = 0;
        }    
        break;
    default:
        break;
    }

}


//============================
// timer set
//============================
void timerSet(void){
    int16_t work;

    switch(M_timer){
    case stop:
        break;
    case set1min:
        if(sw.checkEdgeOn(upSw) == 1){
            work = D_timerSec / 60;
            if(work < 99){
                beep();
                D_timerSec += 60;
                C_flicker = Z_flicker;
            }
        }
        
        if(sw.checkEdgeOn(downSw) == 1){
            work = D_timerSec / 60;
            if (work > 0){
                beep();
                D_timerSec -= 60;
                C_flicker = Z_flicker;
            }
        }
        break;
    case set10min:
        if(sw.checkEdgeOn(upSw) == 1){
            if(D_timerSec <= (98 * 60)){
                beep();
                D_timerSec += 600;
                C_flicker = Z_flicker;
            }
        }
        
        if(sw.checkEdgeOn(downSw) == 1){
            if(D_timerSec >= 600){
                beep();
                D_timerSec -= 600;
                C_flicker = Z_flicker;
            }    
        }
        break;
    case count:
        break;
    case chime:
        break;
    case timeup:
        break;
    default:
        break;
    }
    
    if(D_timerSec > (99 * 60)){D_timerSec = 99 * 60;}
}

//==========================
// seven segment display
//==========================
void sevenSegDisplay(void){
    int16_t work;


    
    switch(M_timer){
    case stop:
        work = D_timerSec / 600;
        if(work == 0){D_7seg[0] = 0x10;}
        else{D_7seg[0] = work;}
        
        work = D_timerSec / 60;
        work %= 10;
        D_7seg[1] = work;

        D_7seg[2] = 0x10;
        D_7seg[3] = 0x10;
 
        
        D_dot[0] = 0;
        D_dot[1] = 1;
        D_dot[2] = 0;
        D_dot[3] = 0;
        
        break;
    case set1min:
    case set10min:
        work = D_timerSec / 600;
        if(work == 0){
            if(M_timer == set10min){
                D_7seg[0] = work;
            }
            else{
                D_7seg[0] = 0x10;
            }
        }
        else{
            D_7seg[0] = work;
        }
        
        work = D_timerSec / 60;
        work %= 10;
        D_7seg[1] = work;
        
        if((C_flicker == 0) && (F_flip500ms == 0)){
            if(M_timer == set1min){
                D_7seg[1] = 0x10;
            }
            else{
                D_7seg[0] = 0x10;
            }
        }
        
        D_7seg[2] = 0x10;
        D_7seg[3] = 0x10;

        D_dot[0] = 0;
        D_dot[1] = 1;         
        D_dot[2] = 0;
        D_dot[3] = 0;

        break;
    case count:
        work = C_timerSec / 600;
        if(work == 0){D_7seg[0] = 0x10;}
        else{D_7seg[0] = work;}
        
        work = C_timerSec / 60;
        work %= 10;
        D_7seg[1] = work;
        
        work = C_timerSec % 60;
        work /= 10;
        D_7seg[2] = work;

        work = C_timerSec % 60;
        work %= 10;
        D_7seg[3] = work;

        D_dot[0] = 0;
        D_dot[1] = 1;
        D_dot[2] = 0;
        D_dot[3] = 0;

        break;
    case chime: // same "timeup"

#ifdef debug
    D_7seg[0] = 0x0E;
    D_7seg[1] = 0x10;
    D_7seg[2] = 0x10;
    D_7seg[3] = 0x10;
    break;
#endif //debug

    case timeup:
        if(F_flip500ms == 1){
            D_7seg[0] = 0x0f;
            D_7seg[1] = 0x0f;
            D_7seg[2] = 0x0f;
            D_7seg[3] = 0x0f;
        }
        else{
            D_7seg[0] = 0x10;
            D_7seg[1] = 0x10;
            D_7seg[2] = 0x10;
            D_7seg[3] = 0x10;
        }
        
        D_dot[0] = 0;
        D_dot[1] = 0;
        D_dot[2] = 0;
        D_dot[3] = 0;
        break;
    default:
        break;
    }
    sevenSegLed.SevenSegLed_main(D_7seg, D_dot);
}

//================================
// 100ms interrupt
//================================
void interrupt100ms(void){
//    led2 = !led2;
    static uint8_t C_100ms = 0;
    
    C_100ms++;
    if(C_100ms > 9){C_100ms = 0;}
    
    // flip flag 
    F_flip100ms = !F_flip100ms;

    if(C_100ms < 5){F_flip500ms = 1;}
    else{F_flip500ms = 0;}

    // settei keta flicker
    if(C_flicker > 0){C_flicker--;}

    // timer counter decrement
    if((C_100ms == 0) && (C_timerSec > 0)){C_timerSec--;}        

}


//================================
// main
//================================
int main() {
    timeout100ms.attach(&interrupt100ms, 0.1);  // 10ms interrupt

    while(1) {
    

        // sw level and edge data refresh

        sw.refreshEdgeData();


        timerSeni();
        timerSet();

        sevenSegDisplay();
 
        // debug code
#if 0
            pc.printf("%01d %01d %01d    %01d %01d %01d\r\n",
            sw.checkLevel(0),
            sw.checkLevel(1),
            sw.checkLevel(2),
            sw.checkLevel(3),
            sw.checkLevel(4),
            sw.checkLevel(5)
           
            );
#endif      
 
    }
}