0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux+Qt驅(qū)動dht11溫濕度傳感器實(shí)驗(yàn)過程遇到的問題及解決辦法

CHANBAEK ? 來源:嵌入式大本營 ? 作者:小小飛飛哥 ? 2023-05-23 15:54 ? 次閱讀

最近想要做一個基于嵌入式Linux+Qt驅(qū)動dht11溫濕度傳感器的實(shí)驗(yàn)。 想要實(shí)現(xiàn)的功能是通過野火的imx6ull開發(fā)板控制dht11傳感器,然后使用Qt做一個上位機(jī),在上位機(jī)上面把數(shù)據(jù)顯示出來。

這里把我在做的過程中遇到的一些問題先記錄一下,免得日后忘記。

在網(wǎng)上關(guān)于這方面的資料不多,大多數(shù)都是基于stm32來控制的,所以在做的過程中遇到一些問題解決起來也比較麻煩。

下面簡述一下我做的過程及遇到的問題

首先查看原理圖看使用到了哪個管腳,然后在設(shè)備樹里添加相應(yīng)的節(jié)點(diǎn)。 這里用到了gpio子系統(tǒng)和pinctrl子系統(tǒng)。

接著參考網(wǎng)上的相關(guān)代碼,進(jìn)行了改寫,因?yàn)檫@個傳感器的時序也比較簡單,所以有關(guān)時序的部分基本上可以不用改。

遇到的第一個問題 :寫好驅(qū)動后,在應(yīng)用程序中使用read函數(shù)來讀取設(shè)備文件,如果只讀取一次,可以得到結(jié)果,但是如果使用while(1)來嘗試反復(fù)讀取,就會失敗。

按照手冊來說,只要兩次讀取間隔超過1秒就行了,但是我使用while(1)即使休眠sleep(3)之類的依然會在第二次讀取的失敗,而且整個函數(shù)會卡死在讀取這里,這個進(jìn)程怎么也殺不死,kill -9殺不死,kill -15 也殺不死。 這里很快把問題定位在了read函數(shù)。

后面,我在代碼中做了如下修改:本來在驅(qū)動程序里面有使用while函數(shù)來等待管腳電平的跳變,我認(rèn)為這樣是不合理的,因?yàn)闆]有超時處理,容易卡死,所以我加了一個計數(shù),當(dāng)超過一定計數(shù)值時就跳出while循環(huán)。 后來這個問題就解決了。 雖然我是不確定一開始是不是因?yàn)檫@個原因,因?yàn)橹虚g過了挺久的時間,我不確定有沒有別的因素存在 ,總之后來就不會卡死了,可以使用while循環(huán)來反復(fù)讀取。

遇到的第二個問題 :在解決了上面的問題之后,insmod安裝驅(qū)動,可以工作,然后rmmod卸載驅(qū)動,再次insmod安裝驅(qū)動就會發(fā)現(xiàn)安裝不上去。

圖片

使用dmesg命令查看內(nèi)核打印的信息,比較容易猜到應(yīng)該是卸載驅(qū)動的時候沒有卸載干凈,然后仔細(xì)看了一下驅(qū)動,在結(jié)合網(wǎng)上查找資料,發(fā)現(xiàn)我的驅(qū)動里沒有寫remove函數(shù)。 所以我添加了remove函數(shù),在remove函數(shù)里注銷掉那些東西。 而且要注意注銷的順序,和注冊是相反的,比如在驅(qū)動中最先是申請?jiān)O(shè)備號,在注銷的時候就是最后注銷它,否則會出現(xiàn)很多錯誤,包括段錯誤 。

遇到的第三個問題 :在解決了第二個問題之后,已經(jīng)可以反復(fù)卸載和安裝驅(qū)動了,但是發(fā)現(xiàn)一個問題,就是在第二次安裝的時候,總是會出現(xiàn)gpio_request失敗,按道理講我已經(jīng)在remove函數(shù)里使用gpio_free釋放掉了,不應(yīng)該會失敗才對,后來發(fā)現(xiàn)是在gpio_request的時候還沒拿到引腳號, 全局變量沒有初始化默認(rèn)是0,所以request的是0,后來通過一個函數(shù)(忘記叫什么了,總之是gpio子系統(tǒng)的那些函數(shù))從設(shè)備樹中拿到引腳號,這個引腳號是2,所以后面free的是2,也就是說request和free的不是同一個引腳,當(dāng)然會出錯了。

