Arduino实验报告

发布时间 2023-12-12 09:26:47作者: ¶凉笙

实验三:温湿度传感器

实验目的

  1. 初步了解 LCD 电子屏幕的使用;
  2. 使用温湿度传感器将温湿度参数显示在电子屏幕上。

实验展示

实验代码

#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); 
}

实验四:电子闹钟

实验目的

  1. 模拟时间的流逝过程,实现时钟的正常运行;
  2. 实现电子闹钟的修改模式;
  3. 实现闹钟模式,保存闹钟时间并在指定时间使蜂鸣器发出声音。

实验展示

正常模式及修改模式

闹钟模式

实验代码

#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);
  }
}