加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

【RT-Thread作品秀】基于RT-Thread的數(shù)據(jù)采集

2020/12/20
688
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
方塊圖(2)
相關(guān)方案
  • 方案介紹
  • 相關(guān)文件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

概述:

       這是一個(gè)數(shù)據(jù)采集的裝置,本身沒有什么亮點(diǎn)。主要是基于RT-Thread操作系統(tǒng),驅(qū)動(dòng)NB模塊-BC26來實(shí)現(xiàn)數(shù)據(jù)的發(fā)送。值得一說的是RT-Thread本身有BC-26的驅(qū)動(dòng)包。不過這里并沒有使用,而是使用at-device軟件包來驅(qū)動(dòng)的BC26。因此稍微改一改內(nèi)部的代碼,就能驅(qū)動(dòng)其他的AT設(shè)備。話回正題,我使用at-thread的目的就是驅(qū)動(dòng)BC26建立TCPUDP連接,使得板卡采集得到的數(shù)據(jù)能發(fā)送到我電腦上的TCP Server。當(dāng)然,除了數(shù)據(jù)上傳之外,也能實(shí)現(xiàn)上位機(jī)控制板卡。還有則是在代碼中發(fā)現(xiàn)利用郵箱+消息隊(duì)列來進(jìn)行數(shù)據(jù)傳輸通信真的很爽。

開發(fā)環(huán)境:

  1. ART-Pi (主控)
  2. BC-26  (NB-IOT模塊)
  3. BHT11 (溫濕度傳感器)
  • RT-Thread版本
  1. RT-Thread V4.0.2
  • 開發(fā)工具及版本
  1. RT-Thread Studio V2.0.0 :RT-thread推出的IDE,免費(fèi)。
  2. Putty V0.73:開源免費(fèi)的一款工具,我純把他當(dāng)成串口助手使用
  3. 花生殼 V5 :內(nèi)網(wǎng)穿透工具。
  4. 網(wǎng)絡(luò)調(diào)試助手(MetAssist  V4.3.13):網(wǎng)上下的,應(yīng)該比較出名。

RT-Thread使用情況描述:

  • 內(nèi)核部分
  1. 調(diào)度器
  2. 消息隊(duì)列
  3. 郵箱
  • 組件部分
  1. at_device
  2. UART

硬件框架描述

先附圖一張:

       很簡單的一個(gè)框架,總共只有主控,傳感器,執(zhí)行器,以及比較重要的云平臺(tái),這四大部分。傳感器可以是任意傳感器,只要發(fā)送的數(shù)值種類不一次性超出兩種即可。執(zhí)行器我在這里使用了板載的LED燈充當(dāng)。云平臺(tái)則是利用網(wǎng)絡(luò)調(diào)試助手搭了一個(gè)TCP Server來充當(dāng)。由于我個(gè)人沒有固定外網(wǎng)IP,所以我如果直接使用網(wǎng)絡(luò)助手,是無法將ART采集得到的數(shù)據(jù)傳輸?shù)轿业碾娔X上的。因此我利用花生殼將我的IP映射到了外網(wǎng),使得板卡能連接到我創(chuàng)建的TCP Server上。

軟件框架說明

流程圖如下:

       本人并不是很會(huì)畫流程圖,所以辛苦大家看一看介紹吧。

       其實(shí)在這個(gè)板卡中是要燒兩套程序的,一套是bootloader負(fù)責(zé)初始化QSPI并且運(yùn)行QSPI內(nèi)的程序。所以這份程序是下載到片內(nèi)Flash的。另一份則是具體的功能添加的比較多的程序。他是運(yùn)行在QSPI中的。這兩個(gè)程序必須先運(yùn)行BootLoader否則QSPI中的程序是無法運(yùn)行的。而由于BootLoader的職責(zé)是讓程序從 0x08000000跳轉(zhuǎn)到0x90000000運(yùn)行所以,如果QSPI中沒有其他程序的話,Bootloader只會(huì)運(yùn)行一次,表現(xiàn)的現(xiàn)象就是只打印一個(gè)LOGO。

       其實(shí)在RT-Thread中其實(shí)有BC26的驅(qū)動(dòng)包,可以直接拿來用,不需要自己再對(duì)BC26進(jìn)行初始化,但是我這里使用的是at_device驅(qū)動(dòng)包,所以自己要寫一部分的代碼,進(jìn)行初始化。創(chuàng)建郵箱和消息隊(duì)列則是為了兩者相互配合一起實(shí)現(xiàn)發(fā)送同步消息的功能。

       數(shù)據(jù)采集線程和數(shù)據(jù)發(fā)送線程之間使用消息隊(duì)列+郵箱的方式實(shí)現(xiàn)消息同步,在這里數(shù)據(jù)采集線程可以有多個(gè),而數(shù)據(jù)發(fā)送線程我這設(shè)立了一個(gè)。發(fā)送線程會(huì)將接收到的信息都發(fā)送到云平臺(tái)中。

       數(shù)據(jù)接收則是利用at_device中的代碼實(shí)現(xiàn)的。利用內(nèi)部的代碼還可實(shí)現(xiàn)云平臺(tái)發(fā)送消息控制板卡上的LED燈或者其他執(zhí)行器。