這屬于粗心的錯,把這個問題解決了之后,這個驅(qū)動總算可以正常工作了,也完全可以反復(fù)卸載和安裝。

遇到的第四個問題 :在第一個問題里提到我在while里加了超時處理,防止一直死等卡死。 最開始我是這樣寫的

while(gpio_get_value(gpio)==0 &&cnt<6)< span="">
{
       cnt++;
       udelay(10);
}

這里通過cnt來防止while死掉,也就是說最多等待60微秒就退出循環(huán)。 但是直覺告訴我這樣不好 ,因?yàn)橹虚g延時10個微秒太長了,導(dǎo)致響應(yīng)性不好。 所以我改成了這樣:

while(gpio_get_value(gpio)==0 &&cnt<60)< span="">
{
       cnt++;
       udelay(1);
}

這樣的實(shí)時響應(yīng)性好多了,測出的數(shù)據(jù)也更準(zhǔn)確了。

到這里為止,驅(qū)動就基本沒有問題了,使用應(yīng)用程序來讀取設(shè)備文件,也基本沒問題,就是有時數(shù)據(jù)校驗(yàn)會失敗,但是測出的數(shù)據(jù)基本可以,而且是有變化的,說明還是比較可靠的。

接下來是把在Qt里把數(shù)據(jù)讀出來并且顯示, 下面說一下調(diào)試Qt遇到的問題 。

在寫完驅(qū)動之后,很自然會寫一個.c的測試程序,用來驗(yàn)證驅(qū)動是否能正常工作,很幸運(yùn),一下子就成功了,于是我認(rèn)為在Qt中也是類似,直接用Qt里的read相關(guān)的函數(shù)去讀取設(shè)備文件就好了,但是沒想到在這個環(huán)節(jié)卡了我最久

起初,我使用Qfile 里的readAll方法去讀,發(fā)現(xiàn)控制臺會刷屏(刷屏就是驅(qū)動中的read一直被調(diào)用而打印出的信息刷屏),一讀就停不下來,而且后面的程序也執(zhí)行不了,也就是說函數(shù)沒有返回。

我不太清楚是什么原因,只能換一個函數(shù),接著我嘗試了readLine方法,一樣刷屏,接著嘗試read方法,這個方法和C語言的read類似,參數(shù)里要填讀幾個字節(jié),這和前面兩個不太一樣,所以我想,這回應(yīng)該不會刷屏了吧。

結(jié)果確實(shí)沒有刷屏,但是讀取的數(shù)據(jù)是錯的,體現(xiàn)出來的就是從機(jī)無響應(yīng)(這時我還沒有注意這個問題)。

雖然說數(shù)據(jù)是錯的,但是好歹沒有刷屏了,只要再想一想為什么會讀出錯的數(shù)據(jù)就行了。

我想到Qt里還有一種讀文件的方式,就是使用數(shù)據(jù)流Datastream,但是效果和上面的read一樣。

接著我開始思考刷屏的原因,百度了一下,有人說要在末尾加一個"\\0",嘗試,未果。

接著,我在一些技術(shù)交流群尋求幫助,因?yàn)榇丝涛业膯栴}確實(shí)很奇怪,在自己寫的.c測試程序里,調(diào)用read讀設(shè)備文件是完全沒有問題的,現(xiàn)在唯一的區(qū)別就是在Qt中讀,驅(qū)動又不變,為什么讀出來的是錯的呢? 我懷疑是Qt的read對數(shù)據(jù)的解析可能和C語言里不太一樣,因?yàn)榇丝淌怯袛?shù)據(jù)的, 會不會是因?yàn)樽止?jié)對齊之類的原因?qū)е陆馕鰯?shù)據(jù)不對呢 ? 群里大佬建議先排查一下源數(shù)據(jù)對不對。

于是我拿出了我許久沒用過的邏輯分析儀來分析波形,我先觀察了我的.c測試程序的波形,和手冊描述的基本一致。 接著觀察Qt里read時的波形,一觀察發(fā)現(xiàn)根本沒有波形,正常情況應(yīng)該是主機(jī)先拉低18ms,再拉高,等待從機(jī)應(yīng)答。 而我觀察到的波形是主機(jī)拉低了30多ms才拉高,再看一下終端打印的數(shù)據(jù), 發(fā)現(xiàn)驅(qū)動里的read被調(diào)用了兩次 。

