|
|
#include <Arduino.h>
|
|
|
#line 1 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
//通过人体红外热释电传感器和超声波测距传感器检测是否有人靠近以及当前距离是否小于30cm,基于温湿度传感器采集环境数据,通过硬件编程实现所需功能。
|
|
|
const int INFRARED_PIN = 2;
|
|
|
const int ECHO_PIN = 3;
|
|
|
const int TRIG_PIN = 4;
|
|
|
const int DHT11_PIN = 5;
|
|
|
const double DISTANCE = 30.0;
|
|
|
byte data[5];
|
|
|
#line 8 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
void setup();
|
|
|
#line 18 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
void loop();
|
|
|
#line 31 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
bool person_closing();
|
|
|
#line 36 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
double measure_distance();
|
|
|
#line 47 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
void measure_T();
|
|
|
#line 72 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
byte read_byte();
|
|
|
#line 86 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
void show();
|
|
|
#line 8 "g:\\course\\wlw\\exs\\code\\ex2\\ex2.ino"
|
|
|
void setup() {
|
|
|
// put your setup code here, to run once:
|
|
|
// 输入模式传感器读取环境数据,此时可被读取
|
|
|
pinMode(INFRARED_PIN, INPUT);
|
|
|
pinMode(ECHO_PIN, INPUT);
|
|
|
pinMode(TRIG_PIN, OUTPUT);
|
|
|
pinMode(DHT11_PIN, OUTPUT);
|
|
|
Serial.begin(9600);
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
// put your main code here, to run repeatedly:
|
|
|
|
|
|
if (person_closing())
|
|
|
{
|
|
|
if (measure_distance()<DISTANCE)
|
|
|
{
|
|
|
measure_T();
|
|
|
show();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool person_closing(){
|
|
|
// check if someone closing, outputting result
|
|
|
return digitalRead(INFRARED_PIN)==HIGH;
|
|
|
}
|
|
|
|
|
|
double measure_distance(){
|
|
|
digitalWrite(TRIG_PIN, LOW);
|
|
|
delayMicroseconds(2);
|
|
|
digitalWrite(TRIG_PIN, HIGH);
|
|
|
delayMicroseconds(20); // >10, starting measuring
|
|
|
digitalWrite(TRIG_PIN, LOW);
|
|
|
|
|
|
double time = pulseIn(ECHO_PIN, HIGH);
|
|
|
return time/1000000*340/2*100; // return distance (cm)
|
|
|
}
|
|
|
|
|
|
void measure_T(){
|
|
|
// 主机把总线拉低(输出低)至少18ms,保证DHT11检测到信号
|
|
|
digitalWrite(DHT11_PIN, LOW);
|
|
|
delay(30); // > 18 ms
|
|
|
|
|
|
// 主机延时等待20-40us(输出高,然后等待DHT11响应)
|
|
|
digitalWrite(DHT11_PIN, HIGH);
|
|
|
delayMicroseconds(40);
|
|
|
|
|
|
// DHT11输入模式,准备读取数据
|
|
|
pinMode(DHT11_PIN, INPUT);
|
|
|
|
|
|
// DHT11发送80us低电平响应信号,然后再把总线拉高(高电平)80us
|
|
|
while (digitalRead(DHT11_PIN) == HIGH); // 必须等到 LOW
|
|
|
delayMicroseconds(80); // DHT11 发出响应,会拉低 80us;所以至少等80us
|
|
|
while (digitalRead(DHT11_PIN) == LOW); // 继续等到变 HIGH
|
|
|
delayMicroseconds(80); //DHT11 会拉高到HIGH 80us 后开始发送数据
|
|
|
for (int i = 0; i < 5; ++i) data[i] = read_byte();
|
|
|
|
|
|
// 最后一bit发送后,DHT11拉低总线50us,然后转换为输出模式(总线拉高),总线进入空闲状态
|
|
|
pinMode(DHT11_PIN, OUTPUT);
|
|
|
digitalWrite(DHT11_PIN, HIGH);
|
|
|
}
|
|
|
|
|
|
// 连续发送40bit数据,高位先出, 每一bit数据都是50us低电平开始,高电平的长短决定了数据是‘0’或是‘1’
|
|
|
byte read_byte(){
|
|
|
byte byt = 0;
|
|
|
for (int i = 0; i < 8; ++i){
|
|
|
if (digitalRead(DHT11_PIN) == LOW){
|
|
|
while (digitalRead(DHT11_PIN) == LOW); // wait to be high
|
|
|
delayMicroseconds(30);
|
|
|
if (digitalRead(DHT11_PIN) == HIGH)
|
|
|
byt |= (1<<(7-i)); ////高位在前,低位在后
|
|
|
while (digitalRead(DHT11_PIN) == HIGH); // wait to be low
|
|
|
}
|
|
|
}
|
|
|
return byt;
|
|
|
}
|
|
|
|
|
|
void show(){
|
|
|
Serial.print("Current humdity = ");
|
|
|
Serial.print(data[0], DEC); //显示湿度的整数部分;
|
|
|
Serial.print('.');
|
|
|
Serial.print(data[1], DEC); //显示湿度的小数位;(其实是 0)
|
|
|
Serial.println(" %"); // 注意有空格要用 " %" 不可用 ' %'
|
|
|
Serial.print("Current temperature = ");
|
|
|
Serial.print(data[2], DEC); //显示温度的整数部分;
|
|
|
Serial.print('.');
|
|
|
Serial.print(data[3], DEC); //显示温度的小数位;(其实是 0)
|
|
|
Serial.println(" C");
|
|
|
}
|