ARDUINOにi2cでRTCとLCDとキャパシティブセンシングキースレーブをくっつけて時計機能とか、アラーム機能を試作しました。
RTCはばんとさんのライブラリーを利用。
LCDはエレキジャックの光村さんのライブラリーを利用。
キャパシティブセンシングのキースレーブはPIC16F1827で自作です。
タイマーコールして、割り込みでタイムアップを表示します。
一回きりタイマーのみ実装。
0x34キーでタイマー設定画面が起動し、分単位でのタイマー値が
できるようになります。UP/DOWNキーで0から59までを選択
0x31キーで時計表示に戻り、タイマースタート。
次の59秒時(設定した秒によりタイマー実時間が縮むのがイマイチ)
になるとD13のLEDが点灯し、LCDの2行目右側にTimeUp表示が出ます。
表示はおよそ10秒間で消えます。
繰り返しタイマーと年月時秒指定アラームは今回は取り組まず。
これにてばんとさんのRTC-8564ライブラリーの主たる機能は確かめ
たということになります。
さて、ちょいと長くなりますが、スケッチは次の通りです。
// i2c RTC-8564NB -> i2c Lcd // Using BANT's library by nobcha 05/06/2013 // RTC8564 http://memo.tank.jp/archives/7734 // Using MITSUNAGA's library by nobcha 05/06/2013 // i2c_lcd http://n.mtng.org/ele/arduino/i2c.html // nobcha // 2013.06.09 debugged // RTC_TIME ok RTC_setTIMER ok #include <I2CLiquidCrystal.h> #include <Wire.h> #include <RTC8564.h> RTC8564 RTC; RTC_TIME rtc_time; bool fWakeUp; const char* dayofweek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; char key_data, key_ref, set_pos,fWake_cnt; char LCD_CUR[7][2]={{0x03,0},{0x06,0},{0x09,0},{0x0C,0}, {0x2,1},{0x5,1},{0x8,1}}; // cursor position char RTC_VALUE[8][3] = {{11,30,5}, // initial,MAX,MIN {10,12,1}, {10,31,1}, {1,6,0}, {18,23,0}, {59,59,0}, {59,59,0}, {59,59,00}}; // year,month,day,weekday,hour,minute,second,timer // initialize the library I2CLiquidCrystal lcd(50, true); // | +--- set true if the power suply is 5V, false if it is 3.3V // +-------- contrast (0-63) void wakeup() { fWakeUp = true; } void setup() { Wire.begin(); lcd.begin(16,2); // set lib for display size (16x2) lcd.clear(); // clear the screen RTC.begin(); fWakeUp = false; attachInterrupt(0, wakeup, FALLING); pinMode(13,OUTPUT); fWake_cnt=10; if(rtc_time.month==0) { /* 2013年5月6日 0時0分0秒に時刻合わせ */ rtc_time.year = 2013; rtc_time.month = 5; rtc_time.day = 6; rtc_time.hour = 12; rtc_time.min = 0; rtc_time.sec = 0; RTC.adjust( rtc_time ); } } char Key_get( ) { char key; key_ref=0x0; Wire.requestFrom(0x38,1); // scm key:0x70 key=Wire.read(); Wire.endTransmission(); if(key==key_data) key_ref=0x0; else key_ref=0x1; return key; } // data increment and MAX check void data_inc(char set_pos ) { RTC_VALUE[set_pos][0]++; if(RTC_VALUE[set_pos][0]>(RTC_VALUE[set_pos][1])) { RTC_VALUE[set_pos][0]=RTC_VALUE[set_pos][2]; } } // data decrement and 0 check void data_dec(char set_pos) { if(RTC_VALUE[set_pos][0]==RTC_VALUE[set_pos][2]) { RTC_VALUE[set_pos][0]=RTC_VALUE[set_pos][1]+1; } RTC_VALUE[set_pos][0]--; } // RTC_VALUE loading from rtc_data void rtc_value_load() { RTC_VALUE[0][0]=(char)(rtc_time.year-2000); RTC_VALUE[1][0]=rtc_time.month; RTC_VALUE[2][0]=rtc_time.day; RTC_VALUE[3][0]=rtc_time.wday; RTC_VALUE[4][0]=rtc_time.hour; RTC_VALUE[5][0]=rtc_time.min; RTC_VALUE[6][0]=rtc_time.sec; } // RTC_VALUE recovering to rtc_data void rtc_value_recover() { rtc_time.year=RTC_VALUE[0][0]+2000; rtc_time.month=RTC_VALUE[1][0]; rtc_time.day=RTC_VALUE[2][0]; rtc_time.wday=RTC_VALUE[3][0]; rtc_time.hour=RTC_VALUE[4][0]; rtc_time.min=RTC_VALUE[5][0]; rtc_time.sec=RTC_VALUE[6][0]; } // main loop void loop(void) { char buf[32]; char key_1; if(RTC.now(&rtc_time)) { snprintf(buf,16,"%04u-%02u-%02u(%s)", rtc_time.year, rtc_time.month, rtc_time.day, dayofweek[rtc_time.wday]); lcd.setCursor(0,0); delay(100); lcd.print(buf); delay(100); snprintf(buf,16," %02u:%02u:%02u", rtc_time.hour, rtc_time.min, rtc_time.sec ); lcd.setCursor(0,1); delay(100); lcd.print(buf); } key_data=Key_get(); if(key_data!=0) { lcd.setCursor(9,1); snprintf(buf,8," k=%02X%02X", key_data, key_ref ); lcd.print(buf); } if((key_data==0x31)&(key_ref==1)) { set_pos=0; // YEAR->Month->day->hour->minuts->second rtc_value_load(); lcd.blink(); delay(300); while(set_pos<7) { // set_pos:5->0 char line, cur, key_in_data; line=LCD_CUR[set_pos][1]; cur=LCD_CUR[set_pos][0]; lcd.setCursor(cur,line); delay(100); key_data=Key_get(); lcd.setCursor(9,1); snprintf(buf,8," k=%02X%02X", key_data, key_ref ); lcd.print(buf); if(key_ref==0) key_in_data=0; else key_in_data=key_data; if(key_in_data==0x32) // 0x32:increment { data_inc(set_pos);} else if(key_in_data==0x33) // 0x33:decrement { data_dec(set_pos);} else if(key_in_data==0x31) { set_pos++;} delay(100); rtc_value_recover(); RTC.adjust( rtc_time ); snprintf(buf,16,"%04u-%02u-%02u(%s)", rtc_time.year, rtc_time.month, rtc_time.day, dayofweek[rtc_time.wday]); lcd.setCursor(0,0); delay(100); lcd.print(buf); delay(100); snprintf(buf,16," %02u:%02u:%02u", rtc_time.hour, rtc_time.min, rtc_time.sec ); lcd.setCursor(0,1); delay(100); lcd.print(buf); } delay(100); } lcd.setCursor(9,1); snprintf(buf,8," " ); lcd.print(buf); if((key_data==0x34)&(key_ref==1)) // 0x34 ? { delay(200); RTC_VALUE[7][0]=0; while(Key_get( )!=0x31) { char key_in_data; key_data=Key_get( ); snprintf(buf,16,"Timer set %02uMIN",RTC_VALUE[7][0]); lcd.setCursor(0,0); delay(100); lcd.print(buf); lcd.setCursor(11,0); lcd.blink(); delay(300); if(key_ref==0) key_in_data=0; else key_in_data=key_data; if(key_in_data==0x32) // 0x32:increment { data_inc(7);} else if(key_in_data==0x33) // 0x33:decrement { data_dec(7);} } RTC.setTimer(RTC.TIMING_1_MIN, RTC_VALUE[7][0] , true, true); } if((fWakeUp == true)&(fWake_cnt!=0)) { digitalWrite(13,HIGH); snprintf(buf,16,"TimeUP"); lcd.setCursor(9,1); delay(100); lcd.print(buf); fWake_cnt--; if(fWake_cnt==0) { fWakeUp=false; fWake_cnt=10; digitalWrite(13,LOW); snprintf(buf,16," "); lcd.setCursor(9,1); delay(100); lcd.print(buf); } } delay(500); } // 2013.06.08 // Timer set indicator ok // Alarm function debugging ok // How can I read out REG value?