Arduino的電子鬧鐘,可以設(shè)置時(shí)間,蜂鳴器報(bào)警,播放葫蘆娃,使用超聲波模塊,當(dāng)手與超聲波一定距離的時(shí)候關(guān)掉鬧鐘。
代碼復(fù)制到IDE下載即可。
Arduino單片機(jī)源程序如下:
- #include <EEPROM.h>
- #include <SR04.h>
- //葫蘆娃對(duì)應(yīng)的樂(lè)譜
- #define NOTE_D0 -1
- #define NOTE_D1 262
- #define NOTE_D2 293
- #define NOTE_D3 329
- #define NOTE_D4 349
- #define NOTE_D5 392
- #define NOTE_D6 440
- #define NOTE_D7 494
- #define NOTE_DL1 147
- #define NOTE_DL2 165
- #define NOTE_DL3 175
- #define NOTE_DL4 196
- #define NOTE_DL5 221
- #define NOTE_DL6 248
- #define NOTE_DL7 278
- #define NOTE_DH1 523
- #define NOTE_DH2 586
- #define NOTE_DH3 658
- #define NOTE_DH4 697
- #define NOTE_DH5 783
- #define NOTE_DH6 879
- #define NOTE_DH7 987
- //以上部分是定義是把每個(gè)音符和頻率值對(duì)應(yīng)起來(lái),其實(shí)不用打這么多,但是都打上了,后面可以隨意編寫D調(diào)的各種歌,我這里用NOTE_D+數(shù)字表示音符,NOTE_DH+數(shù)字表示上面有點(diǎn)的那種音符,NOTE_DL+數(shù)字表示下面有點(diǎn)的那種音符。這樣后面寫起來(lái)比較好識(shí)別。
- #define WHOLE 1
- #define HALF 0.5
- #define QUARTER 0.25
- #define EIGHTH 0.25
- #define SIXTEENTH 0.625
- //這部分是用英文對(duì)應(yīng)了拍子,這樣后面也比較好看
- int tune[] =
- {
- NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,
- NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,NOTE_D6,
- NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D6,
- NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,
- NOTE_D1,NOTE_D1,NOTE_D3,
- NOTE_D1,NOTE_D1,NOTE_D3,NOTE_D0,
- NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
- NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
- NOTE_DH1,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
- NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
- NOTE_D7,NOTE_D7,NOTE_D5,NOTE_D3,
- NOTE_D5,
- NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
- NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
- NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
- NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
- NOTE_D3,NOTE_D3,NOTE_D1,NOTE_DL6,
- NOTE_D1,
- NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
- NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
- NOTE_DH1,NOTE_D0,NOTE_D7,NOTE_D5,
- NOTE_D6,
- };//這部分就是整首曲子的音符部分,用了一個(gè)序列定義為tune,整數(shù)
- float duration[]=
- {
- 1,1,0.5,0.5,1,
- 0.5,0.5,0.5,0.5,1,0.5,0.5,
- 0.5,1,0.5,1,0.5,0.5,
- 0.5,0.5,0.5,0.5,1,1,
- 1,1,1+1,
- 0.5,1,1+0.5,1,
- 1,1,0.5,0.5,1,
- 0.5,1,1+0.5,1,
- 0.5,0.5,0.5,0.5,1+1,
- 0.5,1,1+0.5,1,
- 1+1,0.5,0.5,1,
- 1+1+1+1,
- 0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
- 0.5,1,0.5,1,1,
- 0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
- 0.5,1,0.5,1,1,
- 1+1,0.5,0.5,1,
- 1+1+1+1,
- 0.5,1,0.5,1+1,
- 0.5,1,0.5,1+1,
- 1+1,0.5,0.5,1,
- 1+1+1+1
- };//這部分是整首曲子的接拍部分,也定義個(gè)序列duration,浮點(diǎn)(數(shù)組的個(gè)數(shù)和前面音符的個(gè)數(shù)是一樣的,一一對(duì)應(yīng)么)
- //LCD初始化
- #include <LiquidCrystal.h>
- LiquidCrystal lcd=LiquidCrystal(2,3,4,5,6,7,8);
- // 初始 化按鍵
- int ring=A3;
- int set=A0; //選擇端口
- int add=A1; //加
- int minus=A2; //減
- //設(shè)置參數(shù)
- int jy=0,jmonth=0,jd=0,jh=0,jm=0,js=0;// 進(jìn)位
- int year=0,month=0,day=0,hour=0,minute=0,second=0;// 當(dāng)前時(shí)間
- int YEAR=2018,MONTH=4,DAY=12,HOUR=18,MINUTE=10,SECOND=00;// 初始設(shè)定時(shí)間
- int moving=0,ring_moving=0;// 設(shè)置時(shí)間的移動(dòng)
- int ring_hour=0,ring_minute=0,jr=0;//鬧鐘時(shí)間
- unsigned long seconds=0;//讀取程序運(yùn)行時(shí)間
- unsigned long b=1,secondcomp=0,exsecond=0;
- //蜂鳴器模塊定義
- int length;//這里定義一個(gè)變量,后面用來(lái)表示共有多少個(gè)音符
- int tonePin=9;//蜂鳴器的pin
- int a=0;
- //超聲波模塊管腳參數(shù)
- int echo=13;
- int trig=12;
- SR04 target=SR04(echo,trig);
- long distance=0;
- //共同體設(shè)置,把 無(wú)符號(hào)長(zhǎng)整 分4個(gè)字節(jié)存入 EEPROM
- union data
- {
- float renewtime;
- byte difference[4];
- };
- data col;
- void Time_Lcd(int rol,int raw,int number)// 標(biāo)準(zhǔn)格式 在lcd 顯示時(shí)間
- {
- lcd.setCursor(rol,raw);
- if(number<10)// 如果小于 10,輸出 為 0X
- {
- lcd.print(0);
- }
- lcd.print(number);
- }
- //顯示具體的時(shí)間
- void time()
- {
- if(SECOND<=0) SECOND=0;
- second=(secondcomp+seconds+SECOND+exsecond)%60;
- Time_Lcd(6,1,second);
- jm=(seconds+SECOND)/60;
- if(MINUTE<=0) MINUTE=0;
- minute=(jm+MINUTE)%60;
- Time_Lcd(3,1,minute);
- jh=(jm+MINUTE)/60;
- if(HOUR<=0) HOUR=0;
- hour=(jh+HOUR)%24;
- Time_Lcd(0,1,hour);
- lcd.setCursor(2,1);
- lcd.print(":");
- lcd.setCursor(5,1);
- lcd.print(":");
- lcd.setCursor(8,1);
- lcd.print(" ");
- lcd.setCursor(4,0);
- lcd.print("-");
- lcd.setCursor(7,0);
- lcd.print("-");
- }
- //算出當(dāng)月一共多少個(gè)月
- int DAYS(int year,int month)
- {
- if(year%4==0&&year%100!=0||year%400==0)
- {
- switch(month){
- case 1:case 3:case 5:case 7:case 8:case 10:case 12: return 31;break;
- case 2:return 29;break;
- case 4:case 6:case 9:case 11: return 30;break;}
- }
- else
- {
- switch(month){
- case 1:case 3:case 5:case 7:case 8:case 10:case 12: return 31;break;
- case 2:return 28;break;
- case 4:case 6:case 9:case 11: return 30;break;}
- }
- }
- //設(shè)置后的天數(shù),考慮進(jìn)一個(gè)月或者天數(shù)為 0,退一個(gè)月的情況
- void Day()
- {
- if(DAY<=0) DAY=0;
- int day=0;
- int exdays=0;
- int days=DAYS(year,month);
- if(month==1) exdays=DAYS(year-1,12);
- else exdays=(year,month-1);
- jd=(HOUR+jh)/24;
- day=(jd+DAY)%(days+1);
- if((jd+DAY)==0)
- {
- jmonth--;
- DAY=exdays;
- }
- if((jd+DAY)==(days+1))
- {
- jmonth++;
- DAY=DAY-days;
- }
- Time_Lcd(8,0,day);
- }
- //設(shè)置后的月數(shù),考慮 0月退一年的情況
- void Month()
- {
- if(MONTH<=0) MONTH=0;
- month=(MONTH+jmonth)%12;
- if(month==0&&(MONTH+jmonth)!=0) month=12;
- jy=(jmonth+MONTH-1)/12;
- if((MONTH+jmonth)==0)
- {
- month=12;
- jy--;
- }
- Time_Lcd(5,0,month);
- }
- //設(shè)置 年
- void Year()
- {
- if(YEAR<=0) YEAR=0;
- year=(jy+YEAR)%10000;
- lcd.setCursor(0,0);
- if(year<1000)
- {
- lcd.print("0");
- }
- if(year<100)
- {
- lcd.print("00");
- }
- if(year<10)
- {
- lcd.print("000");
- }
- lcd.print(year);
- }
- // 顯示時(shí)間匯總
- //設(shè)置鬧鐘,移動(dòng)光標(biāo)到對(duì)應(yīng)的時(shí)間位置
- void Set_Clock() //按鍵選擇
- {
- if(digitalRead(set)==LOW)
- {
- lcd.setCursor(9, 1); lcd.print("SetTime");
- while(1)
- {
- if(digitalRead(set)==LOW)
- {
- delay(10);
- if(digitalRead(set)==LOW)
- moving++;
- }
- seconds = millis()/1000;
- Show_Time();
- if(moving == 1)
- Set_Time(0, 1, HOUR); //設(shè)置小時(shí)
- if(moving == 2)
- Set_Time(3, 1, MINUTE); //分鐘
- if(moving == 3)
- Set_Time(6, 1, SECOND); //秒
- if(moving== 4)
- Set_Time(8, 0, DAY); //天
- if(moving== 5)
- Set_Time(5, 0, MONTH); // 月
- if(moving== 6)
- Set_Time(2, 0, YEAR); // 年
- if(moving >= 7)
- {
- moving = 0;
- lcd.setCursor(9,1);
- lcd.print(" ");
- break;
- }
- }
- delay(50);
- }
- }
- //光標(biāo)閃爍,顯示正在設(shè)置哪一位
- void Cursor_Blink(int col,int raw)
- {
- lcd.setCursor(col,raw);
- lcd.cursor();
- delay(100);
- lcd.noCursor();
- delay(100);
- }
- //更改初始時(shí)間
- void Set_Time(int col, int row, int &TIME) //通過(guò)按鍵設(shè)置時(shí)間
- {
- Cursor_Blink(col, row);
- if(digitalRead(add) == LOW)
- {
- delay(10);
- if(digitalRead(add) == LOW)
- TIME ++;
- Show_Time();
- }
- if(digitalRead(minus) == LOW)
- {
- delay(10);
- if(digitalRead(minus) == LOW)
- TIME --;
- Show_Time();
- }
- }
- //光標(biāo)閃爍,顯示正在設(shè)置哪一位
- //更改初始時(shí)間
- void Show_Time()
- {
- time();
- Day();
- Month();
- Year();
- }
- //設(shè)置鬧鈴時(shí)間,原理同上
- void Set_Ring()
- {
- if(digitalRead(ring)==LOW)
- {
- lcd.setCursor(0,0); lcd.print(" set RINGTime ");
- lcd.setCursor(0,1);
- lcd.print(" ");
- Time_Lcd(2,1,ring_hour);
- lcd.print(":");
- Time_Lcd(5,1,ring_minute);
- lcd.print(" ");
- while(1)
- {
- if(digitalRead(ring)==LOW)
- {
- delay(10);
- if(digitalRead(ring)==LOW)
- ring_moving++;
- }
- if(ring_moving == 1)
- Set_RingHour(); //SetHour
- if(ring_moving == 2)
- Set_RingMinute(); //SetMinute
- if(ring_moving >= 3)
- {
- ring_moving = 0;
- lcd.setCursor(10,0);
- lcd.print(" ");
- break;
- }
- }
- delay(100);
- }
- }
- void Set_RingHour() //通過(guò)按鍵設(shè)置時(shí)間
- {
- Cursor_Blink(2,1);
- if(digitalRead(add) == LOW)
- {
- delay(10);
- if(digitalRead(add) == LOW)
- ring_hour++;
- ring_hour=ring_hour%24;
- Time_Lcd(2,1,ring_hour);
- Time_Lcd(5,1,ring_minute);
- }
- if(digitalRead(minus) == LOW)
- {
- delay(10);
- if(digitalRead(minus) == LOW)
- ring_hour--;
- Time_Lcd(2,1,ring_hour);
- Time_Lcd(5,1,ring_minute);
- }
- }
- void Set_RingMinute() //通過(guò)按鍵設(shè)置時(shí)間
- {
- Cursor_Blink(5,1);
- if(digitalRead(add) == LOW)
- {
- delay(10);
- if(digitalRead(add) == LOW)
- {
- ring_minute++;
- ring_minute=ring_minute%60;
- if(ring_minute==0) ring_hour++;
- ring_hour=ring_hour%24;
- }
- Time_Lcd(2,1,ring_hour);
- Time_Lcd(5,1,ring_minute);
- }
- if(digitalRead(minus) == LOW)
- {
- delay(10);
- if(digitalRead(minus) == LOW)
- ring_minute--;
- ring_minute=ring_minute%60;
- Time_Lcd(2,1,ring_hour);
- Time_Lcd(5,1,ring_minute);
- }
- }
- void showdistance() //超聲波測(cè)量距離
- {
- distance=target.Distance();
- }
- void music()//控制蜂鳴器
- {
- length = sizeof(tune)/sizeof(tune[0]);//這里用了一個(gè)sizeof函數(shù),可以查出tone序列里有多少個(gè)音符
- for(int x=0;x<length;x++)
- {
- distance=target.Distance();
- if(distance<10)
- {
- break;
- }
- tone(tonePin,tune[x]);//此函數(shù)依次播放tune序列里的數(shù)組,即每個(gè)音符
- delay(200*duration[x]);//每個(gè)音符持續(xù)的時(shí)間,即節(jié)拍duration,400是調(diào)整時(shí)間的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
- noTone(tonePin);//停止當(dāng)前音符,進(jìn)入下一音符
- }
- }
- void Ring()//鬧鈴
- {
- if(hour==ring_hour&&minute==ring_minute&&second==0)
- music();
- }
- void setup() {
- // put your setup code here, to run once:
- lcd.begin(16,2);
- digitalWrite(add, HIGH);
- digitalWrite(minus, HIGH);
- digitalWrite(set, HIGH);
- digitalWrite(ring,HIGH);
- pinMode(tonePin,OUTPUT);//設(shè)置蜂鳴器的pin為輸出模式
- for(int i=0;i<4;i++)
- col.difference[i]=EEPROM.read(i);
- exsecond=col.renewtime;
- }
- void loop() {
- // put your main code here, to run repeatedly:
- seconds=millis()/1000;
- if(seconds==900*b+(b-1)) {secondcomp++;b++;}//補(bǔ)償誤差
- Show_Time();
- Set_Clock();
- Set_Ring();
- Ring();
- col.renewtime=seconds;
- for(int i=0;i<4;i++)
- EEPROM.write(i, col.difference[i]);
- }
復(fù)制代碼
所有資料51hei提供下載:
電子鬧鐘.docx
(16.28 KB, 下載次數(shù): 55)
2018-6-6 18:31 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|