**
备注:本人因学校社团假期作业要求,用Arduino IDE编写并模拟实现了一个全自动
收/凉衣服的机器(由于硬件条件不足只能模拟),本人也是萌新一枚,希望观看的
大佬们不喜勿喷,有发现做错的话欢迎在评论区讨论,如果对你有帮助,本人也会
非常开心哒
1.下雨时报警,如果没有人反应,则自动收衣服
2.晴天时自动晒衣服
1.用流水灯不同的方向显示电机运转的不同方向
2.检测晴天和下雨时蜂鸣器发出的声音不一样
3.本人采用了开始时令数据稳定,三次取两次等方法防止数据波动出现异常
1.减速电机
2.蜂鸣器
3.HC-SR04超声波测距(可不用)
4.DHT11温湿度传感器
5.LED
6.Arduino单片机
7.杜邦线若干根
8.在电脑上安装IDE
串口通信协议,c/c++编程语言,各种传感器的数据手册等
void ring();//自定义的蜂鸣器报警旋律
byte readData();// 温湿度信号接脚连入 Arduino 的 Pin 2
void start_test();// 每次要与 DHT11 沟通并开始检测温湿度
boolean test_rain();//检测为下雨(湿度超标),返回True,否则返回False
boolean test_sun();//检测为晴天(湿度和温度都合适),返回True,否则返回False
void liushui1();//控制流水灯的函数,用于显示电机正向运作(持续时间大约18s)
void liushui2();//控制流水灯的函数,用于显示电机反向运作(持续时间大约18s)
int judge = 0;//设置一个变量判断现在的情况,0为初始化阶段,1为下雨,2为晴天
int val;//流水灯中电平变量
//float range;设置HC-SR04的距离
//float time1;设置HC-SR04返回信号的时间
void ring(){
for(int i=0;i<3;i++){
digitalWrite(8,HIGH);
delay(233);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(132);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(200);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(266);
digitalWrite(8,LOW);
delay(66);
digitalWrite(8,HIGH);
delay(233);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(132);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(200);
digitalWrite(8,LOW);
delay(33);
digitalWrite(8,HIGH);
delay(266);
digitalWrite(8,LOW);
delay(2400);
}
}
int dhPin = 2;
byte dat[5]; // 存放湿度2byte, 温度 2 byte, checksum 1 byte
byte readData() { // 每次读取 8 bits ( one byte)
byte data = 0 ; // 初始化数据,不然可能出错
for (int i = 0; i < 8; i++) {
if (digitalRead(dhPin) == LOW) { // 一开始要 LOW 才表示要传过来
while (digitalRead(dhPin) == LOW); //等待 50us;
// 现在已经变成 HIGH 了
delayMicroseconds(30); //判断高电平持续时间,以判定资料是‘0’还是‘1’;
if (digitalRead(dhPin) == HIGH) // 持续了 30 us 以上就是 1
data |= (1 << (7 - i)); //高位在前,低位元在后;
//如果这时已经是 LOW, 表示这 bit 是 0, 不必塞入 data
//..而且以下的 while 也会立即结束(因为 LOW), 准备接收下一个 bit
while (digitalRead(dhPin) == HIGH); // 等待下一bit的接收;
//这时一定已经变成 LOW 了
}
}
return data; // 收完 8 bit = one byte = one char
}
void start_test() {
digitalWrite(dhPin, LOW); //拉低到 LOW,发送表示要开始沟通的信号;
delay(30); //延时要大于 18ms,以便 DHT11 能检测到开始信号;我们用30ms
digitalWrite(dhPin, HIGH); // 拉高HIGH, 让 DHT11 拉低到 LOW 告诉我们要传送
delayMicroseconds(40); // 给40us等待 DHT11 响应;
pinMode(dhPin, INPUT); // 改为输入 mode 准备 digitalRead( )
while (digitalRead(dhPin) == HIGH); // 必须等到 LOW
delayMicroseconds(80); //DHT11 发出响应,会拉低 80us;所以至少等80us
while (digitalRead(dhPin) == LOW); // 继续等到变 HIGH
delayMicroseconds(80); //DHT11 会拉高到HIGH 80us 后开始发送数据;
/// 以下连续读入 5 bytes (40 bits), 最后的 byte 是 checksum 校验值
for (int i = 0; i < 5; i++) dat[i] = readData(); //接收温湿度资料,校验位元;
pinMode(dhPin, OUTPUT); // 改为 Output mode, 准备拉高HIGH
digitalWrite(dhPin, HIGH); //发送完一次资料后释放bus,等待下一次开始信号;
}
boolean test_rain(){
int count = 0;
for(int i=0;i<3;i++){//防止数据波动
start_test( );
if (dat[0] > 70)
count++;
delay(1985);
}
if(count >=2)//三次测试如果有两次超标,则返回True,表示雨天
return true;
else
return false;
}
boolean test_sun(){
int count = 0;
for(int i=0;i<3;i++){//防止数据波动
start_test( );
if ((dat[0] < 40)&&(dat[2] > 30))
count++;
delay(1985);
}
if(count >=2)//三次测试如果有两次达到标准,则返回True,表示晴天
return true;
else
return false;
}
void liushui1(){//控制流水灯的函数,用于显示电机正向运作(持续时间大约18s)
for(int i=0;i < 2;i++){
for(val=0;val<=255;val++){
analogWrite(9,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(9,val);
delay(6);
}
for(val=0;val<=255;val++){
analogWrite(10,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(10,val);
delay(6);
}
for(val=0;val<=255;val++){
analogWrite(11,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(11,val);
delay(6);
}
}
}
void liushui2(){//控制流水灯的函数,用于显示电机反向运作(持续时间大约18s)
for(int i=0;i < 2;i++){
for(val=0;val<=255;val++){
analogWrite(11,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(11,val);
delay(6);
}
for(val=0;val<=255;val++){
analogWrite(10,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(10,val);
delay(6);
}
for(val=0;val<=255;val++){
analogWrite(9,val);
delay(6);
}
for(val=255;val>=0;val--){
analogWrite(9,val);
delay(6);
}
}
}
/*float distance(){//返回超声波测距的距离
digitalWrite(12, LOW);
delayMicroseconds(2);
digitalWrite(12,HIGH);
delayMicroseconds(10);
digitalWrite(12, LOW);
time1=float(pulseIn(3,HIGH));
range=time1*17/1000;
delay(100);
return range;
}*/
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(8,OUTPUT);
pinMode(4,OUTPUT);
pinMode(7,OUTPUT);
Serial.println("begin!");
pinMode(dhPin, OUTPUT);
//pinMode(3,INPUT_PULLUP);
//pinMode(12,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int i;
boolean rain = test_rain(),sun = test_sun();
if(judge == 0){//如果处于初始化阶段(晾衣杆在外面)
for(i=0;i<6;i++){//先检测6次让数据稳定
start_test();
Serial.print("检测到湿度为 = ");
Serial.print(dat[0], DEC); //显示湿度的整数部分;
Serial.print('.');
Serial.print(dat[1], DEC); //显示湿度的小数位;(其实是 0)
Serial.println(" %"); // 注意有空格要用 " %" 不可用 ' %'
Serial.print("检测到温度为 = ");
Serial.print(dat[2], DEC); //显示温度的整数部分;
Serial.print('.');
Serial.print(dat[3], DEC); //显示温度的小数位;
Serial.println(" C");
delay(1985);
}
Serial.println("数据已稳定!");
while((rain||sun) == false){//两个测试都为假的话,保持初始化阶段,直到检测出有变化
Serial.println("当前未检测到有变化");
rain = test_rain();
sun = test_sun();
}
if(rain){//如果检测到下雨
judge = 1;//将判断条件设为1
ring();//发出警报
Serial.println("检测到下雨!开始警报并且收衣服!");
digitalWrite(4,HIGH);
digitalWrite(7,LOW);
liushui1();//电机开始工作,同时流水灯显示电机正转
//当然有些情况下电机转动后距离依然不够,于是我添加了HC-SR04超声波测距,但是由于硬件条件不足,我无法将
//其在现实中实现,这里只提供代码。。(使用时要把上面一行代码删除)
/*float distance1 = distance();
while(distance1 >= 10){//当距离超过10cm时,持续收回晾衣杆
distance1 = distance();
Serial.print("当前距离");
Serial.println(range);
}*/
digitalWrite(4,LOW);
Serial.println("已成功收回晾衣杆!");
}
}
else if (judge == 1){//如果是处于下雨的情况
Serial.println("现在在下雨!");
while(!sun){
sun = test_sun();
Serial.print("检测到湿度为 = ");
Serial.print(dat[0], DEC); //显示湿度的整数部分;
Serial.print('.');
Serial.print(dat[1], DEC); //显示湿度的小数位;(其实是 0)
Serial.println(" %"); // 注意有空格要用 " %" 不可用 ' %'
Serial.print("检测到温度为 = ");
Serial.print(dat[2], DEC); //显示温度的整数部分;
Serial.print('.');
Serial.print(dat[3], DEC); //显示温度的小数位;
Serial.println(" C");
}
Serial.println("检测到已经晴天!");
digitalWrite(8,HIGH);
delay(1200);
digitalWrite(8,LOW);
judge = 2;
digitalWrite(4,LOW);
digitalWrite(7,HIGH);
liushui2();//电机开始工作,同时流水灯显示电机反转
digitalWrite(7,LOW);
Serial.println("已成功伸出晾衣杆!");
//这里关于使用HC-SR04的代码和上面初始化时的情况类似,就不赘述了
}
else if(judge == 2){//如果是处于晴天的情况
Serial.println("现在是晴天!");
while(!rain){
rain = test_rain();
Serial.print("检测到湿度为 = ");
Serial.print(dat[0], DEC); //显示湿度的整数部分;
Serial.print('.');
Serial.print(dat[1], DEC); //显示湿度的小数位;(其实是 0)
Serial.println(" %"); // 注意有空格要用 " %" 不可用 ' %'
Serial.print("检测到温度为 = ");
Serial.print(dat[2], DEC); //显示温度的整数部分;
Serial.print('.');
Serial.print(dat[3], DEC); //显示温度的小数位;
Serial.println(" C");
}
Serial.println("检测到下雨了!");
ring();
judge = 1;
digitalWrite(7,LOW);
digitalWrite(4,HIGH);
liushui1();//电机开始工作,同时流水灯显示电机正转
digitalWrite(4,LOW);
Serial.println("已成功收回晾衣杆!");
//这里关于使用HC-SR04的代码和上面初始化时的情况类似,就不赘述了
}
}
注:由于本人囊中羞涩+时间不足,无法购买一些曲轴、齿轮等零件,所以只能将
晾衣架模拟为竖直方向的运动,在这里深感抱歉(不过改成水平运动的代码和原理
是差不多的啦)
萌新的Arduino大作业(自动收\晾衣服)
最后,我的有部分代码转载自某些大佬之手,如果侵权请与本人联系,本人会尽快
删除!