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

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

【RT‐Thread 作品秀】基于RT‐Thread的網(wǎng)絡(luò)照相機

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

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

虛擬商品不可退

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

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

【RT-Thread 作品秀】基于RT-Thread的網(wǎng)絡(luò)照相機

作者:吳頂頂

概述

隨著科技的進步和互聯(lián)網(wǎng)的發(fā)展,基于物聯(lián)網(wǎng)的可拍照設(shè)備也越來越多的融入到人們的生活中來,例如在超市中,管理者利用拍照設(shè)備定時抓取貨架照片,分析貨物狀態(tài),并補充、優(yōu)化貨物擺放;在酒吧里,管理者會利用拍照設(shè)備定時抓拍酒架照片,傳送到網(wǎng)絡(luò)平臺供大眾瀏覽,以招攬更多顧客。本網(wǎng)絡(luò)照相機基于STM32H7+RTThread平臺,采集攝像頭數(shù)據(jù),并通過無線網(wǎng)絡(luò)傳送到服務(wù)器,提供SD卡配網(wǎng)、手動拍攝、定時拍攝、照片推送等功能,并提供windows上位機提供控制和照片顯示功能。

主要功能有:

格式化sd卡:格式化sd卡,但是會保留網(wǎng)絡(luò)配置文件,其他文件全部刪除
設(shè)備重啟:重啟設(shè)備
實時拍照:發(fā)送指令給照相機,照相機拍照,并把照片回傳
定時拍照:照相機依據(jù)下發(fā)的拍照時間,在時間到達時拍攝一張照片,并傳給服務(wù)器
按鍵拍照:點擊板上用戶按鈕,拍攝一張照片,并傳給服務(wù)器
定時任務(wù):可以新建/刪除/查詢定時拍照任務(wù),任務(wù)存儲在sd卡中,重啟有效

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

硬件:ART-PI(STM32H750主控)+ OV2640模組
RT-Thread版本:4.0.3
SDK 版本:1.0.1
開發(fā)工具及版本:RT-Thread Studio 1.1.5, Qt5.14.0

RT-Thread使用情況概述

內(nèi)核部分:調(diào)度器,信號量,互斥鎖,內(nèi)存管理

調(diào)度器:多任務(wù)調(diào)度
信號量:用于喚醒對應(yīng)任務(wù)
互斥鎖:用于互斥資源獨占訪問
內(nèi)存管理:動態(tài)內(nèi)存申請與釋放

組件部分:虛擬文件系統(tǒng),IPC,I2C,RTC,NTP

虛擬文件系統(tǒng):文件操作,sd卡、照片文件
IPC:mqtt發(fā)送數(shù)據(jù)需要
I2C:配置攝像頭模塊需要
RTC和NTP:同步時間

軟件包部分:paho mqtt,cJSON,netutils

pahomqtt:用于和服務(wù)器通信
cJSON:解析、封裝mqtt消息
netutils:NTP網(wǎng)絡(luò)對時

其他:base64

用于將圖片文件轉(zhuǎn)換成字符串,便于mqtt傳輸

硬件框架

總體的硬件框架如下圖所示:

 

本網(wǎng)絡(luò)攝像機硬件結(jié)果較為簡單,即art-pi連接一個攝像頭模組,art-pi板上用到了AP6212無線模塊,外部內(nèi)存,led指示燈,和sd卡。其中,攝像頭模塊用于采集圖像信號;AP6212用于和服務(wù)器進行通信;因一張圖像數(shù)據(jù)量較大,片內(nèi)內(nèi)存不夠,故而使用外部內(nèi)存;led燈用于指示設(shè)備工作狀態(tài);sd卡用于保存網(wǎng)絡(luò)、服務(wù)器、和定時任務(wù)配置。

軟件框架說明

整體的軟件框架如下圖所示,網(wǎng)絡(luò)照相機內(nèi)部有一個proxy線程,負(fù)責(zé)和云端進行通信,在接收到云端消息后會解析,并分發(fā)到其他的線程執(zhí)行,然后將執(zhí)行結(jié)果返回到云端;照相機發(fā)生了其他的事件,例如用戶按鍵拍照,也會將數(shù)據(jù)傳給proxy線程,proxy線程再將數(shù)據(jù)發(fā)送到云端。用戶通過上位機終端軟件連接上云服務(wù)器,實現(xiàn)與照相機的通信及控制。

整個系統(tǒng)支持接入多個照相機,如下圖所示,不同的照相機通過sd卡配置文件中sn進行區(qū)分,上位機軟件可以顯示所有在線的照相機,但同一時間只支持操作一個。

軟件模塊說明

1. 用戶線程創(chuàng)建流程