這時,我已經(jīng)猜到原因了,**之所以數(shù)據(jù)不對,是因?yàn)轵?qū)動里的read被連續(xù)調(diào)用了兩次,導(dǎo)致時序根本就不對,從機(jī)沒有應(yīng)答。 **

再觀察之前使用readAll函數(shù)來讀取,雖然會刷屏,但是偶爾能捕捉到有效的波形。 這已經(jīng)很能說明問題了,就是要解決驅(qū)動里的read為什么會被調(diào)用多次這個問題,正常應(yīng)該是應(yīng)用層調(diào)用一次read,驅(qū)動里的read就被調(diào)用一次。

關(guān)于這個問題,這篇文章講的不錯,使用cat讀取和echo寫內(nèi)核文件節(jié)點(diǎn)的一些問題

這篇文章對我還是有很大的啟發(fā)。 總之就是驅(qū)動中read 的返回值會影響它是否被多次調(diào)用。

先來看一下驅(qū)動中read函數(shù)的參數(shù)和返回值

ssize_t dht11_chr_dev_read(struct file *filp, char __user *buf, size_t count, loff_t *fops)

我經(jīng)過很多實(shí)驗(yàn),發(fā)現(xiàn)以下規(guī)律:

對于Qt中的readAll、readLine函數(shù),不管驅(qū)動返回什么,readAll都會刷屏,readLine會調(diào)用驅(qū)動多次。

對于Qt中的read函數(shù),如果驅(qū)動返回的是count,將不會刷屏,否則,也會刷屏。 (這一點(diǎn)確實(shí)很奇怪)

更奇怪的是同樣的實(shí)驗(yàn)條件,在多次實(shí)驗(yàn)中甚至可能得到不同的結(jié)果,但是上面這幾點(diǎn)結(jié)論是反復(fù)實(shí)驗(yàn)得到的結(jié)論。

最后,我發(fā)現(xiàn)可以在Qt中使用C和C++混合編程,方法就是使用

extern "C"{
#include    //這里寫用到的C頭文件
}

然后在用到的C語言的函數(shù)前加兩個冒號,比如

::read(fd,buf,sizeof(buf));

這樣就可以直接調(diào)用C語言代碼了,而且發(fā)現(xiàn)效果還不錯,比Qt中的read系列函數(shù)穩(wěn)定。 (實(shí)驗(yàn)次數(shù)有限,從我觀察到的結(jié)果來看是這樣)。

所以,最終的解決方法就是:

方法一 :使用Qfile 的read函數(shù),使用方法和C語言類似,可以正確讀出數(shù)據(jù),但是要注意,如果使用這個函數(shù),驅(qū)動中的read要返回參數(shù)列表中的count,否則會刷屏。

方法二 :直接使用混合編程的方式,調(diào)用C語言中的read ,這樣測出的效果是最好的,而且不必要求驅(qū)動中的read 返回count,直接返回實(shí)際讀取的字節(jié)即可,也就是copy_to_user的字節(jié)數(shù)。

驅(qū)動代碼參考了Linux下DHT11驅(qū)動編程,以及測試程序

在此基礎(chǔ)上修改得到

#include 
#include 
#include 
#include 
#include 


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#include 








/*------------------字符設(shè)備內(nèi)容----------------------*/
#define DEV_NAME            "dht11"
#define DEV_CNT                 (1)


typedef struct
{
  uint8_t  humi_int;   //濕度的整數(shù)部分
  uint8_t  humi_deci;   //濕度的小數(shù)部分
  uint8_t  temp_int;   //溫度的整數(shù)部分
  uint8_t  temp_deci;   //溫度的小數(shù)部分
  uint8_t  check_sum;   //校驗(yàn)和





} DHT11_Data_TypeDef;




//定義字符設(shè)備的設(shè)備號
static dev_t dht11_devno;
//定義字符設(shè)備結(jié)構(gòu)體chr_dev
static struct cdev dht11_chr_dev;




struct class *class_dht11;  //保存創(chuàng)建的類
struct device *device;      // 保存創(chuàng)建的設(shè)備
struct device_node  *dht11_device_node; //dht11的設(shè)備樹節(jié)點(diǎn)


