This program is a clock that uses a kitchen Timer boad.

Dependencies:   SevenSegLed Sound_pwmToDig SwAnalog mbed

Fork of kitchenTimer_Clock by suu pen

LPC1114FN28(mbed)を使ったデジタル時計

<概要>

以前作成したLPC1114FN28(mbed)で作ったキッチンタイマーのプログラムを変更して、デジタル時計をつくりました。

回路はキッチンタイマーのものをそのまま使っています。基板作成や、プログラムの書き込み方法については、次のblogを参照してください。

回路図、PCB、WINSTAR PCB for iModela、などのデータはこちらからダウンロードできます。

<時計動作の説明>

基板の電源を入れると、表示が“FFFF”になり、メロディーが流れます。

スイッチは、 右上(赤)SW :時計時刻設定の開始・完了 右下(青)SW :時計時刻設定のキャンセル 左(黒)十字SW:時計時刻変更用 となっています。

/media/uploads/suupen/----p1170422.jpg デジタル時計のLED,SWの説明

時刻あわせをする場合は、赤色SWを押して時刻設定モードにしてから、十字SWで時刻を変更し、再度赤色SWを押すと時刻確定して、時計動作を始めます。

時計設定をやめたいときは、青色SWを押します。

時計計時は、4桁の7セグメントLEDで、時・分表示をします。秒は、一番右側のドットLEDの点滅で表示しています。

ドットや、数字の変化は、滑らかに変化させています。

毎正時(59から00分に変化)した時に、メロディーを流します。

<プログラムについて>

プログラムは、こちらからからダウンロードできます。

main.cpp

Committer:
suupen
Date:
2013-12-01
Revision:
2:04062925e025
Parent:
1:fe97b047f96b

File content as of revision 2:04062925e025:

//===========================================================================
// digital clock
//
// <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 131130
// 
//
//===========================================================================
#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




// 7segment LED initial display data.
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)

// control mode number.
enum timer_t{
    stop,
    setMin,
    setHore,
    count,
 };
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

time_t seconds;
typedef struct{
    uint8_t tm_hour;
    uint8_t tm_min;
    uint8_t tm_sec;
    } sstm;

sstm rtc_time;    // LPC11U24 yo rtc
sstm A_time;   // genzai jikoku
#define Z_japanOffset   (9 * 60 * 60)   // japan time offset (utc + 9h)

//time_t seconds;
//struct tm  *A_time;   // genzai jikoku

//===================================
// beep (sw sosa ji no oto)
//===================================
// "beep" merody data
    const Sound::sound_t BEEP[] = {
    {1,0x95,200,100},
    {1,0xFF,10,0}    // end
    };

void beep(void){
    sound.sound_enso((Sound::sound_t*)BEEP);
    sound.sound_enso(true);
}


//**********************************************************
// chime
//**********************************************************
uint8_t C_chime;    // chime kaisuu 1 - 255 (1/1[kai]/count)

//=====================================================
// chime request
//      no : chime no kaisuu 1 - 255 ( 1/1 [kai]/count)
//=====================================================
void chimeSet(uint8_t no){
    C_chime = no;
}

//====================================
// chime check and output
//    10 - 100 ms syuuki de call suru
//====================================
void chimeCheck(void){
    if(C_chime > 0){
        if((sound.sound_sound() == false) && (sound.sound_enso() == false)) {
            Sound::sound_t oto = {1,0xF4,2500,1500};
            sound.sound_sound(oto);
            C_chime--;
        }
    }
}

//***************************************************
// melody data tabel
//***************************************************

//================================
// "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)
};

//=============================
// rtc count
// 1sec syuki no syori
//=============================
void rtc_count(void){
    seconds++;
    if(seconds >= (23 *3600 + 59 * 60 + 60)){
        seconds = 0;
    }
}

//=============================
// localtime
//=============================
sstm ss_localtime( time_t  * t ){ 
    sstm ans;
    ans.tm_hour = *t / 3600;
    ans.tm_min = (*t % 3600) / 60;
    ans.tm_sec = (*t % 3600) % 60;
    return (ans);
} 

//=============================
// mktime
//=============================
time_t ss_mktime( sstm  t ){
    time_t ans;
    ans = (t.tm_hour * 3600) + (t.tm_min * 60) + t.tm_sec;
    return (ans);
} 