如下圖所示為用戶線程創(chuàng)建流程

用戶線程作用描述如下:
main:用于創(chuàng)建sd_card 線程,檢測按鍵事件,閃燈;
sd_card:用于管理與sd卡相關(guān)的工作,包括拍照,網(wǎng)絡(luò)配置,定時任務(wù);
network:負(fù)責(zé)聯(lián)網(wǎng),根據(jù)sd卡的配置文件連接到指定的wifi網(wǎng)絡(luò);
proxy:負(fù)責(zé)啟動mqtt,并管理與云端的通信,其他線程都需要通過proxy線程與云端交互數(shù)據(jù);
event:定時任務(wù)和按鍵任務(wù),在定時時間到達時,或者用戶按鍵時拍攝照片并通過proxy上傳云端。

2. 通信接口及流程

2.1 MQTT訂閱主題

  • 設(shè)備向服務(wù)器訂閱主題:
    /ter/query/discovery,用于接收設(shè)備發(fā)現(xiàn)消息
    /ter/sn/request,用于接收針對該設(shè)備的指令,其中sn為設(shè)備的SN號,下同

  • 客戶端向服務(wù)器訂閱主題:
    /dev/response/discovery,用于接收設(shè)備發(fā)現(xiàn)回復(fù)
    /dev/response/will,用于接收設(shè)備遺囑消息
    /dev/sn/response,用于接收設(shè)備操作指令回復(fù)
    /dev/sn/event,用于接收設(shè)備的通知

2.2 設(shè)備發(fā)現(xiàn)

所有的設(shè)備均訂閱/ter/query/discovery主題,客戶端向該主題發(fā)布發(fā)現(xiàn)消息,所有收到消息的設(shè)備向/dev/response/discovery回復(fù)一條消息,而客戶端又訂閱了/dev/response/discovery主題,故而便可以知道哪些設(shè)備在線了。
設(shè)備連上服務(wù)器的時候,會定義一個遺囑消息,主題為/dev/sn/will,客戶端訂閱了該主題,當(dāng)設(shè)備因為某些原因掉線,則超過一定時間之后,客戶端便可收到該消息,進而知道該設(shè)備掉線。

  • 客戶端發(fā)起設(shè)備發(fā)現(xiàn)流程,topic: /ter/query/discovery
{
    "params": {
        "code": "0x01",
        "param": {}
    },
    "ecode": 0
}
  • 設(shè)備端回復(fù)發(fā)現(xiàn)命令,topic: /dev/response/discovery
{
    "params": {
        "code": "0x01",
        "sn":"SN-1234",
        "param": {
            "ip":"192.168.1.100",
            "mac":"01:0F:0A:0B"
        }
    },
    "ecode":0
}
  • 設(shè)備端掉線通知,topic: /dev/response/will
{
    "params": {
        "code": "0x11",
        "sn": "SN-1234",
        "param": {}
    },
    "ecode":0
}

2.3 攝像機操作

客戶端訂閱/dev/sn/response,并通過 /ter/sn/request發(fā)送請求指令,設(shè)備端訂閱 /ter/sn/request,并通過/dev/sn/response返回操作結(jié)果,進而實現(xiàn)客戶端對設(shè)備端的操作。
客戶端和設(shè)備端通過消息中的code字段區(qū)分不同的操作。

  • 設(shè)備重啟指令,topic: /ter/sn/request
{
    "params": {
        "code": "0x21",
        "param": {}
    },
    "ecode":0
}
  • 設(shè)備重啟指令回復(fù),topic: /dev/sn/response
{
    "params": {
        "code": "0x21",
        "sn": "SN-1234",
        "param": {
            "action":1    //1,重啟;0,不重啟
        }
    },
    "ecode":0
}
  • 格式化sd卡指令,topic: /ter/sn/request
{
    "params": {
        "code": "0x22",
        "param": {}
    },
    "ecode":0
}
  • 格式化sd卡指令回復(fù),topic: /dev/sn/response
{
    "params": {
        "code": "0x22",
        "sn": "SN-1234",
        "param": {
            "result":1    //1,成功;0,失敗
        }
    },
    "ecode":0
}
  • 實時截圖指令,topic: /ter/sn/request
{
    "params": {
        "code": "0x23",
        "param": {}
    },
    "ecode":0
}
  • 實時截圖回復(fù),topic: /dev/sn/response
{
    "params":{
        "code": "0x23",
        "sn": "SN-1234",
        "param": {
            "result":1,      //截圖結(jié)果,1-成功,0-失敗
            "time":1235,
            "pic":"xxxx"    //base64編碼后的圖片字符串,成功時才有
        }
    },
    "ecode":0
}
  • 下發(fā)截圖定時任務(wù),topic: /ter/sn/request
{
    "params":{
        "code": "0x24",
        "param": {
            "total": 3,
            "time_list":[
                1234,
                1244,
                1254
            ]
        }
    },
    "ecode":0
}
  • 下發(fā)截圖定時任務(wù)回復(fù),topic: /dev/sn/response
{
    "params": {
        "code":"0x24",
        "sn": "SN-1234",
        "param":{
            "result":0
        }
    }
    "ecode":0
}
  • 查詢截圖定時任務(wù),topic: /ter/sn/request,sn為設(shè)備的SN號
{
    "params": {
        "code": "0x25",
        "param":{}
    }
    "ecode":0
}
  • 返回查詢定時任務(wù)結(jié)果,topic: /dev/sn/response
{
    "params": {
        "code":"0x25",
        "sn":"SN-1234",
        "param": {
            "result":1, 1--查詢正常,0--查詢出錯
            "total":3,
            "time_list":[
                1234,
                1244,
                1254
            ]
        }
    },
    "ecode":0
}
  • 刪除截圖定時任務(wù),topic: /ter/sn/request
{
    "params": {
        "code": "0x26"
        "param":{
            "total":3,
            "time_list":[
                1234,
                1244,
                1254
            ]
        }
    }
    "ecode":0
}
  • 返回刪除定時任務(wù)結(jié)果,topic: /dev/sn/response
{
    "params": {
        "code":"0x26",
        "sn":"SN-1234",
        "param": {
            "result":0
        }
    },
    "ecode":0
}

