1. 程式人生 > >Arduino與Air800開發板使用UART通信:傳輸DHT22傳感器數據

Arduino與Air800開發板使用UART通信:傳輸DHT22傳感器數據

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;

#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)

Arduino與Air800開發板使用UART通信:傳輸DHT22傳感器數據