int dht11_data_pin;         // 保存獲取得到的dht11引腳編號


DHT11_Data_TypeDef DHT11_Data;


//從DHT11讀取1byte數(shù)據(jù),MSB先行
uint8_t DHT11_ReadByte(void)
{
  uint8_t i, temp=0;

    int cnt=0;
  for(i=0;i<8;i++)    
  {   
    /*每bit以50us低電平標(biāo)置開始,輪詢直到從機(jī)發(fā)出 的50us 低電平 結(jié)束*/
    while(gpio_get_value(dht11_data_pin) == 0  && cnt<60)
        {
            cnt++;
            udelay(1);
        }
        cnt =0;
    /*DHT11 以26~28us的高電平表示“0”,以70us高電平表示“1”,
     *通過檢測 x us后的電平即可區(qū)別這兩個狀 ,x 即下面的延時 
     */
    udelay(40); //延時x us 這個延時需要大于數(shù)據(jù)0持續(xù)的時間即可         

    if(gpio_get_value(dht11_data_pin))/* x us后仍為高電平表示數(shù)據(jù)“1” */
    {
      /* 等待數(shù)據(jù)1的高電平結(jié)束 */
      while(gpio_get_value(dht11_data_pin) && cnt<50)
            {
                cnt++;
                udelay(1);
            }

      temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行 
    }
    else   // x us后為低電平表示數(shù)據(jù)“0”
    {         
      temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
    }
  }


  return temp;

}


/**
 * 一次完整的數(shù)據(jù)傳輸為40bit,高位先出
 * 8bit 濕度整數(shù) + 8bit 濕度小數(shù) + 8bit 溫度整數(shù) + 8bit 溫度小數(shù) + 8bit 校驗(yàn)和的末8位
 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{
  //  int ret;
    int cnt=0;

    printk(KERN_ERR"DHT11_Read_TempAndHumidity 被調(diào)用\\n");

  /*主機(jī)拉低*/
  gpio_direction_output(dht11_data_pin, 0);

  /*延時18ms,(>=18ms)*/
  mdelay(18);

  /*總線拉高 主機(jī)延時30us*/
  gpio_direction_output(dht11_data_pin, 1);

  udelay(30);   //延時30us,(20~40us)

  /*主機(jī)設(shè)為輸入 判斷從機(jī)響應(yīng)信號*/ 
  gpio_direction_input(dht11_data_pin);

  /*判斷從機(jī)是否有低電平響應(yīng)信號 如不響應(yīng)則跳出,響應(yīng)則向下運(yùn)行*/   
  if(gpio_get_value(dht11_data_pin) == 0)     
  {
    /*輪詢直到從機(jī)發(fā)出 的80us 低電平 響應(yīng)信號結(jié)束*/  
    while(gpio_get_value(dht11_data_pin) == 0 && cnt<100)
        {
            cnt++;
            udelay(1);
        }
        cnt = 0;
    /*輪詢直到從機(jī)發(fā)出的 80us 高電平 標(biāo)置信號結(jié)束*/
    while(gpio_get_value(dht11_data_pin) && cnt<100)
        {
            cnt++;
            udelay(1);
        }

    /*開始接收數(shù)據(jù)*/   
    DHT11_Data->humi_int= DHT11_ReadByte();

    DHT11_Data->humi_deci= DHT11_ReadByte();

    DHT11_Data->temp_int= DHT11_ReadByte();

    DHT11_Data->temp_deci= DHT11_ReadByte();

    DHT11_Data->check_sum= DHT11_ReadByte();




    /*讀取結(jié)束,引腳改為輸出模式,主機(jī)拉高*/
    gpio_direction_output(dht11_data_pin, 1);


        printk("humi: %d.%d, temp: %d.%d,check:%d\\n",DHT11_Data->humi_int,\\
                    DHT11_Data->humi_deci,DHT11_Data->temp_int,DHT11_Data->temp_deci,DHT11_Data->check_sum);
    /*檢查讀取的數(shù)據(jù)是否正確*/
    //DHT11_Data->check_sum的正確的結(jié)果是溫濕度總和的末8位,結(jié)構(gòu)體也有定義check_sum為uint8_t類型
    if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
      return 0;
    else {
       printk(KERN_ERR " ERROR 數(shù)據(jù)校驗(yàn)失敗");
       return -1;
    }

  }
  else
    {
        printk(KERN_ERR "ERROR 從機(jī)無響應(yīng)");
        return -1;
    }


}




