基于Arduino的智能家居系统设计

基于Arduino的智能家居系统设计

一、设计要求
1、利用DHT11温湿度检测模块和光敏电阻采集环境温度、湿度和光强信息;
2、通过Arduino开发板对DS1302时钟模块进行初始设置,并每隔一定时间读取日期和时间信息;
3、利用LCD1602显示模块显示温度、湿度、光强、日期、时间和控制模式等信息;
4、根据从DS1302时钟模块读取的时间信息,每天固定时间给宠物进行自动投食、喂水若干次;
5、能够在自动控制模式和语音控制模式之间进行切换;
6、自动控制模式下,根据温度、湿度、光强等环境参数对灯、空调、窗帘等进行自动控制,通过继电器控制不同颜色的LED,模拟简单的家用电器场景;
7、语音控制模式下,根据LD3320语音识别模块接收到的控制指令,实现对家用电器的语音控制。
在这里插入图片描述

二、系统硬件设计
1.Arduino开发板
在这里插入图片描述
2.DHT11温湿度检测模块
DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一 个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式 进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大 电流 0.5mA。DHT11 的技术参数如下: 工作电压范围:3.3V-5.5V,工作电流 :平均 0.5mA ,输出:单总线数字信号,测量范围:湿度 20~90%RH,温度 0~50℃,精度 :湿度±5%,温度±2℃,分辨率 :湿度 1%,温度 1℃,DHT11 的管脚排列下图所示:
在这里插入图片描述
DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向 传输。其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数 数据+8bit 温度小数数据+8bit 校验和。其中校验和数据为前四个字节相加。 传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。
3.LCD1602显示模块
在这里插入图片描述
4.电位器
电位器是具有三个引出端、阻值可按某种变化规律调节的电阻元件。电位器通常由电阻体和可移动的电刷组成。当电刷沿电阻体移动时,在输出端即获得与位移量成一定关系的电阻值或电压。 电位器既可作三端元件使用也可作二端元件使用。后者可视作一可变电阻器,由于它在电路中的作用是获得与输入电压(外加电压)成一定关系得输出电压,因此称之为电位器。
5.继电器
继电器是一种根据电压、电流、温度、速度或时间等物理量的变化来接通或切断电路的电器,是一种在特定条件下可以使电路断开或导通的开关的,但开关的动力不是人手,而是电、磁、声、光、热等。常用于隔离控制与被控制电路,用低电压控制高电压系统,用小电流控制大电流系统,实现逻辑功能。继电器的主要功能是保护和控制,所以继电器虽然种类很多,但通常可分为保护继电器和控制继电器两大类。常见的继电器有热继电器、电磁式继电器、时间继电器、温度继电器和速度继电器等。
6.DS1302时钟模块
DS1302 是美国 DALLAS 公司推出的一种高性能、低功耗、带 RAM 的实时时钟电路, 它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能。且能自动对少于31天的月份日期进行调整,支持12小时制和24小时制。工作电压为 2.5V~ 5.5V。其内部包含一个实时时钟/日历以及一个31字节的RAM,同时采用三线接口与 CPU 进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或 RAM 数据。通过使用串行通信,可以简化DS1302与单片机的连接。与DS1302连接只需要三条线:RST(复位);I/O(数据线);SCLK(串行时钟信号);可以一次1字节或最多31个字节的在RAM之间传输数据。其他引脚的说明:VCC2:工作电源。GND:电源接地。VCC1:后背电源,需要3V的纽扣电池,能够在VCC2断开的时候继续供电,从而保持时钟数据。DS1302的运行只需要非常低的能耗,维持数据与时钟信息只需要不到1微瓦的功率。其内部有多个寄存器,通过访问特定地址,我们就能对这些寄存器进行读写操作。
7.光敏电阻
光敏电阻(photocell)又称光敏电阻器(缩写为ldr)或光导管,在电路中常用字母“R”或“RL”、“RG”表示。是一种随着外界光线强弱变化而变化的电阻。入射光强,电阻减小,入射光弱,电阻增大。常用材料为硫化镉,另外还有硒、硫化铝、硫化铅和硫化铋等半导体材料。一般用于光的测量、光的控制和光电转换(将光的变化转换为电的变化);如路灯,走廊光控灯,烟雾警报器等。光敏电阻是用硫化隔或硒化隔等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应。这些制作材料在特定波长的光照射下产生载流子参与导电,在外加电场的作用下作漂移运动,电子奔向电源的正极,空穴奔向电源的负极,使光敏电阻器的阻值迅速下降。
在这里插入图片描述
8.LD3320语音识别模块
LD332X芯片是一款由是有 ICRoute公司设计生产的“语音识别”专用芯片。该片集成了语音识别处理器和一些外部电路,包括AD、DA转换器、麦克风接口音输出接口等。不需要外接任何的辅助芯片如 Flash、RAM等,直接集成在现有的产品中即可以实现语音识别/声控/人机对话功能。真正提供了单识别解决方案。在LD332X内部,固化有高效的非特定人语音识别搜索引擎模块和完整的非特定人语音识别特征库,以及专为语音识别而作的硬件优化和加速设计。
在这里插入图片描述
三、系统软件设计
在这里插入图片描述
四、系统测试**
打开串口监视器,观察本机识别的MOC3口(不同的USB接口不同),同时lCD1602显示器会显示当前的光强,湿温度信息和时钟日期。系统默认的控制模式是自动控制的,在自动控制中用手挡住光敏电阻,系统中会判定当前光强较弱,会触发开灯的命令,LED灯就被点亮了,把手拿开以后,用手机的手电筒给个光,系统中会触发关灯的指令,LED就会熄灭。DHT11温湿度传感器模块,将采集周围环境的温湿度,当环境中的温度过高时,会触发系统中开空调的命令,这里在串口中显示空调已开启。当环境中的湿度过高时,串口显示开窗帘。当语音模块收到语音信号时,会将当前的控制模式转换为语音模式,程序里边自定义多个时间来设定给宠物喂食的时间,以及喝水的时间,DS1302模块会一直读取当前时间,用条件判断语句,当前的时间是否和自己设定的时间相等,如果相等的话,则系统会执行相应的投食和喝水等指令。当语音模块收到语音的时候,会从自动模式切换到语音模式,同时自己提前定义好语音内容,并且对语音内容进行绑定,当系统收到“kai deng”“guan deng”的命令时,LED灯就会做出相应的反应。当收到“kai kong tiao”“guan kong tiao”的命令时,串口进行相信的显示。当收到“kai jia shi”“guan jia shi”命令时,串口进行相应的显示。整个简易家具系统也算设计成功并且测试没有问题了。
附录

