Arduino與Air800開發板使用UART通信:傳輸DHT22傳感器數據
阿新 • • 發佈:2018-03-05
mic sta sam ext table per emp out 標識符
硬件介紹
Arduino Leonardo在數字引腳0(RX)和1(TX)進行串口通信時是使用“Serial1”,USB的串口通信使用的是“Serial”。在數字引腳0(RX)和1(TX)與USB是相互獨立的。
Air800使用UART1串口進行通信。
代碼
Arduino Leonardo代碼如下:
#include <inttypes.h> /* * LED */ unsigned int LED = 13; /* * DHT22配置程序 */ unsigned int DHT_PIN = 7; #defineDHT_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)
Arduino與Air800開發板使用UART通信:傳輸DHT22傳感器數據