//=============================
// timer SW seni
//=============================
void timerSeni(void){
    static uint8_t B_timesec = 0;

    // aSw(settei SW)
    if(sw.checkEdgeOn(aSw) == 1){
        if((M_timer != setMin) && (M_timer != setHore)){
            beep();
            M_timer = setMin;
            
            // genzai jikoku kakuno
            //seconds = time(NULL);
            A_time = ss_localtime(&seconds);
        }
        else if((M_timer == setMin) || (M_timer == setHore)){
            beep();
            M_timer = count;
            
            A_time.tm_sec = 0;
            seconds = ss_mktime(A_time);
         //   set_time(seconds);       
        }
        else{
            // noting
        }
    }
    
    // bSw(torikesi SW)
    if((sw.checkEdgeOn(bSw) == 1) && (M_timer != count)
    ){
        beep();
        M_timer = count;
    }    

    switch(M_timer){
    case stop:
        // other aSw,bSw then setMin
        if((sw.checkEdgeOn(upSw) == 1)
         ||(sw.checkEdgeOn(downSw) == 1)
         ||(sw.checkEdgeOn(leftSw) == 1)
         ||(sw.checkEdgeOn(rightSw) == 1)
         ){
            beep();
            M_timer = setMin;
            C_flicker = 0;
            
            // genzai jikoku kakuno
            //seconds = time(NULL);
            A_time = ss_localtime(&seconds);
        }
        break;
    case setMin:
        if(sw.checkEdgeOn(leftSw) == 1){
            beep();
            M_timer = setHore;
            C_flicker = 0;
        }
        break;
    case setHore:
        if(sw.checkEdgeOn(rightSw) == 1){
            beep();
            M_timer = setMin;
            C_flicker = 0;
        }
        break;
    case count:
        //seconds = time(NULL);
        A_time = ss_localtime(&seconds);
        
        // 59 kara 0 byo ni nattara melody wo narasu
        if((B_timesec == 59) && (A_time.tm_sec == 0)){
            // jikoku chime no kaisuu set
            uint8_t C_chime = A_time.tm_hour;
            if(C_chime == 0){
                C_chime = 12;
            }
            else if(C_chime > 12){
                C_chime -= 12;
            }

            // jikoku no melody and chime
            if(A_time.tm_min == 0){
                if(A_time.tm_hour == 12){
                    sound.sound_enso((Sound::sound_t*)RAMEN);
                    sound.sound_enso(true);
                    chimeSet(C_chime);
                }
                else {
                    sound.sound_enso((Sound::sound_t*)WESTMINSTER);
                    sound.sound_enso(true);
                    chimeSet(C_chime);
                }
            }
            
            // 30min no chime               
            if(A_time.tm_min == 30){
                chimeSet(2);
            }
            
            // 15min or 45min no chime
            if((A_time.tm_min == 15) || (A_time.tm_min == 45)){
                chimeSet(1);
            }
         }
        B_timesec = A_time.tm_sec; // jikai hikaku yo time data kioku
      break;
    
     default:
        // nothing
        break;
    }

}
//============================
// time set
//============================
void timerSet(void){

    switch(M_timer){
    case stop:
        break;
    case setMin:
        if(sw.checkEdgeOn(upSw) == 1){
            beep();
            if(A_time.tm_min < 59){
                A_time.tm_min++;
            }
            else{
                A_time.tm_min = 0;
            }
            C_flicker = Z_flicker;
         }
        
        if(sw.checkEdgeOn(downSw) == 1){
            beep();
            if(A_time.tm_min > 0){
                A_time.tm_min--;
            }
            else{
                A_time.tm_min = 59;
            }
            C_flicker = Z_flicker;
        }
        break;
    case setHore:
        if(sw.checkEdgeOn(upSw) == 1){
            beep();
            if(A_time.tm_hour < 23){
                A_time.tm_hour++;
            }
            else{
                A_time.tm_hour = 0;
            }
            C_flicker = Z_flicker;
        }
        
        if(sw.checkEdgeOn(downSw) == 1){
            beep();
             if(A_time.tm_hour > 0){
                A_time.tm_hour--;
            }
            else{
                A_time.tm_hour = 23;
            }
            C_flicker = Z_flicker;
        }
        break;
    case count:
        // nothing
        break;
    default:
        // nothing
        break;
    }
    
 }

//==========================
// seven segment display
//==========================
void sevenSegDisplay(void){
//    int16_t work;
    
    switch(M_timer){
    case stop:
 
        D_7seg[0] = 0x0f;
        D_7seg[1] = 0x0f;
        D_7seg[2] = 0x0f;
        D_7seg[3] = 0x0f;
 
        
        D_dot[0] = 0;
        D_dot[1] = 0;
        D_dot[2] = 0;
        D_dot[3] = 0;
        
        break;
    case setMin:    // setHore to onaji
    case setHore:
        sevenSegLed.smoothSet(1);   // hyoji hard
        D_7seg[0] = A_time.tm_hour / 10;
        D_7seg[1] = A_time.tm_hour % 10;
        D_7seg[2] = A_time.tm_min / 10;
        D_7seg[3] = A_time.tm_min % 10;

        // settei basyo no tenmetu        
        if((C_flicker == 0) && (F_flip500ms == 0)){
            if(M_timer == setMin){
                D_7seg[2] = 0x10;
                D_7seg[3] = 0x10;
            }
            else{
                D_7seg[0] = 0x10;
                D_7seg[1] = 0x10;
            }
        }

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

        break;
    case count:
        sevenSegLed.smoothSet(0);   // hyoji smooth
 //       seconds = time(NULL);
        A_time = ss_localtime(&seconds);
        
        D_7seg[0] = A_time.tm_hour / 10;
        D_7seg[1] = A_time.tm_hour % 10;
        D_7seg[2] = A_time.tm_min / 10;
        D_7seg[3] = A_time.tm_min % 10;

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

        // byo no dot no tenmetu   
        if((A_time.tm_sec % 2) == 0){
            D_dot[3] = 0;
        }
        else{
            D_dot[3] = 1;
        }
        break;

    default:
        break;
    }
    sevenSegLed.SevenSegLed_main(D_7seg, D_dot);    // 7segment hyoji
}

//================================
// 100ms interrupt
//================================
void interrupt100ms(void){
    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){
        rtc_count();
    }
}

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

    // kido ji no melody
    sound.sound_enso((Sound::sound_t*)DEMEKIN);
    sound.sound_enso(true);

    while(1) {
        // sw level and edge data refresh
        sw.refreshEdgeData();
    
        timerSeni();
        timerSet();
        sevenSegDisplay();
        chimeCheck();
    }
}