/*字符設(shè)備操作函數(shù)集,open函數(shù)*/
static int dht11_chr_dev_open(struct inode *inode, struct file *filp)
{
  printk("\\n open form driver \\n");
    return 0;
}


/*字符設(shè)備操作函數(shù)集,write函數(shù)*/
static ssize_t dht11_chr_dev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{



  unsigned char write_data; //用于保存接收到的數(shù)據(jù)


  int error = copy_from_user(&write_data, buf, cnt);
  if(error < 0) {
    return -1;
  }


  return 0;
}




ssize_t dht11_chr_dev_read(struct file *filp, char __user *buf, size_t count, loff_t *fops)
{




  int size=sizeof(DHT11_Data_TypeDef);
  printk(KERN_ERR " count: %d, fops: %lld\\n", count, *fops);

  printk(KERN_ERR "--------%s---------\\n",__func__);

    /*調(diào)用DHT11_Read_TempAndHumidity讀取溫濕度,若成功則輸出該信息*/
  if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) != 0)
  {
    printk(KERN_ERR "Read DHT11 ERROR!\\r\\n");
  }
  else
  {
    if(copy_to_user(buf, &DHT11_Data, size)!=0)
    {
      printk(KERN_ERR " 拷貝失敗\\n");
//        return 0;
    }
    else
      printk(KERN_ERR " 拷貝成功\\n");
  }

    // ret= simple_read_from_buffer(buf, count, fops, &DHT11_Data, sizeof(DHT11_Data_TypeDef));
  //   *fops=0;

  return count;
//    return size;
}






/*字符設(shè)備操作函數(shù)集*/
static struct file_operations  dht11_chr_dev_fops = 
{
  .owner = THIS_MODULE,
    .open = dht11_chr_dev_open,
  .write = dht11_chr_dev_write,
  .read = dht11_chr_dev_read,
};






/*----------------平臺驅(qū)動函數(shù)集-----------------*/
static int dht11_probe(struct platform_device *pdv)
{

  int ret = 0;  //用于保存申請?jiān)O(shè)備號的結(jié)果

  printk(KERN_EMERG "\\t  match successed  \\n");

    /*獲取dht11的設(shè)備樹節(jié)點(diǎn)*/
    dht11_device_node = of_find_node_by_path("/dht11");
    if(dht11_device_node == NULL)
    {
        printk(KERN_EMERG "\\t  get dht11 failed!  \\n");
    }


    dht11_data_pin = of_get_named_gpio(dht11_device_node, "dht11_data_pin", 0);



    printk("dht11_data_pin = %d\\n ", dht11_data_pin);


  ret=gpio_request(dht11_data_pin, "DQ_OUT");
    if(ret==0)
    {
        printk(KERN_ERR "gpio request success\\n");
    }
    else
    {
        printk(KERN_ERR "gpio request failed \\n");

    }




    gpio_direction_output(dht11_data_pin, 1);





  /*---------------------注冊 字符設(shè)備部分-----------------*/


  //第一步
    //采用動態(tài)分配的方式,獲取設(shè)備編號,次設(shè)備號為0,
    //設(shè)備名稱為rgb-leds,可通過命令cat  /proc/devices查看
    //DEV_CNT為1,當(dāng)前只申請一個設(shè)備編號
    ret = alloc_chrdev_region(&dht11_devno, 0, DEV_CNT, DEV_NAME);
    if(ret < 0){
        printk("fail to alloc dht11_devno\\n");
        goto alloc_err;
    }
    //第二步
    //關(guān)聯(lián)字符設(shè)備結(jié)構(gòu)體cdev與文件操作結(jié)構(gòu)體file_operations
  dht11_chr_dev.owner = THIS_MODULE;
    cdev_init(&dht11_chr_dev, &dht11_chr_dev_fops);
    //第三步
    //添加設(shè)備至cdev_map散列表中
    ret = cdev_add(&dht11_chr_dev, dht11_devno, DEV_CNT);
    if(ret < 0)
    {
        printk(KERN_ERR"fail to add cdev\\n");
        goto add_err;
    }


  //第四步
  /*創(chuàng)建類 */
  class_dht11 = class_create(THIS_MODULE, DEV_NAME);
    if(class_dht11==NULL)
    {
        printk(KERN_ERR"class creat failed\\n");
        goto add_class;
    }
  /*創(chuàng)建設(shè)備*/
  device = device_create(class_dht11, NULL, dht11_devno, NULL, DEV_NAME);
    if(device==NULL)
    {
        printk(KERN_ERR"device creat failed\\n");
        goto add_device;
    }
  return 0;


 //   device_destroy(class_dht11,dht11_devno);
add_device:
    class_destroy(class_dht11);
    printk(KERN_EMERG "\\t  刪除類成功  \\n");
add_class:
    cdev_del(&dht11_chr_dev);
    printk(KERN_EMERG "\\t  刪除設(shè)備成功  \\n");


add_err:
    //添加設(shè)備失敗時,需要注銷設(shè)備號
    unregister_chrdev_region(dht11_devno, DEV_CNT);
  printk(KERN_EMERG"\\n 注銷設(shè)備號成功! \\n");
alloc_err:


  return -1;


}