#include <dht11.h>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    那你  
#include <ld3320.h>
#include <PinMap.h>
#include <LiquidCrystal.h>
#include "DS1302.h"//时钟控制
#include <PinMap.h>
#define AD5 A5   //定义模拟口A5   光敏电阻使用
#define LED A0   //定义模拟口A5    led灯的 控制
#define DHT11PIN A4   //  温湿度数据
const int rs = 6, en = 10, d4 = 5, d5 = 8, d6 = 3, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int Intensity = 0;//光照度数值
dht11 DHT11;// 定义一个温湿度模块的对象
unsigned char Water_Hour=10;          // 喂水小时设置
unsigned char Water_Minute=38;        // 喂水分钟设置
unsigned char Food_Hour=10;          // 喂食小时设置
unsigned char Food_Minute=45;        // 喂食分钟设置
int HumBorder=60;  //湿度上限
int TemBorder=30;// 温度上限
int lightBorder=990;  //光强上限
String mode="Auto";   // 自动情况下
VoiceRecognition Voice;  //声明一个语音识别对象
bool Always=false;  //是否不间断地输出时间到串口(每隔 1 秒)
bool IsOpenHum=true;  //是否不间断地输出时间到串口(每隔 1 秒)
bool IsOpenTem=true;  //是否不间断地输出时间到串口(每隔 1 秒)

