Arduino实验报告
实验一:遥控灯
实验目的
初步了解Arduino编程语言和Arduino程序的执行过程,掌握红外遥控模块**的使用。
实验展示
实验代码
#include <IRremote.h>
int RECV_PIN=4;//红外接收器的引脚
int ledPin=2; //LED -digital 3
boolean ledState=HIGH; //ledState用来存储LED的状态
IRrecv irrecv(RECV_PIN);
decode_results results; //定义红外信号的接收变量
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(ledPin,OUTPUT); //设置LED为输出状态
}
void loop() {
// put your main code here, to run repeatedly:
if(IrReceiver.decode()){//判断是否接收到信号
Serial.println(IrReceiver.decodedIRData.decodedRawData,HEX);
if(IrReceiver.decodedIRData.decodedRawData == 0xFF00BF00){ //如果接受到的是电源键的信号,LED翻转状态
ledState=!ledState; //修改灯的状态
digitalWrite(ledPin,ledState);//更新灯的状态
}
IrReceiver.resume();
}
else{//非电源键信号,不做操作
}
}
实验二:音乐编程
实验目的
- 掌握蜂鸣器的使用方法;
- 使用红外遥控控制蜂鸣器播放音乐的速度。
实验展示
倍速展示
实验代码
#include <IRremote.h>//安装4.0的库(自己填写)
//根据简谱列出各频率
//(自己填写)
int bigeyestune[]=
{
495,589,495,589,495,
495,589,495,589,495
};
//节拍
//(自己填写)
float bigeyesbeat[]= //根据简谱列出各节拍
{
1,1,1,1,1+1,
1,1,1,1,1+1
};
// little star 简谱.
int lstune[]={
262,262,393,393,
441,441,393,
350,350,330,330,
294,294,262,
393,393,350,350,
330,330,294,
393,393,350,350,
330,330,294,
262,262,393,393,
441,441,393,
350,350,330,330,
294,294,262
};
//little star 节拍
float lsbeat[]={
1,1,1,1,
1,1,1+1,
1,1,1,1,
1,1,1+1,
1,1,1,1,
1,1,1+1,
1,1,1,1,
1,1,1+1,
1,1,1,1,
1,1,1+1,
1,1,1,1,
1,1,1+1
};
int buzzerpin = 8; //蜂鸣器引脚(自己填写)
int ledpin = 2; //led灯(自己填写)
//红外接收
#define IR_RECEIVE_PIN 4
IRrecv irrecv(IR_RECEIVE_PIN); //红外接收引脚(自己填写)
decode_results results;
int currentDelay = 500; // 初始节拍时间为500 ms
bool doubleSpeed = false;
void setup() {
pinMode(buzzerpin, OUTPUT); //设置蜂鸣器引脚为输出(自己填写)
pinMode(ledpin, OUTPUT); //设置led引脚为输出(自己填写)
Serial.begin(9600); //设置波特率为9600(自己填写)
IrReceiver.enableIRIn();
}
void start(int len, int buzzpin, int lepin, int *tune, float *beat, int currentDelay) {
irrecv.disableIRIn();
if(currentDelay == 500 )
Serial.println("现在以正常速度播放音乐");
else if(currentDelay == 250 )
Serial.println("现在以两倍速度播放音乐");
for (int x = 0; x < len; x++) {
tone(buzzpin, tune[x]);
digitalWrite(lepin, HIGH);//设置led亮(自己填写)
delay(currentDelay * beat[x]); //节拍参数(自己填写)
Serial.println(currentDelay);
digitalWrite(lepin, LOW);//设置led灭(自己填写)
noTone(buzzpin);
delay(100);
}
irrecv.enableIRIn();
}
void loop() {
String select;
while (Serial.available() > 0) {
select += char(Serial.read());
delay(2);
}
//红外接收模块
if(IrReceiver.decode()) {
Serial.println(IrReceiver.decodedIRData.decodedRawData,HEX);
if (IrReceiver.decodedIRData.decodedRawData == 0xFE01BF00) { //判断红外信号(自己填写)
doubleSpeed = !doubleSpeed;
currentDelay = (doubleSpeed) ? 250 : 500; // 切换节拍时间
Serial.println(currentDelay);
}
IrReceiver.resume(); //接收下一个信号
}
if (select != "") {
int len;
if (select == "Your big eyes") {
Serial.println("Next, we will play the Your big eyes");
len = sizeof(bigeyestune) / sizeof(bigeyestune[0]);
start(len,buzzerpin,ledpin,bigeyestune,bigeyesbeat,currentDelay); //start函数参数(自己填写)
} else if (select == "little star") {
Serial.println("Next, we will play the little star");
len = sizeof(lstune) / sizeof(lstune[0]);
start(len,buzzerpin,ledpin,lstune,lsbeat,currentDelay); //start函数参数(自己填写)
} else {
Serial.println("Sorry, there is no such song in the music library.");
}
}
}
实验三:温湿度传感器
实验目的
- 初步了解 LCD 电子屏幕的使用;
- 使用温湿度传感器将温湿度参数显示在电子屏幕上。
实验展示
实验代码
#include <LiquidCrystal_I2C.h>
#include <DFRobot_DHT11.h>
LiquidCrystal_I2C lcd(0x20,16,2);//设置LCD的地址,2行,每行16字符
DFRobot_DHT11 DHT;
#define DHT11_PIN 4
void setup() {
// put your setup code here, to run once:
lcd.init();// LCD初始化设置
lcd.backlight();// 打开 LCD背光
Serial.begin(9600);//设置串口波特率9600
Serial.print("Type, status, Humidity(%), Temperature(C)\n");//串口输出”Type, status, Humidity(%), Temperature(C)”
lcd.setCursor(0,0);
lcd.print("Humidity(%):");//LCD屏显示” Humidity(%):”
lcd.setCursor(0,1);//光标移到第2行,第一个字符
lcd.print("Temp(C):");//LCD屏显示”Temp(C):”
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("DHT11, \t");w
//读取 DHT11传感器的数据
DHT.read(DHT11_PIN);
//串口显示温湿度值
Serial.print(DHT.humidity,1);
Serial.print(",\t");
Serial.println(DHT.temperature,1);
//LCD显示温湿度值
lcd.setCursor(12,0);//LCD屏的光标移动到第1行某个位置
lcd.print(DHT.humidity,1);//LCD屏打印湿度值
lcd.setCursor(8,1);//LCD屏的光标移动到第2行某个位置
lcd.print(DHT.temperature,1);//LCD屏打印温度值
delay(1000);
}
实验四:电子闹钟
实验目的
- 模拟时间的流逝过程,实现时钟的正常运行;
- 实现电子闹钟的修改模式;
- 实现闹钟模式,保存闹钟时间并在指定时间使蜂鸣器发出声音。
实验展示
正常模式及修改模式
闹钟模式
实验代码
#include <IRremote.h>
#include <LiquidCrystal_I2C.h>
#define IR_RECEIVE_PIN 4
#define ALARM_PIN 8
IRrecv irrecv(IR_RECEIVE_PIN);
decode_results results;
inline int Isyearp(int x){
if(x%400==0)return 1;
if(x%100 && x%4==0)return 1;
return 0;
}
LiquidCrystal_I2C lcd(0x20,16,2);
int Y1,Y2,Y3,Y4;
int M1,M2;
int D1,D2;
int H1,H2;
int MI1,MI2;
int S1,S2;
int Date;
//定义全局闹铃时间变量--月 日 时 分
int Alarm_M1,Alarm_M2;//定义月份的两位,从高到低
int Alarm_D1,Alarm_D2;//定义日期的两位,从高到低
int Alarm_H1,Alarm_H2;//定义小时的两位,从高到低
int Alarm_MI1,Alarm_MI2;//定义分钟的两位,从高到低
int Alarm_S1,Alarm_S2;//定义秒数的两位,从高到低
//定义临时变量存储时间
int temp_Y1,temp_Y2,temp_Y3,temp_Y4;//定义年份的四位,从高到低
int temp_M1,temp_M2;//定义月份的两位,从高到低
int temp_D1,temp_D2;//定义日期的两位,从高到低
int temp_H1,temp_H2;//定义小时的两位,从高到低
int temp_MI1,temp_MI2;//定义分钟的两位,从高到低
int temp_Date;//定义星期
int temp_S1,temp_S2;//定义秒数的两位,从高到低
int pos[]={3,4,5,6,8,9,11,12,
13,14,16,17,19,20,22};
bool modify_flag,light_flag,alarm_flag,buzzer_flag;
int modifyindex,x,y;
char Datename[7][5]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
inline void xblink(){//实现光标闪烁
lcd.setCursor(x,y);
lcd.blink();
}
inline void xNoblink(){//取消光标闪烁
lcd.noBlink();
}
int Dayofmonth[13][2]={
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31
};
void calendarShow(){
lcd.setCursor(3,0);
lcd.print(Y1);lcd.print(Y2);lcd.print(Y3);lcd.print(Y4);
lcd.print("/");
lcd.print(M1);lcd.print(M2);
lcd.print("/");
lcd.print(D1);lcd.print(D2);
lcd.setCursor(1,1);
lcd.print(H1);lcd.print(H2);
lcd.print(":");
lcd.print(MI1);lcd.print(MI2);
lcd.print(":");
lcd.print(S1);lcd.print(S2);
//Date
lcd.setCursor(10,1);
if(Date==0)lcd.print("Mon");
else if(Date==1)lcd.print("Tue");
else if(Date==2)lcd.print("Wes");
else if(Date==3)lcd.print("Thu");
else if(Date==4)lcd.print("Fri");
else if(Date==5)lcd.print("Sat");
else if(Date==6)lcd.print("Sun");
else lcd.print("Error!");
return ;
}
void date(){
Date++;Date%=7;
D2++;
if(D2==10){
D2=0;D1++;
}
int day=D1*10+D2,month=M1*10+M2,year=Y1*1000+Y2*100+Y3*10+Y4;
int type=Isyearp(year);
if(day>Dayofmonth[month][type]){
D1=0;D2=1;
M2++;
if(M2==10)M2=0,M1++;
if(M1*10+M2>12){
Y4++;
if(Y4==10)Y4=0,Y3++;
if(Y3==10)Y3=0,Y2++;
if(Y2==10)Y2=0,Y1++;
}
}
}
void tita(){
S2++;
if(S2==10)S2=0,S1++;
if(S1==6)S1=0,MI2++;
if(MI2==10)MI2=0,MI1++;
if(MI1==6)MI1=0,H2++;
if(H2==4 && H1==2){
H1=H2=0;
date();
}
else if(H2==10){
H2=0;
H1++;
}
if(Alarm_S1==S1 && Alarm_S2==S2 && Alarm_MI2 == MI2 && Alarm_MI1 == MI1 && Alarm_H2 == H2 && Alarm_H1 == H1 && Alarm_D2 == D2 && Alarm_D1 == D1 && Alarm_M2 == M2 && Alarm_M1 == M1){
Serial.print(Alarm_H1);
Serial.print(Alarm_H2);
Serial.print(":");
Serial.print(Alarm_MI1);
Serial.print(Alarm_MI2);
Serial.print(":");
Serial.print(Alarm_S1);
Serial.print(Alarm_S2);
buzzer_flag=true;//启动蜂鸣器
}
if(S2==((Alarm_S2+3)%10)){//响铃3S,自动关闭闹钟
buzzer_flag=false;//关闭蜂鸣器
}
return ;
}
void addTime(){
int days,a,b;
if(y==0){
switch(x){
case 8://M1
if(M2<3)M1++,M1%=2;
else M1=0;
lcd.print(M1);
break;
case 9://M2
if(M1==0){
M2++;
if(M2==10)M2=1;
}
else M2++,M2%=3;
lcd.print(M2);
break;
case 11://D1
int month=M1*10+M2,year=Y1*1000+Y2*100+Y3*10+Y4;
int type=Isyearp(year);
if(month==2){
if(type){//isp
D1++;D1%=3;
}
else {
if(D2==9)D1++,D2%=2;
else D1++,D1%=3;
}
}
else {//month!=2
if(D2==0)D1++,D1%=4;
else if(D2==1){
int days=Dayofmonth[month][type];
if(days==31)D1++,D1%=4;
else if(days==30)D1++,D1%=3;
}
else D1++,D1%=3;
}
lcd.print(D1);
break;
case 12://D2
month=M1*10+M2,year=Y1*1000+Y2*100+Y3*10+Y4;
type=Isyearp(year);
if(month==2){
if(D1==2){
if(type)D2++,D2%=10;
else D2++,D2%=9;
}
else D2++,D2%=10;
}
else {
int days=Dayofmonth[month][type];
if(D1==3){
if(days==31)D2++,D2%=2;
else D2=0;
}
else D2++,D2%=10;
}
lcd.print(D2);
break;
case 3://Y1
Y1++;Y1%=10;
lcd.print(Y1);
break;
case 4:
Y2++;Y2%=10;
lcd.print(Y2);
break;
case 5:
Y3++;Y3%=10;
lcd.print(Y3);
break;
case 6:
Y4++;Y4%=10;
lcd.print(Y4);
break;
default:break;
}
}
else {//y=1
switch(x){
case 1://H1
if(H2<4)H1++,H1%=3;
else H1++,H1%=2;
lcd.print(H1);
break;
case 2://H2
if(H1==2)H2++,H2%=4;
else H2++,H2%=10;
lcd.print(H2);
break;
case 4:
MI1++;MI1%=6;
lcd.print(MI1);
break;
case 5:
MI2++;MI2%=10;
lcd.print(MI2);
break;
case 7:
S1++;S1%=6;
lcd.print(S1);
break;
case 8:
S2++;S2%=10;
lcd.print(S2);
break;
case 10:
Date++;Date%=7;
lcd.print(Datename[Date]);
break;
}
}
lcd.setCursor(x,y);
}
void setAlarm(){
Alarm_M1=M1;Alarm_M2=M2;
Alarm_D1=D1;Alarm_D2=D2;
Alarm_H1=H1;Alarm_H2=H2;
Alarm_MI1=MI1;Alarm_MI2=MI2;
Alarm_S1=S1;Alarm_S2=S2;
}
void setup() {
// put your setup code here, to run once:
//setup time
Y1=2;Y2=0;Y3=2;Y4=3;
M1=M2=1;
D1=2;D2=1;
Date=1;
H1=0;H2=8;
MI1=4;MI2=1;
//Tuesday 2023/11/21 8:41
x=3;y=0;
modifyindex=0;
modify_flag=alarm_flag=buzzer_flag=false;
//IR_remote
pinMode(ALARM_PIN,OUTPUT);
irrecv.enableIRIn();
//lcd
lcd.init();
lcd.backlight();
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(irrecv.decode()){
Serial.println(irrecv.decodedIRData.decodedRawData,HEX);
if(irrecv.decodedIRData.decodedRawData == 0xFF00BF00){//电源键
light_flag^=1;
if(light_flag)lcd.backlight();
else lcd.noBacklight();
}
else if(irrecv.decodedIRData.decodedRawData == 0xEF10BF00){//1
modifyindex=0;
modify_flag^=1;
if(modify_flag){
xblink();
Serial.println("接受到1信号,进入修改时间模式");
}
else{
xNoblink();
modifyindex=0;
//光标逻辑位置数组的索引初始化
}
}
else if(irrecv.decodedIRData.decodedRawData == 0xEE11BF00){//2
modifyindex=0;
if(alarm_flag){
xNoblink();
modify_flag=false;
alarm_flag^=1;
setAlarm();
Y1=temp_Y1;Y2=temp_Y2;Y3=temp_Y3;Y4=temp_Y4;
M1=temp_M1;M2=temp_M2;D1=temp_D1;D2=temp_D2;
H1=temp_H1;H2=temp_H2;MI1=temp_MI1;MI2=temp_MI2;
S1=temp_S1;S2=temp_S2;
Date=temp_Date;
}
else{
temp_Y1=Y1;temp_Y2=Y2;temp_Y3=Y3;temp_Y4=Y4;
temp_M1=M1;temp_M2=M2;temp_D1=D1;temp_D2=D2;
temp_H1=H1;temp_H2=H2;temp_MI1=MI1;temp_MI2=MI2;
temp_Date=Date;
temp_S1=S1;temp_S2=S2;
modify_flag=true;
buzzer_flag=false;
alarm_flag=true;
x=1,y=1;modifyindex=8;
xblink();
}
}
else if(irrecv.decodedIRData.decodedRawData == 0xFB04BF00){//左快进
if(modify_flag){
xNoblink();
(modifyindex+=14)%=15;
x=pos[modifyindex];
if(x>12){
x-=12;y=1;
}
else y=0;
xblink();
}
}
else if(irrecv.decodedIRData.decodedRawData == 0xF906BF00){//右快进
if(modify_flag){
xNoblink();
(modifyindex+=1)%=15;
x=pos[modifyindex];
if(x>12){
x-=12;y=1;
}
else y=0;
xblink();
}
}
else if(irrecv.decodedIRData.decodedRawData == 0xFE01BF00){//vol+
if(modify_flag)addTime();
}
irrecv.resume();
}
if(!modify_flag && !alarm_flag){
tita();
calendarShow();
delay(1000);
}
if(buzzer_flag){
digitalWrite(ALARM_PIN,HIGH);
}
else{
digitalWrite(ALARM_PIN,LOW);
}
}