int  dht11_remove(struct platform_device *dht11_dev)
{
    printk(KERN_EMERG"開始釋放資源");
    gpio_free(dht11_data_pin);
    device_destroy(class_dht11,dht11_devno);
    class_destroy(class_dht11);
    cdev_del(&dht11_chr_dev);
    unregister_chrdev_region(dht11_devno, DEV_CNT);
    printk(KERN_EMERG"釋放資源完畢");
    return 0;
}




static const struct of_device_id dht11[] = {
{ .compatible = "dht11"},
  { /* sentinel */ }
};


/*定義平臺設(shè)備結(jié)構(gòu)體*/
struct platform_driver dht11_platform_driver = {
  .probe = dht11_probe,
    .remove = dht11_remove,
  .driver = {
    .name = "dht11-platform",
    .owner = THIS_MODULE,
    .of_match_table = dht11,
  }
};






/*
*驅(qū)動初始化函數(shù)
*/
static int __init dht11_platform_driver_init(void)
{
  int DriverState;

  DriverState = platform_driver_register(&dht11_platform_driver);

  printk(KERN_EMERG "\\tDriverState is %d\\n",DriverState);
  return 0;
}




/*
*驅(qū)動注銷函數(shù)
*/
static void __exit led_platform_driver_exit(void)
{


  printk(KERN_EMERG "dht11 module exit!\\n");


  platform_driver_unregister(&dht11_platform_driver);  
}




module_init(dht11_platform_driver_init);
module_exit(led_platform_driver_exit);


MODULE_LICENSE("GPL");
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5045

    文章

    18816

    瀏覽量

    298459
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207895
  • STM32
    +關(guān)注

    關(guān)注

    2257

    文章

    10828

    瀏覽量

    352444
  • 溫濕度傳感器
    +關(guān)注

    關(guān)注

    5

    文章

    562

    瀏覽量

    35556
  • Qt
    Qt
    +關(guān)注

    關(guān)注

    1

    文章

    300

    瀏覽量

    37596