2.4 攝像機通知

客戶端訂閱/dev/sn/event主題,當(dāng)設(shè)備端發(fā)生某些事件(目前只有定時拍照事件和按鍵拍照事件)的時候,向該主題發(fā)布一條消息,客戶端進而刷新顯示。

  • 定時/按鍵照相通知,topic: /dev/sn/eventsn為設(shè)備的SN號
{
    "params": {
        "code":"0xF0",
        "sn":"SN-1234",
        "param": {
            "type":0,    //1,定時截圖; 2,按鍵截圖
            "pic":"xxx"
        }
    }
    "ecode":0
}

演示效果

演示視頻

拍照功能

定時拍照任務(wù)

實物圖

比賽感悟

本次比賽主要學(xué)習(xí)了RT-Thread嵌入式操作系統(tǒng)的使用方法,學(xué)習(xí)了RT-Thread線程創(chuàng)建以及線程通信方法,學(xué)習(xí)了stm32 dcmi接口獲取攝像頭圖像的方法。
在項目的過程中遇到了很多困,有些解決了,典型的有一下兩個:

  1. ov2640驅(qū)動,sdk代碼上沒有開啟dma中斷,導(dǎo)致使用sdk源碼始終無法獲取到圖片,困擾了好久,最后不得不去讀stm32芯片手冊,ov2640模塊手冊,并參考開源代碼,最后找到了問題根源,解決了該問題;
  2. mqtt不能發(fā)送超過512字節(jié)的數(shù)據(jù),原因在于默認(rèn)IPC pipo最大只能傳512字節(jié),而且ringbuf采用了一個16位的變量作為長度,并且最高位作為一個鏡像的標(biāo)記,進而理論上一次性最大只能傳輸32768字節(jié)數(shù)據(jù),仍不足以傳輸一張照片,最后通過講ringbuf改為32字節(jié)作為長度,講IPC pipo最大長度設(shè)置位65535,成功解決了該問題。

也有一些問題沒能解決,最后通過其他手段繞過去了,典型有:

  1. sqlite數(shù)據(jù)有問題,不能用,sqlite數(shù)據(jù)庫可以成功的創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表,但是線程一旦進入循環(huán),便不能操作了,包括數(shù)據(jù)插入和數(shù)據(jù)表創(chuàng)建,該問題原因未知,最后也沒能解決,便沒有存儲照片索引到本地sd卡;
  2. sd卡驅(qū)動有些問題,在線程中存儲的照片過多,便會出現(xiàn)錯誤的文件,并且后續(xù)的照片基本都保存不成功,該問題也未能找到原因,沒能解決,便沒有存儲照片到本地,二是作為照片緩存,只保存一張,傳到服務(wù)器。

本次比賽讓我認(rèn)識到學(xué)無止盡,開源世界需要我們每個人都添磚加瓦,才能變得更好。

  • 代碼地址.txt
    描述:代碼地址
  • 【RT‐Thread 作品秀】基于RT‐Thread的網(wǎng)絡(luò)照相機.pdf
    描述:設(shè)計文檔

相關(guān)推薦

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