This program is a clock that uses a kitchen Timer boad.
Dependencies: SevenSegLed Sound_pwmToDig SwAnalog mbed
Fork of kitchenTimer_Clock by
LPC1114FN28(mbed)を使ったデジタル時計
<概要>
以前作成したLPC1114FN28(mbed)で作ったキッチンタイマーのプログラムを変更して、デジタル時計をつくりました。
回路はキッチンタイマーのものをそのまま使っています。基板作成や、プログラムの書き込み方法については、次のblogを参照してください。
回路図、PCB、WINSTAR PCB for iModela、などのデータはこちらからダウンロードできます。
<時計動作の説明>
基板の電源を入れると、表示が“FFFF”になり、メロディーが流れます。
スイッチは、 右上(赤)SW :時計時刻設定の開始・完了 右下(青)SW :時計時刻設定のキャンセル 左(黒)十字SW:時計時刻変更用 となっています。
デジタル時計の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(); } }