收藏 人收藏

    評論

    相關(guān)推薦

    基于arduino的dht11溫濕度傳感器的使用

    本文介紹了DHT11溫濕度傳感器電氣特性、DHT11封裝形式及接口說明與典型應(yīng)用電路,其次介紹了DHT11
    發(fā)表于 01-22 15:50 ?4.4w次閱讀
    基于arduino的<b class='flag-5'>dht11</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>的使用

    DHT11數(shù)字式溫濕度傳感器的應(yīng)用性研究

    基于DHT11溫濕度傳感器具有測量精度高、響應(yīng)速度快、抗干擾能力強(qiáng)等優(yōu)點(diǎn)。通過介紹DHT11數(shù)字式溫濕度
    發(fā)表于 11-06 16:28

    【眾拳】基于STM8的DHT11溫濕度傳感器實(shí)驗(yàn) 附代碼

    ~50us)時間,作為響應(yīng)信號,然后DHT11拉高數(shù)據(jù)線,保持t4(40~50us)時間后,開始輸出數(shù)據(jù)。DHT11 溫濕度傳感器時序圖【眾拳】劍齒虎STM8開發(fā)板的
    發(fā)表于 12-07 09:14

    DHT11溫濕度傳感器介紹

    DHT11溫濕度傳感器介紹,1.實(shí)物原理圖2.模塊說明2.1 DHT11產(chǎn)品概述DHT11數(shù)字溫濕度
    發(fā)表于 07-21 09:04

    DHT11溫濕度傳感器

    DHT11溫濕度傳感器1. DHT11簡介2. 硬件設(shè)計3. 軟件設(shè)計3.1 STM32CubeMX設(shè)置3.2 MDK-ARM編程4. 下載驗(yàn)證
    發(fā)表于 08-11 06:04

    DHT11數(shù)字溫濕度傳感器的數(shù)據(jù)通訊過程是怎樣的

    DHT11數(shù)字溫濕度傳感器是什么?有何優(yōu)點(diǎn)呢?DHT11數(shù)字溫濕度傳感器的數(shù)據(jù)通訊
    發(fā)表于 01-18 06:07

    DHT11溫濕度傳感器簡介

    DHT11溫濕度傳感器1、DHT11簡介DHT11數(shù)字溫濕度
    發(fā)表于 02-16 06:55

    DHT11數(shù)字溫濕度傳感器的相關(guān)資料推薦

    STM32采集DHT11溫濕度關(guān)于DHT11相關(guān)參數(shù)代碼篇接線和實(shí)驗(yàn)結(jié)果總結(jié)關(guān)于DHT11DHT11是一款數(shù)字
    發(fā)表于 02-21 07:34

    DHT11數(shù)字溫濕度傳感器產(chǎn)品介紹

    DHT11數(shù)字溫濕度傳感器產(chǎn)品介紹 DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號輸出的
    發(fā)表于 02-26 17:19 ?256次下載

    DHT11數(shù)字式溫濕度傳感器的應(yīng)用性研究

    基于DHT11溫濕度傳感器具有測量精度高、響應(yīng)速度快、抗干擾能力強(qiáng)等優(yōu)點(diǎn)。通過介紹DHT11數(shù)字式溫濕度
    發(fā)表于 07-25 17:03 ?216次下載
    <b class='flag-5'>DHT11</b>數(shù)字式<b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>的應(yīng)用性研究

    數(shù)字溫濕度傳感器 DHT11

    數(shù)字溫濕度傳感器 DHT11 ?相對濕度和溫度測量 ?全部校準(zhǔn),數(shù)字輸出 ?卓越的長期穩(wěn)定性 ?無需額外部件 ?超長的信號傳輸距離 ?超低能耗 ?4 引腳安裝 ?完全互換
    發(fā)表于 12-02 11:06 ?4次下載

    溫濕度傳感器DHT11驅(qū)動程序

    本文開始介紹了驅(qū)動程序的定義與驅(qū)動程序的作用,其次介紹了DHT11溫濕度傳感器特性、引腳說明與封裝詳情,最后介紹了
    發(fā)表于 01-22 16:52 ?5.3w次閱讀
    <b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>DHT11</b><b class='flag-5'>驅(qū)動</b>程序

    Arduino的實(shí)驗(yàn)例程之溫濕度傳感器DHT11實(shí)驗(yàn)

    本文檔的主要內(nèi)容詳細(xì)介紹的是Arduino的實(shí)驗(yàn)例程之溫濕度傳感器DHT11實(shí)驗(yàn)免費(fèi)下載。
    發(fā)表于 03-01 11:42 ?30次下載

    溫濕度傳感器DHT11的STM32驅(qū)動實(shí)現(xiàn)

    溫濕度傳感器DHT11的STM32驅(qū)動實(shí)現(xiàn)
    發(fā)表于 11-25 20:36 ?74次下載
    <b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>DHT11</b>的STM32<b class='flag-5'>驅(qū)動</b>實(shí)現(xiàn)

    使用ESP8266驅(qū)動DHT11溫濕度傳感器

    DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號輸出的溫濕度綜合傳感器,在Arduino提高篇中已對其進(jìn)行了介紹,本篇使用ESP8266來
    的頭像 發(fā)表于 05-19 14:20 ?5741次閱讀
    使用ESP8266<b class='flag-5'>驅(qū)動</b><b class='flag-5'>DHT11</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>