Arduino与Air800开发板使用UART通信:传输DHT22传感器数据
硬件介绍
Arduino Leonardo在数字引脚0(RX)和1(TX)进行串口通信时是使用“Serial1”,USB的串口通信使用的是“Serial”。在数字引脚0(RX)和1(TX)与USB是相互独立的。
Air800使用UART1串口进行通信。
注意:Arduino nano只有一个硬件串口,如果需要使用串口与其他单片机通信时,必须拔除USB线,使用跳线连接串口引脚
代码
Arduino Leonardo代码如下:
#include <inttypes.h> /* * LED */ unsigned int LED = 13; /* * DHT22配置程序 */ unsigned int DHT_PIN = 7; #define DHT_OK 1 #define DHT_ERR_CHECK 0 #define DHT_ERR_TIMEOUT -1 float humidity; float temperature; unsigned char DHT_read() { // BUFFER TO RECEIVE unsigned char bits[5] = {0,0,0,0,0}; unsigned char cnt = 7; unsigned char idx = 0; unsigned char sum; // REQUEST SAMPLE pinMode(DHT_PIN, OUTPUT); digitalWrite(DHT_PIN, LOW); delay(18); digitalWrite(DHT_PIN, HIGH); delayMicroseconds(40); pinMode(DHT_PIN, INPUT); // ACKNOWLEDGE or TIMEOUT unsigned int count = 10000; while(digitalRead(DHT_PIN) == LOW) if (count-- == 0) return DHT_ERR_TIMEOUT; count = 10000; while(digitalRead(DHT_PIN) == HIGH) if (count-- == 0) return DHT_ERR_TIMEOUT; // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT for (int i=0; i<40; i++) { count = 10000; while(digitalRead(DHT_PIN) == LOW) if (count-- == 0) return DHT_ERR_TIMEOUT; unsigned long t = micros(); count = 10000; while(digitalRead(DHT_PIN) == HIGH) if (count-- == 0) return DHT_ERR_TIMEOUT; if ((micros() - t) > 40) bits[idx] |= (1 << cnt); if (cnt == 0) // next byte? { cnt = 7; // restart at MSB idx++; // next byte! } else cnt--; } sum = bits[0]+bits[1]+bits[2]+bits[3]; if(bits[4] != sum) return DHT_ERR_CHECK; humidity = (float)((bits[0] << 8)+bits[1])/10; temperature = (float)((bits[2] << 8)+bits[3])/10; return DHT_OK; } void setup() { Serial.begin(115200,SERIAL_8N1); Serial1.begin(115200,SERIAL_8N1); pinMode(13,OUTPUT);//指示灯 pinMode(DHT_PIN,INPUT); digitalWrite(DHT_PIN, HIGH); } void loop() { unsigned long starttime = millis(); DHT_read(); //Serial.print(temperature); //Serial.print("-"); //Serial.println(humidity); Serial1.print(temperature); Serial1.print("-"); Serial1.print(humidity); Serial1.println("end");//数据发送完成后必须发送一个end字符串标记数据的结束 digitalWrite(LED,HIGH); delay(925); //Delay digitalWrite(LED,LOW); delay(925); //Delay }
Air800读取DHT22传感器的代码包括以下几个文件:cuart.lua,dht22.lua
cuart.lua代码如下:
module(...,package.seeall) --[[ 模块名称:“cuart应用”测试 模块功能:用于与arduino开发板通过uart通信 模块最后修改时间:2017.02.16 ]] --串口ID,1对应uart1 --如果要修改为uart2,把UART_ID赋值为2即可 local UART_ID = 1 --模拟输入 local ADC_ID = 0 --结束标识符,用于uart通信结束标志 local endflag = "end" data = "0-0" --[[ 函数名:read 功能 :读取串口接收到的数据 参数 :无 返回值:无 ]] local function read() --底层core中,串口收到数据时: --如果接收缓冲区为空,则会以中断方式通知Lua脚本收到了新数据; --如果接收缓冲器不为空,则不会通知Lua脚本 --所以Lua脚本中收到中断读串口数据时,每次都要把接收缓冲区中的数据全部读出,这样才能保证底层core中的新数据中断上来,此read函数中的while语句中就保证了这一点 local tempdata="" local flag = false while true do local tmp = uart.read(UART_ID,"*l",0) if not tmp or string.len(tmp) == 0 then break end flag = true tempdata = tempdata..tmp print("get dht22 tmp: ",tmp) --print("get dht22 tempdata: ",tempdata) --打开下面的打印会耗时 --print("read",data,common.binstohexs(data)) --dht22Get(data) --查找结束字符串是否存在,如果存在,则完成数据的一次读取 if string.find(tempdata,endflag) then print("get dht22 find:",tempdata) break end end index1,index2=string.find(tempdata,endflag) if flag==true and index1 ~= nil then print("get dht22 index:",index1) if index1>0 then --删除末尾的结束标识字符串 data = string.sub(tempdata,0,index1-1) end end end function getTemperature() local tab = split(data,"-") print("get dht22 temperature:",tab[1]) return tab[1] end function getHumidity() local tab = split(data,"-") print("get dht22 humidity:",tab[2]) return tab[2] end --字符串分割函数 --传入字符串和分隔符,返回分割后的table function split(str, delimiter) if str==nil or str=='' or delimiter==nil then return nil end local result = {} for match in (str..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match) end return result end --保持系统处于唤醒状态,此处只是为了测试需要,所以此模块没有地方调用pm.sleep("test")休眠,不会进入低功耗休眠状态 --在开发“要求功耗低”的项目时,一定要想办法保证pm.wake("test")后,在不需要串口时调用pm.sleep("test") pm.wake("test") --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据 sys.reguart(UART_ID,read) --配置并且打开串口 uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
dht22.lua代码如下:
require"cuart" module(...,package.seeall) --[[ 模块名称:“dht22应用”测试 模块功能:测试dht22.lua的接口 模块最后修改时间:2017.02.16 ]] --temperature温度 humidity湿度 temperature = "0" humidity = "0" --[[ 函数名:print 功能 :打印接口,此文件中的所有打印都会加上dht22前缀 参数 :无 返回值:无 ]] local function print(...) _G.print(" dht22 ",...) end --[[ 函数名:dht22Get 功能:读取温湿度数据 参数:无 返回值:无 ]] function dht22Get() temperature = cuart.getTemperature() humidity = cuart.getHumidity() print("dht22Get : ",temperature," ",humidity) end --[[ 函数名:returnTemperature 功能:返回温度 参数:无 返回值:无 ]] function returnTemperature() return temperature end --[[ returnHumidity 功能:返回湿度 参数:无 返回值:无 ]] function returnHumidity() return humidity end --[[ 函数:dht22Init 功能:初始化dht22 参数:无 返回值:无 ]] local function dht22Init() end sys.timer_start(dht22Init,2000) sys.timer_loop_start(dht22Get,2000)
联系方式:wuchaodzxx@126.com