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)

 

posted @ 2018-03-05 19:49  且听风吟-wuchao  阅读(1699)  评论(0编辑  收藏  举报