1.材料 1.DHT11 ×1 2.Arduino小板 ×1 3.Newifi3(已刷Pandora Box) ×1 4.Ubuntu 系统的计算机 ×1 2.单片机端2.1硬件连线: DHT11引脚 Arduino引脚 1 ----------------------- 9 2 ----------------------- 10 3 ----------------------- 11 4 ----------------------- 12 ardiuion 用数据线接到路由器usb接口
2.2软件说明: 1.波特率9600够用,太高linux端会乱码 2.由于未知原因,linux端每次发送完数据,arduino都会被重置,程序又重新从头执行。暂时没找到解决方案,如果有高手有所了解还请指点一二,不胜感激。
程序正文: - #define vcc 9 //2号IO口作为通信接口
- #define out 10
- #define nc 11
- #define gnd 12
- #define contral 13
- void setup() {
- Serial.begin(9600); //波特率9600,太高linux端乱码
- pinMode(vcc, OUTPUT);
- pinMode(out, INPUT);
- pinMode(contral, INPUT);
- digitalWrite(contral, HIGH);
- pinMode(nc, INPUT);
- pinMode(gnd, OUTPUT); //IO口设为输入模式
- digitalWrite(vcc, HIGH);
- digitalWrite(gnd, LOW);
- }
- void loop() {
- delay(500);
- beginDHT(); //起始函数,向DHT11发送起始信号
- unsigned char* b = read1();//读取传感器数据
- display_1(b);//串口显示数据
- }
- void beginDHT()
- {
- pinMode(out, OUTPUT);//io 设为输出模式,是因为测量发现DHT11的上拉电流有5mA,
- //远大于输入模式下ATmega328的 io 的下拉电流,便无法得到 起始的至少28ms的低电平。
- digitalWrite(out, HIGH);//io置高
- delay(1100); //等待1.4s,因为DHT11的采样周期为1s,这里取的稍长一些。
- digitalWrite(out, LOW);//io拉低,发送起始信号
- delay(30); //延时至少28ms,这里取30ms
- digitalWrite(out, HIGH);//拉高
- pinMode(out, INPUT);//切换到输入模式,准备读数据
- }
- unsigned char*read1()
- {
- //int a[6]={0,0,0,0,0,0};//定义数组,存放数据
- int i, j;//变量,下面用到
- unsigned char* b = new unsigned char[5];//用b将数据返回给loop()***此处将传感器数据传递出去用全局变量也行,但想试试其他方法****
- for (i = 0; i < 5;i++)
- b = 0;
- delayMicroseconds(40);//延时40us,等待DHT11将io拉低
- if (digitalRead(out) == 0)//io读取值为0,说明DHT11已响应,io已经被拉低
- {
- while (digitalRead(out) == 0);//等待80us的低电平结束
- delayMicroseconds(82);//等待80us的高电平结束
- for (i = 0; i < 5; i++)//5个元素,依次存放温度、湿度、校验值数据
- {
- for (j = 0; j < 8; j++)//依次读取各二进制位
- {
- b= b << 1;//得到二进制数的第一位之后,将数据左移一位
- while (digitalRead(out) == 0);//等待50us的低电平结束
- delayMicroseconds(32);//延时40us,大于表示数据“0”的26-28us高电平,并小于表示数据“1”70us高电平
- if (digitalRead(out) == 0)//若io读取值为0,说明高电平时间小于40us,即为数据“0”
- {
- b = b | 0x00;//数据最低位取0
- }
- else//若io读取值为1,说明高电平时间大于40us,即为数据“1”
- {
- b = b | 0x01;//数据最高位取1
- delayMicroseconds(40);//因数据“1”高电平时间为70us,70-40=30,这里取的比30稍大,确保io已经拉低
- }
- }
- }
- //b=a; //依次将a[]传给b[];
- }
- else //如果io读取不为0,说明io没有被拉低
- {
- // Serial.print(" DHT11未响应 , ");//则认为是DHT11未响应
- for (i = 0; i < 5; i++) //湿度赋值为-1.湿度为负说明读取出错
- {
- b = 0;
- }
- }
- returnb;//返回b ******此处将传感器数据传递出去用全局变量也行,但想试试其他方法****
- }
- void display_1(unsigned char b[])//显示函数
- {
- int c = (b[0] + b[1] + b[2] + b[3]) & 0xff;
- unsigned char JiaoYanZhi;
- int avaliable = -1;
- charnumber[5];
- floatWenDu, ShiDu;//定义浮点数据类型
- ShiDu = b[0]+ float(b[1]) / 10;//计算湿度,后面的float(b[1])是将int类型的b[1]转换为浮点数据,
- //因为小于10的int类型数据除以10之后将总为0.
- WenDu = b[2]+ float(b[3]) / 10;//计算温度。
- JiaoYanZhi = b[4];//校验值赋值
- if (JiaoYanZhi == c&& ShiDu > 0)//校验数据是否正确且湿度不小于0(湿度小于0说明
- //上面的DHT11未向应),正确且湿度大于0则串口输出数据
- {
- //digitalWrite(out,HIGH);//串口显示数据
- //Serial.println(avaliable);
- Serial.print("温度:");
- //itoa(20,number,10);
- Serial.print(WenDu);
- Serial.print("_度 </h1> <h1> ");
- //Serial.println(int(WenDu));
- Serial.print("湿度:");
- Serial.print(ShiDu);
- Serial.print("_%");
- /*
- Serial.print(" 校验值");
- Serial.print(JiaoYanZhi);
- Serial.print(" 计算值:");
- Serial.print(c);
- if(JiaoYanZhi!=c)
- Serial.print("*************");
- Serial.println("");
- */
- }
- else//校验数据是否正确,错误则串口错误提示
- {
- Serial.println("读取数据出错~");
- }
- //接收到S(ascii码83)T(ascii码84) 之后继续运行
- while(avaliable != 83 && digitalRead(contral) == 0)
- {
- avaliable =Serial.read();
- delay(200);
- }
- while(avaliable != 84 && digitalRead(contral) == 0) {
- avaliable =Serial.read();
- delay(200);
- }
- while(avaliable != -1 && digitalRead(contral) == 0) {
- avaliable =Serial.read();
- delay(200);
- }
- }
复制代码
3.路由器端
3.1路由器配置需要安装的软件包有 1.kmod-usb-serial-ch341 (用于连接arduino) 2.coreutils-stty (用于配置串口参数)
3.2路由器端脚本PS:此脚本保存为 /www/gettmp.sh - #!/bin/bash
- myPath='/www/'
- #获取arduino所在端口号
- USB_Num_str=`dmesg | grepttyUSB*`
- #echo $USB_Num_str
- USB_Num_str=${USB_Num_str##*ch341}
- #echo-------------------------------
- USB_Num_str=${USB_Num_str##*'attachedto '}
- echo $USB_Num_str
- #获取当前系统时间
- time1=$(date)
- #设置串口速率9600,超时4s
- stty -F"/dev/$USB_Num_str" raw speed 9600 min 0 time 40
- #发送起始信号
- echo SSSTTT>"/dev/$USB_Num_str"
- #echo AAABBB>"/dev/$USB_Num_str" | cat "/dev/$USB_Num_str"
- #获取数据
- data_got=`cat"/dev/$USB_Num_str"`
- echo"${time1}${data_got}"
- #写入网页编码信息,防止乱码
- echo '<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />'>"${myPath}index2.html"
- #写入网页内容
- echo"<html><h2>${time1}</h2><h1>${data_got}</h1></html>">>"${myPath}index2.html"
复制代码
3.3路由器端网页服务器搭建$vi /usr/config/uhttpd/ 在末尾增加一条: - config uhttpd 'web'
- list 'listen_http''0.0.0.0:81'
- option 'home' '/www'
- option 'index_page''index2.html'
- option 'cgi_prefix''/cgi-bin'
复制代码
保存退出 $/etc/init.d/uhttpd restart Ps:vi编辑器使用方法,不懂的自行百度 3.4设置定时任务设置定时任务,每分钟读取一次DHT11并更新网页文件 如图:
* * * * * sh /www/gettmp.sh
4.查看用浏览器登录 [路由器所在ip]:81 即可查看 效果如图
5.遇到的问题及解决方法:1.搭建uhttpd之后路由器登录页面进不去。 解决方法:一定要追加配置信息,不要在原有内容上修改。 2.linux收到信息乱码 解决方法:降低波特率 3.网页乱码 解决方法:添加网页编码标识 这只是基本的实现,更复杂一些可以在网页中加入js,在arduion上添加更多传感器等等。欢迎大家提出建议与意见。
顺便来一张Ubuntu美照:
|