軟件模塊說明

  • 消息隊(duì)列+郵箱的消息同步方式

       在使用消息隊(duì)列+郵箱的方式來進(jìn)行線程間消息同步的話需要先創(chuàng)建一個(gè)結(jié)構(gòu)體,一個(gè)動(dòng)態(tài)郵箱,一個(gè)消息隊(duì)列。然后對(duì)結(jié)構(gòu)體進(jìn)行填充后利用消息隊(duì)列發(fā)送出去,具體請(qǐng)看以下代碼示例:

//創(chuàng)建結(jié)構(gòu)體部分

struct msg  //消息隊(duì)列發(fā)送此結(jié)構(gòu)體的地址來實(shí)現(xiàn)線程間的同步
{
    char  *str;
    int vol;
    float data1;
    int data2;
    struct rt_mailbox* ack;
};

//創(chuàng)建動(dòng)態(tài)郵箱部分

rt_mailbox_t mail_box1 = RT_NULL;   //創(chuàng)建二氧化氮線程應(yīng)答郵箱控制塊
rt_mailbox_t mail_box2 = RT_NULL;   //創(chuàng)建二氧化硫線程應(yīng)答郵箱控制塊
rt_mailbox_t mail_box3 = RT_NULL;   //創(chuàng)建粉塵數(shù)據(jù)線程應(yīng)答郵箱控制塊
rt_mailbox_t mail_box4 = RT_NULL;   //創(chuàng)建備用線程郵箱控制塊

/**************創(chuàng)建多個(gè)應(yīng)答郵箱******************/
int move_mail_box_sample(void)
{
    mail_box1 = rt_mb_create("mail_box1", 1, RT_IPC_FLAG_FIFO);    //創(chuàng)建動(dòng)態(tài)郵箱1
    mail_box2 = rt_mb_create("mail_box2", 4, RT_IPC_FLAG_FIFO);    //創(chuàng)建動(dòng)態(tài)郵箱1
    mail_box3 = rt_mb_create("mail_box3", 4, RT_IPC_FLAG_FIFO);    //創(chuàng)建動(dòng)態(tài)郵箱1
    mail_box4 = rt_mb_create("mail_box1", 4, RT_IPC_FLAG_FIFO);    //創(chuàng)建動(dòng)態(tài)郵箱1
}

//填充發(fā)送

        struct msg msage;

        msage.str  = "NO2";
        msage.data1 = data1;
        msage.ack   = mail_box1;

        result = rt_mq_send(&mq,&msage, sizeof(struct msg));  //發(fā)送消息隊(duì)列
        if(result != RT_EOK)
        {
            rt_kprintf("消息發(fā)送失敗rn");
        }

//接收處理

LOG_I("準(zhǔn)備接收各個(gè)數(shù)據(jù)rn");
        data_send = at_create_resp(128, 0, rt_tick_from_millisecond(5000)); //分配內(nèi)存,并設(shè)定超時(shí)接收時(shí)間.準(zhǔn)備接收消息隊(duì)列
        if (data_send == RT_NULL)
            LOG_E("響應(yīng)結(jié)構(gòu)沒有內(nèi)存!");

        if(rt_mq_recv(&mq, &msage, sizeof(struct msg), RT_WAITING_FOREVER) == RT_EOK)        /**接收消息隊(duì)列**/
        {
            rt_kprintf("收到信息:%srn",msage.str);
            linshi = (int)msage.data1 *10;
            rt_kprintf("收到發(fā)送的消息%drn",linshi);

       抱歉,第一次寫,不知道重點(diǎn)在哪,先這樣吧。

演示效果

  • 圖片

  • 視頻

比賽感悟

         首先非常感謝舉辦方舉辦的這場比賽,這也是我第一次參加這樣的比賽,也正是此次比賽讓我認(rèn)識(shí)到了和同齡人的差距,也讓我感受到了這么多的奇思妙想。很多參賽者的構(gòu)思和實(shí)力令我嘆為觀止。我個(gè)人是沒有做過什么項(xiàng)目的,也沒進(jìn)行過系統(tǒng)的學(xué)習(xí),RT-thread對(duì)我來講也是一個(gè)接觸沒多久的新事物。我對(duì)其也只是會(huì)使用一些皮毛。從大一到現(xiàn)在也只是接觸一些PLC和電動(dòng)機(jī)。對(duì)于ARM都是憑著一份愛好去做。一直以來沒有什么眼界和想法。通過這次比賽我發(fā)現(xiàn),它的能力超出了我的想象。對(duì)我指明了一點(diǎn)前進(jìn)的方向。并且在使用RT-Thread的過程中,我發(fā)現(xiàn)編程并不像以前那么復(fù)雜了。在使用RT-Thread的時(shí)候我可以不再考慮怎樣實(shí)現(xiàn)一個(gè)模塊的驅(qū)動(dòng),而是將重點(diǎn)放到了邏輯上,這對(duì)來講還是比較新奇的。最后其實(shí)是想對(duì)官方人員道個(gè)歉的,畢竟這款作品由于時(shí)間的原因,并沒有進(jìn)行細(xì)改,而是一個(gè)趕出來的作品。沒有擺正心態(tài),真的很抱歉。

  • 代碼地址.txt
    描述:代碼地址
  • 簡單介紹.pdf
    描述:本文的PDF版本文件,內(nèi)容和您在網(wǎng)頁上所看內(nèi)容一直。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