//显示时间
void Display_RTCC()
{
    
    

  if(DS1302Buffer.Year < 10)
  {
    
    
    Serial.print("200");
  }
  else
  {
    
    
    Serial.print("20");
  }
  Serial.print(DS1302Buffer.Year);
  Serial.print('-');
  Serial.print(DS1302Buffer.Month);
  Serial.print('-');
  Serial.print(DS1302Buffer.Day);
  Serial.print("   ");
  switch(DS1302Buffer.Week)
  {
    
    
  case 1:
    Serial.println("Mon");         //显示星期一
    break;
  case 2:
    Serial.println("Tue");         //显示星期二
    break;
  case 3:
    Serial.println("Wed");         //显示星期三
    break;
  case 4:
    Serial.println("Thu");         //显示星期四
    break;
  case 5:
    Serial.println("Fri");         //显示星期五
    break;
  case 6:
    Serial.println("Sat");         //显示星期六
    break;
  case 7:
    Serial.println("Sun");         //显示星期日
    break;
  default : break;            
  }
  Serial.print(DS1302Buffer.Hour);
  Serial.print(':');
  if(DS1302Buffer.Minute<10){
    
    
    Serial.print("0");
  }
  Serial.print(DS1302Buffer.Minute);
  Serial.print(':');
  Serial.println(DS1302Buffer.Second);
}
//串口输入
void Scan_Input()
{
    
    
  String comdata=""; 
  while (Serial.available() > 0)  
  {
    
    
    comdata += char(Serial.read());
    delay(2);
  }
  const char*timechar=comdata.c_str();
  if(strncmp(timechar,"set",3)==0)
  {
    
    
    Set_Time(comdata);
    Display_RTCC();
  }
  if(strncmp(timechar,"waterset",8)==0)
  {
    
    
    Water_Hour=comdata.substring(9,11).toInt();
    Water_Minute=comdata.substring(12,14).toInt();
    lcd.clear();
    lcd.print("Waterset:");
    lcd.print((String)Water_Hour+":"+(String)Water_Minute);
    lcd.setCursor(0,1);
    lcd.print("Set done!");
    delay(2000);
    lcd.clear();
  }
  if(strncmp(timechar,"foodset",7)==0)
  {
    
    
    Food_Hour=comdata.substring(8,10).toInt();
    Food_Minute=comdata.substring(11,13).toInt();
    lcd.clear();
    lcd.print("Foodset:");
    lcd.print((String)Food_Hour+":"+(String)Food_Minute);
    lcd.setCursor(0,1);
    lcd.print("Set done!");
    delay(2000);
    lcd.clear();
  }

  if(strncmp(timechar,"lightset",8)==0)
  {
    
    
    lightBorder=comdata.substring(8,12).toInt();
    lcd.clear();
    lcd.print("Lightset:");
    lcd.print((String)lightBorder);
    lcd.setCursor(0,1);
    lcd.print("Set done!");
    delay(2000);
    lcd.clear();
  }

  if(strncmp(timechar,"show",4)==0)
  {
    
    
    Serial.println("The Time Now Is:");
    Always=false;
    Display_RTCC();
  }

  //是否不间断地将时间输出到串口
  if(strncmp(timechar,"always",6)==0)
  {
    
    
    Always=!Always;
  }

  //显示闹钟
  //if( strncmp(timechar,"alarm",5)==0)
  //{
    
    
  //  Serial.print("Water Set to ");
  //  Serial.print(Water_Hour); 
  //  Serial.print(":");
  //  Serial.println(Water_Minute);   
  //}
  //帮助v
  if(strncmp(timechar,"help",4)==0)
  {
    
    
    help();
  }
  //切换自动
  if(strncmp(timechar,"auto",4)==0 )
  {
    
    
    mode="Auto";
    Serial.println("Mode: Auto");
    Serial.println("Set done");
  }
  //切换语音
  if(strncmp(timechar,"voice",5)==0){
    
    
    mode="Voice";
    Serial.println("Mode: Voice");
    Serial.println("Set done");
  }
}

//时间设置函数
void Set_Time(String &command)
{
    
    
  DS1302_ON_OFF(0);     //关闭振荡
  DS1302Buffer.Year=command.substring(4,6).toInt();
  DS1302Buffer.Month=command.substring(7,9).toInt();
  DS1302Buffer.Day=command.substring(10,12).toInt();
  DS1302Buffer.Week=command.substring(13,14).toInt();
  DS1302Buffer.Hour=command.substring(15,17).toInt();
  DS1302Buffer.Minute=command.substring(18).toInt();
  DS1302_SetTime( DS1302_YEAR , DS1302Buffer.Year );
  DS1302_SetTime( DS1302_MONTH , DS1302Buffer.Month );
  DS1302_SetTime( DS1302_DAY , DS1302Buffer.Day );
  DS1302_SetTime( DS1302_WEEK , DS1302Buffer.Week );
  DS1302_SetTime( DS1302_HOUR , DS1302Buffer.Hour );
  DS1302_SetTime( DS1302_MINUTE , DS1302Buffer.Minute );
  DS1302_ON_OFF(1);
  Always=false;
  Serial.println("Set Done");
  Display_RTCC();   
}


//帮助内容
void help()
{
    
    
  Serial.println("************************************* help *****************************************");
  Serial.println("Edited By Starky");
  Serial.println("Type \"set YY MM DD WEEK HH MM\" To Set The Time!");
  Serial.println("Such As Type \"set 08 08 08 1 12 00\" To Set The Time As 2008-8-8 Monday 12:00");
  Serial.println("Type \"waterset HH MM\" to set water time");
  Serial.println("Type \"foodset HH MM\" to set food time");
  Serial.println("Type \"lightset ###\" such as \"lightset 987\" to set lightborder");
  Serial.println("Type \"show\" To Display The Time Now!");
  Serial.println("Type \"always\" To Print The Time Every Second!");
  Serial.println("Welcome To Use!"); 
  Serial.println("************************************* help *****************************************");
}

// 自动控制系统
void autoControl(int Intensity,int Hum,int Tem){
    
    
  if(Intensity>=lightBorder)
  {
    
    
    digitalWrite(LED, HIGH);
  }
  else if(Intensity<=900)
  {
    
    
    digitalWrite(LED, LOW);
  }
  if(Hum>=HumBorder)
  {
    
    
    if(IsOpenHum)
    {
    
    
    Serial.println("关闭加湿器");
    IsOpenHum=false;
    }
  }

  if(Tem>=TemBorder)
  {
    
    
    if(IsOpenTem)
    {
    
    
    Serial.println("打开空调");
    IsOpenTem=false;
    }
  }
 
}
void setup()  //程序初始化
{
    
           
  Voice.init();                               //初始化VoiceRecognition模块   
  Voice.addCommand("zi dong",0);
  Voice.addCommand("sheng yin",1);
  Voice.addCommand("kai deng",2);
  Voice.addCommand("guan deng",3);
  Voice.addCommand("kai jia shi",4);
  Voice.addCommand("guan jia shi",5);
  Voice.addCommand("kai kong tiao",6);
  Voice.addCommand("guan kong tiao",7);
  Voice.start();//开始识别
  pinMode(LED,OUTPUT);//设置LED为输出模式
  Serial.begin(9600);//设置波特率9600
  lcd.begin(16, 2);
  DS1302_Init();
  DS1302_GetTime(&DS1302Buffer);
}

void loop()//程序主体循环
{
    
    
  Scan_Input();
  Intensity = analogRead(AD5);  //读取模拟口AD5的值,存入Intensity变量  光敏电阻
  int chk = DHT11.read(DHT11PIN); 
  switch(Voice.read()){
    
    
  case 0:
    mode="Auto";
    Serial.println("自动");
    break;
  case 1:
    mode="Voicqe";
    Serial.println("声音");
    break;
  case 2:
  if(mode=="Voicqe"){
    
    
    Serial.println("开灯===");
    digitalWrite(LED, HIGH);
  }
    break;
  case 3:
  if(mode=="Voicqe"){
    
    
    Serial.println("关灯===");  
    digitalWrite(LED, LOW);
  }
    break;
  case 4:
    Serial.println("开加湿===");  
    break;
  case 5:
    Serial.println("关加湿===");  
    break;
  case 6:
    Serial.println("开空调===");  
    break;
  case 7:
    Serial.println("关空调===");  
    break;
  default:
    break;
  }
  int Hum=(int)DHT11.humidity;
  int Tem=(int)DHT11.temperature;
  if(mode=="Auto"){
    
    
    autoControl(Intensity,Hum,Tem);
  } 
  ///显示在lcd上的 温度 湿度  光强
  lcd.setCursor(0, 0);
  lcd.print("g");
  lcd.setCursor(1, 0);
  lcd.print(Intensity);
  lcd.setCursor(5, 0);
  lcd.print("s");
  lcd.setCursor(6, 0);
  lcd.print(Hum);
  lcd.setCursor(9, 0);
  lcd.print("t");
  lcd.setCursor(10, 0);
  lcd.print(Tem);
  ///显示时间
  lcd.setCursor(0, 1);
  lcd.print(DS1302Buffer.Year);
  lcd.print("-");
  lcd.print(DS1302Buffer.Month);
  lcd.print("-");
  lcd.print(DS1302Buffer.Day);
  lcd.print(" ");
  lcd.print(DS1302Buffer.Hour);
  lcd.print(":");
  if(DS1302Buffer.Minute<10){
    
    
    lcd.print("0");
  }
  lcd.print(DS1302Buffer.Minute);
  lcd.print(":");
  lcd.print(DS1302Buffer.Second);
  delay(500);
  lcd.clear();
  DS1302_GetTime(&DS1302Buffer);       //获取当前RTCC值
  if(Always)
  {
    
    
    if(Flag_Time_Refresh == 1)
    {
    
    
      Flag_Time_Refresh = 0;
      Display_RTCC();
    }
  }
  if(DS1302Buffer.Hour==Water_Hour && DS1302Buffer.Minute==Water_Minute && DS1302Buffer.Second==0)
  {
    
    
    Display_RTCC();
    Serial.println("喂水时间到======");
    lcd.clear();
    for(int times=1;times<4;times++){
    
    
      lcd.setCursor(0, 0);
      lcd.print("Water time!");
      delay(1000);
      lcd.clear();
    }
  }
  if(DS1302Buffer.Hour==Food_Hour && DS1302Buffer.Minute==Food_Minute && DS1302Buffer.Second==0)
  {
    
    
    Display_RTCC();
    Serial.println("喂食时间到=====");
    lcd.clear();
    for(int times=1;times<4;times++){
    
    
      lcd.setCursor(0, 0);
      lcd.print("Food time!");
      delay(1000);
      lcd.clear();
    } 
  }
}

猜你喜欢

转载自blog.csdn.net/m0_46717588/article/details/122213301