• 方案介紹
  • 附件下載
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

基于STM32設(shè)計的掃地機器人

22小時前
201
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

更多詳細資料請聯(lián)系.docx

共1個文件

一、前言

1.1 項目介紹

【1】項目開發(fā)背景

隨著社會節(jié)奏的加快和人們生活方式的改變,智能家居產(chǎn)品逐漸走入千家萬戶。作為智能清潔系統(tǒng)的重要組成部分,掃地機器人憑借其自動化、高效性和便捷性,成為現(xiàn)代家庭中不可或缺的智能設(shè)備之一。傳統(tǒng)人工清潔方式費時費力,尤其對于老年人、上班族而言,日常清掃負擔(dān)較重,因此急需一種智能化、自動化的解決方案來提升生活質(zhì)量。

掃地機器人結(jié)合了嵌入式控制、傳感器技術(shù)、路徑規(guī)劃算法以及無線通信等多種現(xiàn)代技術(shù),實現(xiàn)了自動避障、智能清掃、自動回充等功能,體現(xiàn)了智能控制與人機交互的發(fā)展趨勢。隨著MCU芯片和傳感器技術(shù)的不斷成熟,開發(fā)一套基于STM32微控制器的掃地機器人系統(tǒng),既具有良好的技術(shù)實現(xiàn)基礎(chǔ),又能滿足用戶對于清潔智能化的迫切需求。

本項目通過STM32系列單片機構(gòu)建一個功能完善、成本適中、實用性強的智能掃地機器人系統(tǒng)。通過軟硬件協(xié)同設(shè)計,實現(xiàn)路徑規(guī)劃、灰塵識別、跌落保護、遠程控制等關(guān)鍵功能,提升機器人在不同家庭場景下的清掃效率和安全性。項目不僅具有較強的應(yīng)用價值,同時也為智能機器人技術(shù)的學(xué)習(xí)與研究提供了實踐平臺。

【2】設(shè)計實現(xiàn)的功能

(1)采用紅外避障傳感器和超聲波測距模塊實現(xiàn)自動避障功能,能夠在復(fù)雜環(huán)境中自動繞開障礙物。
(2)利用實時時鐘RTC模塊實現(xiàn)定時清掃功能,按設(shè)定時間自動啟動清掃任務(wù)。
(3)結(jié)合MPU6050姿態(tài)傳感器編碼器反饋實現(xiàn)路徑規(guī)劃與完整覆蓋式清掃,提高清掃效率。
(4)通過紅外跌落傳感器檢測地面邊緣,實時進行邊緣檢測并防止機器人跌落。
(5)通過ESP8266模塊實現(xiàn)WIFI通信,支持手機APP進行手動遙控操作與遠程控制。
(6)由STM32主控處理清掃路徑并生成清掃地圖,上傳至APP實現(xiàn)簡易地圖繪制功能。
(7)灰塵識別模塊檢測空氣中粉塵濃度,在污染區(qū)域啟動重點清掃機制。
(8)利用DFPlayer Mini語音模塊實現(xiàn)語音提示功能,用于狀態(tài)播報與故障提醒。
(9)使用0.96寸OLED屏幕顯示當(dāng)前清掃狀態(tài)、電量信息和系統(tǒng)參數(shù),方便本地查看。
(10)通過電壓檢測模塊監(jiān)測電池電量,并結(jié)合紅外尋跡模塊實現(xiàn)自動回充功能。
(11)ESP8266模塊通過MQTT協(xié)議與服務(wù)器通信,實現(xiàn)清掃狀態(tài)與控制指令的聯(lián)網(wǎng)功能。
(12)Android APP平臺支持清掃進度查看、路徑顯示、電量查詢、遠程啟動/停止等控制功能。

【3】項目硬件模塊組成

(1)主控芯片STM32F103RCT6,作為系統(tǒng)核心控制器,負責(zé)傳感器數(shù)據(jù)處理、運動控制與通信管理。
(2)驅(qū)動電機:2個帶編碼器的TT減速直流電機,用于驅(qū)動機器人前進、后退、轉(zhuǎn)向等移動動作。
(3)電機驅(qū)動模塊:L298N雙路直流電機驅(qū)動模塊,實現(xiàn)對左右驅(qū)動電機的正反轉(zhuǎn)與調(diào)速控制。
(4)紅外避障傳感器:3個TCRT5000模塊,分別安裝在機器人前方與左右側(cè),用于檢測障礙物。
(5)超聲波測距模塊:1個HC-SR04模塊,用于精確測量前方障礙物距離。
(6)紅外跌落傳感器:3個TCRT5000模塊,安裝在機器人底部前端及兩側(cè),用于檢測地面是否存在,防止跌落。
(7)姿態(tài)檢測模塊:1個MPU6050六軸陀螺儀+加速度計模塊,用于獲取機器人運動姿態(tài)和角度變化。
(8)灰塵識別模塊:GP2Y1010AU0F光學(xué)粉塵傳感器,用于檢測空氣中灰塵濃度,實現(xiàn)重點清掃。
(9)語音模塊:DFPlayer Mini音頻模塊,配合揚聲器實現(xiàn)語音播報與提示功能。
(10)顯示模塊:0.96寸SPI接口OLED顯示屏(SSD1306驅(qū)動),用于顯示清掃狀態(tài)、電量等信息。
(11)通信模塊:ESP8266 WiFi模塊(NodeMCU),通過串口與STM32通信,實現(xiàn)與APP的數(shù)據(jù)交互。
(12)電源系統(tǒng):7.4V 18650鋰電池組,配合升壓模塊為系統(tǒng)提供5V/9V穩(wěn)定電源。
(13)電壓檢測模塊:電壓分壓采集模塊,用于檢測電池電壓,實現(xiàn)電量監(jiān)測。
(14)自動回充模塊:紅外接收模塊配合充電座紅外發(fā)射器,實現(xiàn)機器人自動返回充電座。
(15)實時時鐘模塊:DS3231高精度RTC模塊,用于實現(xiàn)定時清掃功能。
(16)APP平臺:基于Android系統(tǒng)的手機APP,使用Qt(C++)開發(fā),提供遠程控制與狀態(tài)監(jiān)控功能。
(17)車體結(jié)構(gòu):亞克力底盤、萬向輪與支撐結(jié)構(gòu),固定并承載各模塊與電路系統(tǒng)。
(18)吸塵模塊:5V高速風(fēng)扇與滾刷組合,實現(xiàn)地面灰塵與顆粒物的有效吸附與清潔。

【4】設(shè)計意義

本項目基于STM32設(shè)計的掃地機器人系統(tǒng),旨在利用嵌入式系統(tǒng)和多傳感器融合技術(shù),構(gòu)建一套具備基本智能清掃能力的自動化清潔設(shè)備。通過項目的設(shè)計與實現(xiàn),不僅能夠減輕用戶日常清潔的勞動負擔(dān),還可以提高清潔效率與覆蓋率,為家庭智能化建設(shè)提供實用的技術(shù)支持和硬件基礎(chǔ)。

項目集成了自動避障、路徑規(guī)劃、定時清掃、防跌落、語音提示、自動回充、APP遠程控制等功能模塊,充分體現(xiàn)了現(xiàn)代嵌入式系統(tǒng)在智能家居中的實際應(yīng)用價值。通過合理的模塊選型與軟硬件協(xié)同開發(fā),系統(tǒng)在穩(wěn)定性、實用性、用戶交互體驗等方面都達到了較高水平,具備良好的工程實現(xiàn)與應(yīng)用推廣基礎(chǔ)。

本項目的實施不僅為實際家庭場景中的清潔工作提供了解決方案,也為學(xué)習(xí)和掌握STM32平臺的開發(fā)技術(shù)、傳感器集成應(yīng)用、路徑算法設(shè)計、無線通信協(xié)議以及多線程邏輯管理等關(guān)鍵技術(shù)提供了一個完整的綜合性平臺,具有較強的教學(xué)實踐和工程訓(xùn)練價值。

【5】市面上同類產(chǎn)品研究現(xiàn)狀

目前市面上的掃地機器人產(chǎn)品已較為成熟,主要品牌包括iRobot的Roomba系列、石頭科技的石頭掃地機器人、小米米家掃地機器人等。這些產(chǎn)品普遍具備自動避障、路徑規(guī)劃、邊緣檢測和自動回充等核心功能,體現(xiàn)了智能清掃設(shè)備的發(fā)展趨勢。

iRobot Roomba系列通過多傳感器融合和先進的SLAM(同步定位與地圖構(gòu)建)算法,實現(xiàn)精準地圖繪制和高效路徑規(guī)劃,能夠適應(yīng)復(fù)雜家庭環(huán)境,實現(xiàn)無遺漏清掃。其采用多點激光測距和視覺傳感技術(shù),配合強大的云端算法,提供用戶友好的APP遠程控制及語音交互功能。

石頭科技的掃地機器人注重激光雷達(LIDAR)導(dǎo)航技術(shù),配合高精度陀螺儀和多組紅外傳感器,實現(xiàn)快速環(huán)境感知與障礙物避讓。該系列產(chǎn)品支持房間分區(qū)清掃及定時預(yù)約,用戶可通過手機APP查看實時地圖和清掃進度,增強使用體驗。

小米米家掃地機器人則采用了激光導(dǎo)航與視覺傳感的結(jié)合,具備強大的智能路徑規(guī)劃和避障能力。通過手機APP實現(xiàn)遠程啟動、停止及清掃模式切換,并集成語音助手控制功能,滿足現(xiàn)代智能家居需求。

綜上,當(dāng)前主流掃地機器人均注重傳感器融合、智能路徑規(guī)劃與用戶交互體驗的提升,形成了較為完善的產(chǎn)品生態(tài)。本項目結(jié)合STM32平臺和多種傳感器,實現(xiàn)基礎(chǔ)功能的同時,也為低成本智能清掃設(shè)備的開發(fā)提供了可行的參考方案。

【6】摘要

基于STM32的掃地機器人項目,設(shè)計并實現(xiàn)了一套集自動避障、路徑規(guī)劃、邊緣檢測、防跌落、定時清掃、語音提示、自動回充及遠程APP控制于一體的智能清掃系統(tǒng)。系統(tǒng)采用STM32F103RCT6作為主控芯片,結(jié)合多種傳感器模塊實現(xiàn)環(huán)境感知與智能決策,通過ESP8266實現(xiàn)無線通信與遠程控制。該機器人能夠高效完成地面無遺漏清掃,保障運行安全,提高用戶使用便捷性和生活質(zhì)量。項目驗證了嵌入式系統(tǒng)與傳感器融合技術(shù)在智能家居領(lǐng)域的應(yīng)用價值,具備良好的工程實用性和推廣前景。

關(guān)鍵字:STM32,掃地機器人,路徑規(guī)劃,自動避障,邊緣檢測,ESP8266,遠程控制

1.2 設(shè)計思路

本項目設(shè)計基于STM32F103RCT6微控制器,充分利用其豐富的接口和較強的處理能力作為系統(tǒng)核心。設(shè)計思路以多傳感器融合為基礎(chǔ),通過紅外避障傳感器和超聲波測距模塊實現(xiàn)環(huán)境感知,保障機器人能夠?qū)崟r識別障礙物并進行繞行。結(jié)合MPU6050姿態(tài)傳感器和編碼器數(shù)據(jù),實現(xiàn)路徑規(guī)劃與運動控制,確保機器人能夠高效完成地面覆蓋式清掃。

為了保證運行安全,設(shè)計采用多個紅外跌落傳感器進行邊緣檢測,有效防止機器人跌落樓梯或其他高差處。系統(tǒng)通過實時電壓檢測與紅外尋跡模塊實現(xiàn)低電量自動回充功能,提升使用便捷性和續(xù)航能力。語音模塊的集成則用于狀態(tài)提示和故障報警,增強人機交互體驗。

通信方面,設(shè)計采用ESP8266無線模塊,配合MQTT協(xié)議,實現(xiàn)機器人與手機APP的遠程數(shù)據(jù)交互和控制,使用戶能夠?qū)崟r監(jiān)控清掃狀態(tài)并進行遠程操作。整體設(shè)計采用模塊化開發(fā)思路,硬件選型合理,軟件結(jié)構(gòu)清晰,保證系統(tǒng)的穩(wěn)定性和易維護性,滿足智能家居對掃地機器人高效、智能、安全的使用需求。

1.3 系統(tǒng)功能總結(jié)

功能模塊 功能描述 主要硬件模塊 關(guān)鍵技術(shù)/實現(xiàn)方式
自動避障 識別并繞開前方及側(cè)方障礙物 紅外避障傳感器(3個)、超聲波模塊 紅外與超聲波傳感器融合檢測
定時清掃 按設(shè)定時間自動啟動清掃任務(wù) DS3231 RTC模塊 實時時鐘定時觸發(fā)
路徑規(guī)劃與覆蓋 實現(xiàn)地面無遺漏的覆蓋式清掃 MPU6050、編碼器 姿態(tài)檢測+編碼器數(shù)據(jù),路徑規(guī)劃算法
邊緣檢測與防跌落 檢測地面邊緣,防止機器人跌落 紅外跌落傳感器(3個) 紅外傳感器實時檢測邊緣
手動遙控 通過手機APP遠程控制機器人 ESP8266 WiFi模塊 WIFI通信+MQTT協(xié)議
地圖繪制 生成簡易的房間清掃路徑圖 STM32主控、傳感器數(shù)據(jù)處理 算法生成路徑地圖,上傳APP
灰塵識別與重點清掃 檢測灰塵濃度,針對高灰塵區(qū)域加強清掃 GP2Y1010光學(xué)粉塵傳感器 模擬信號采集與閾值判定
語音播報 語音提示工作狀態(tài)和故障信息 DFPlayer Mini音頻模塊 語音模塊控制播放
OLED顯示 實時顯示清掃狀態(tài)、電量及系統(tǒng)參數(shù) 0.96寸OLED顯示屏(SSD1306) SPI通信顯示信息
自動回充 低電量時自動返回充電座充電 電壓檢測模塊、紅外尋跡模塊 電量監(jiān)測+紅外尋跡定位
WIFI聯(lián)網(wǎng) 實現(xiàn)遠程監(jiān)控與控制 ESP8266 WiFi模塊 WIFI通信與云端MQTT協(xié)議
APP遠程控制 遠程查看機器人狀態(tài),控制啟動、停止及路徑等功能 手機APP、ESP8266模塊 APP界面設(shè)計與無線數(shù)據(jù)交互

1.4 開發(fā)工具的選擇

【1】設(shè)備端開發(fā)

硬件設(shè)備端的開發(fā)主要依賴于C語言,利用該語言直接操作硬件寄存器,確保系統(tǒng)運行的高效性和低延遲。C語言在嵌入式開發(fā)中具有廣泛的應(yīng)用,它能夠直接訪問硬件,滿足對資源消耗和響應(yīng)速度的嚴格要求。為了編寫高效、穩(wěn)定的代碼,開發(fā)工具選擇了Keil uVision 5作為主要的開發(fā)環(huán)境。Keil是一個專業(yè)的嵌入式開發(fā)工具,廣泛應(yīng)用于基于ARM架構(gòu)的微控制器(如STM32)開發(fā)。Keil提供了完善的調(diào)試、編譯和仿真支持,能夠幫助在軟件開發(fā)過程中高效地進行調(diào)試、單步執(zhí)行以及斷點設(shè)置,確保開發(fā)的穩(wěn)定性和高效性。
STM32F103RCT6是項目中使用的主控芯片,它基于ARM Cortex-M3架構(gòu),擁有強大的計算能力和豐富的外設(shè)接口。在硬件編程中,寄存器級編程是常用的方式,這要求開發(fā)者對芯片的硬件寄存器有深入的理解。在Keil環(huán)境中,通過STM32的寄存器直接控制GPIOADC、I2C、SPI等硬件接口,以滿足各個硬件模塊(如傳感器、執(zhí)行器、顯示屏等)與主控芯片的交互。使用寄存器編程能夠提供更高效、精確的控制,避免了外部庫的開銷,同時也能深入調(diào)控硬件特性,提升系統(tǒng)性能。

【2】上位機開發(fā)

本項目的上位機開發(fā)基于Qt 5框架,使用**C++**作為主要編程語言。Qt是一個跨平臺的應(yīng)用開發(fā)框架,廣泛用于開發(fā)GUI應(yīng)用程序。Qt提供了豐富的GUI組件和工具,能夠高效地實現(xiàn)圖形界面的設(shè)計與開發(fā)。C++則作為Qt的底層語言,具有高效的性能和良好的控制力,非常適合用于處理設(shè)備與系統(tǒng)之間的數(shù)據(jù)交互、通信協(xié)議的實現(xiàn)和復(fù)雜的計算任務(wù)。在項目中,Qt被用于開發(fā)Windows平臺的桌面應(yīng)用程序以及Android平臺的手機APP。Qt框架的跨平臺特性使得開發(fā)者能夠使用同一套代碼在不同操作系統(tǒng)上進行構(gòu)建和部署,大大提高了開發(fā)效率。

為了方便開發(fā)和調(diào)試,上位機的開發(fā)采用了Qt Creator作為主要的集成開發(fā)環(huán)境(IDE)。Qt Creator是一款由Qt官方提供的開發(fā)工具,專為Qt應(yīng)用程序開發(fā)設(shè)計,支持C++、QML和JavaScript等語言。Qt Creator提供了豐富的功能,如代碼編輯、調(diào)試、構(gòu)建、版本控制集成等,能夠顯著提升開發(fā)者的生產(chǎn)力。在本項目中,Qt Creator為開發(fā)者提供了自動化構(gòu)建、界面設(shè)計工具(如Qt Designer)和調(diào)試工具(如QDebug和QML調(diào)試工具),使得開發(fā)過程更加高效和流暢。
上位機與硬件設(shè)備端的通信采用了基于TCP/IP協(xié)議的數(shù)據(jù)傳輸方式。為了實現(xiàn)這一功能,Qt提供了豐富的網(wǎng)絡(luò)編程支持,尤其是QTcpSocketQTcpServer類,使得上位機能夠輕松地與硬件設(shè)備建立TCP連接,進行數(shù)據(jù)收發(fā)。上位機通過WIFI連接ESP8266-WIFI模塊,ESP8266模塊創(chuàng)建TCP服務(wù)器,上位機應(yīng)用則作為客戶端連接到服務(wù)器,進行實時的數(shù)據(jù)傳輸與控制命令的下發(fā)。
為了滿足不同用戶的需求,本項目需要支持Windows平臺的桌面應(yīng)用和Android平臺的移動APP。Qt的跨平臺特性使得開發(fā)人員能夠在一個代碼庫下完成多平臺應(yīng)用的開發(fā)和移植。開發(fā)者僅需要編寫一次應(yīng)用邏輯和用戶界面,就可以通過Qt的跨平臺構(gòu)建工具生成Windows和Android兩個平臺的可執(zhí)行文件。此外,Qt提供了豐富的文檔和社區(qū)支持,幫助開發(fā)者解決平臺差異和兼容性問題,確保應(yīng)用在不同平臺上都能穩(wěn)定運行。

總體而言,上位機開發(fā)環(huán)境采用了Qt 5框架和C++語言,結(jié)合Qt Creator集成開發(fā)環(huán)境,提供了一個高效、穩(wěn)定、跨平臺的開發(fā)工具鏈。通過Qt強大的GUI設(shè)計、網(wǎng)絡(luò)通信、多線程支持以及數(shù)據(jù)庫管理功能,開發(fā)者能夠輕松實現(xiàn)與硬件設(shè)備的交互、控制設(shè)備、處理傳感器數(shù)據(jù),并為用戶提供直觀、流暢的操作體驗。

二、算法設(shè)計

2.1 算法設(shè)計思路

本項目采用柵格地圖法(Grid Map)+螺旋清掃+墻邊跟隨相結(jié)合的方式,實現(xiàn)高效率覆蓋清掃。

(1)地圖構(gòu)建

  • 將房間劃分為二維柵格地圖,每個格子表示20cm × 20cm的面積(實際可調(diào)整)
  • 格子狀態(tài):0=未清掃,1=已清掃,2=障礙物

(2)基本策略

  • 默認從左上角或充電座位置開始清掃
  • 采用螺旋清掃 + Z字形遍歷 + 遇墻回轉(zhuǎn)機制,提升效率
  • 實時更新當(dāng)前位置和地圖信息
  • 編碼器與MPU6050配合,進行位置估算(簡化SLAM)

(3)避障融合

  • 在路徑規(guī)劃過程中融合超聲波+紅外避障模塊,對障礙進行打標(記為2)

(4)完成判斷

  • 所有柵格=1(已清掃)時清掃結(jié)束,進入回充狀態(tài)

2.2 核心模塊算法流程圖

image-20250627222940953

flowchart TD
    A[初始化柵格地圖] --> B[定位當(dāng)前位置(x,y)]
    B --> C[標記當(dāng)前位置已清掃]
    C --> D[查找下一個可清掃鄰格]
    D -->|存在| E[規(guī)劃方向移動]
    D -->|無| F[回退/掉頭/回充]
    E --> G[檢測障礙]
    G -->|無障礙| H[移動到新位置]
    G -->|有障礙| I[標記障礙格,換方向]
    H --> B
    I --> B
    F --> J[全部完成 -> 回充]

2.3 STM32簡化路徑規(guī)劃算法代碼(偽代碼 + 可移植C代碼)

1. 柵格地圖結(jié)構(gòu)定義

#define MAP_SIZE_X 20
#define MAP_SIZE_Y 20

#define CELL_UNVISITED 0
#define CELL_VISITED   1
#define CELL_OBSTACLE  2

uint8_t map[MAP_SIZE_Y][MAP_SIZE_X];  // 2D 柵格地圖
int current_x = 0;
int current_y = 0;
int direction = 0;  // 0=上,1=右,2=下,3=左

2. 標記當(dāng)前位置已清掃

void mark_visited(int x, int y) {
    if (x >= 0 && x < MAP_SIZE_X && y >= 0 && y < MAP_SIZE_Y) {
        map[y][x] = CELL_VISITED;
    }
}

3. 查找下一個可清掃格子(四方向)

int dx[4] = {0, 1, 0, -1}; // 上右下左
int dy[4] = {-1, 0, 1, 0};

int find_next_direction() {
    for (int i = 0; i < 4; i++) {
        int nx = current_x + dx[i];
        int ny = current_y + dy[i];
        if (nx >= 0 && nx < MAP_SIZE_X && ny >= 0 && ny < MAP_SIZE_Y) {
            if (map[ny][nx] == CELL_UNVISITED) {
                return i;
            }
        }
    }
    return -1; // 無可清掃方向
}

4. 移動函數(shù)(偽動作控制)

void move_to(int dir) {
    // 電機控制部分略(根據(jù)dir控制左右輪轉(zhuǎn)速方向)
    current_x += dx[dir];
    current_y += dy[dir];
    mark_visited(current_x, current_y);
}

5. 主控制循環(huán)(主邏輯)

void clean_room() {
    mark_visited(current_x, current_y); // 初始位置

    while (1) {
        int next_dir = find_next_direction();
        if (next_dir == -1) {
            // 所有方向均已訪問或是障礙,嘗試回退或結(jié)束
            if (all_cleaned()) {
                return_to_charge(); // 所有清掃完成
                break;
            } else {
                rotate_90(); // 更換方向
                continue;
            }
        }

        if (!is_obstacle(current_x + dx[next_dir], current_y + dy[next_dir])) {
            move_to(next_dir);
        } else {
            map[current_y + dy[next_dir]][current_x + dx[next_dir]] = CELL_OBSTACLE;
        }
    }
}

6. 判斷是否清掃完畢

int all_cleaned() {
    for (int y = 0; y < MAP_SIZE_Y; y++) {
        for (int x = 0; x < MAP_SIZE_X; x++) {
            if (map[y][x] == CELL_UNVISITED) return 0;
        }
    }
    return 1;
}

2.4 邊緣檢測與防跌落功能算法設(shè)計過程

1. 傳感器選型

采用 3個 TCRT5000 紅外反射式跌落檢測傳感器 安裝于機器人底部前端和左右兩側(cè),用于檢測地面是否存在反射(白色地面為反射,懸空為無反射)。

2. 原理說明

  • TCRT5000發(fā)射紅外光并接收反射光,若有地面反射回紅外光,則表示有地面;
  • 若前方/左側(cè)/右側(cè)無反射光(即信號電平改變),則判定為“邊緣”或“懸空”,觸發(fā)防跌落動作。

3. 傳感器安裝建議

  • 每個TCRT5000傳感器對應(yīng)一個檢測區(qū)域:
    • 前部傳感器:防止前進跌落
    • 左側(cè)/右側(cè)傳感器:防止側(cè)滑跌落
  • 建議安裝高度約為 0.8~1.2cm,距離地面

4. 防跌落處理機制

  • 一旦某個傳感器檢測為無地面(懸空):
    • 立即停止所有電機
    • 后退一小段距離
    • 左/右轉(zhuǎn)避開邊緣
    • 重新進入正常清掃邏輯

2.5 STM32 防跌落算法設(shè)計(代碼實現(xiàn))

(1)接口定義與引腳配置(示例使用 GPIO 輸入)

假設(shè)連接如下:

  • 前TCRT5000 —— GPIOA PIN0
  • 左TCRT5000 —— GPIOA PIN1
  • 右TCRT5000 —— GPIOA PIN2
#define SENSOR_FRONT   HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)
#define SENSOR_LEFT    HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)
#define SENSOR_RIGHT   HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2)
  • TCRT5000輸出為 低電平表示地面存在,高電平表示無地面/懸空

(2)初始化 GPIO 輸入

void TCRT5000_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

(3)檢測邊緣函數(shù)

uint8_t is_edge_detected(void)
{
    if (SENSOR_FRONT == GPIO_PIN_SET ||
        SENSOR_LEFT == GPIO_PIN_SET ||
        SENSOR_RIGHT == GPIO_PIN_SET)
    {
        return 1;  // 檢測到邊緣
    }
    return 0;  // 正常地面
}

(4)防跌落動作處理函數(shù)

void handle_fall_protection(void)
{
    stop_motors();  // 停止所有電機

    delay_ms(200);  // 稍作停頓

    move_backward();  // 后退一小段
    delay_ms(500);

    turn_right();  // 隨機右轉(zhuǎn)避開邊緣
    delay_ms(400);

    stop_motors();
}

(5)集成進主循環(huán)

void main_loop(void)
{
    while (1)
    {
        if (is_edge_detected())
        {
            handle_fall_protection();  // 邊緣檢測觸發(fā)處理
            continue;
        }

        clean_forward();  // 正常前進清掃
        delay_ms(100);
    }
}

三、Qt開發(fā)入門與環(huán)境搭建

當(dāng)前項目的上位機是采用Qt開發(fā)的,這一章節(jié)主要是介紹Qt開發(fā)環(huán)境的安裝,以及Qt開發(fā)環(huán)境入門的使用。如果你Qt沒有任何基礎(chǔ),建議仔細看一遍。

3.1 Qt是什么?

Qt 是一個功能強大、跨平臺的應(yīng)用程序開發(fā)框架,主要用于創(chuàng)建圖形用戶界面(GUI)應(yīng)用程序,但它不僅僅局限于GUI編程。它由挪威的奇趣科技(TrollTech)最初于1991年開發(fā),并在后續(xù)的發(fā)展歷程中經(jīng)歷了多次所有權(quán)變更,包括諾基亞和Digia等公司接手,現(xiàn)在Qt屬于The Qt Company所有。

Qt 主要特點和優(yōu)勢包括:

(1)跨平臺:Qt 支持多種操作系統(tǒng),開發(fā)者可以使用同一份源代碼在不同平臺上編譯運行,如Windows、Linux、macOS、Android以及各種嵌入式系統(tǒng)(如RTOS),實現(xiàn)“一次編寫,到處編譯”。

(2)C++ 開發(fā):Qt 的核心是基于C++編程語言構(gòu)建,提供了一套豐富的類庫,通過面向?qū)ο蟮脑O(shè)計方式簡化了開發(fā)過程。

(3)圖形用戶界面:Qt 提供了完整的GUI組件集,包含窗口、按鈕、標簽、文本框等各種標準控件,以及布局管理器、樣式表等功能,使得開發(fā)者能夠高效地創(chuàng)建美觀且功能完善的桌面應(yīng)用或移動應(yīng)用界面。

(4)工具鏈完整:Qt 包含一系列集成開發(fā)環(huán)境(IDE)和輔助工具,例如Qt Creator是一個全能的跨平臺IDE,Qt Designer用于可視化拖拽設(shè)計UI界面,Qt Linguist支持國際化資源文件的翻譯,還有Qt Assistant和大量文檔資源方便開發(fā)者的使用。

(5)非GUI功能豐富:除了GUI功能外,Qt 還提供了眾多非圖形化功能模塊,如網(wǎng)絡(luò)通信、數(shù)據(jù)庫訪問、XML處理、多媒體處理(音頻視頻)、文件I/O、線程與并發(fā)處理、OpenGL和3D圖形渲染等。

(6)元對象系統(tǒng):Qt 使用元對象系統(tǒng)(Meta-Object System, MOC)實現(xiàn)了信號與槽機制(Signals and Slots),這是一種高級事件處理機制,允許在不同對象之間安全地進行異步通信。

(7)可擴展性與靈活性:Qt 架構(gòu)高度靈活,支持插件體系結(jié)構(gòu),開發(fā)者可以根據(jù)需要自定義組件并輕松地集成到Qt應(yīng)用中。

Qt 以其強大的跨平臺能力和全面的功能集合成為許多企業(yè)和個人開發(fā)者選擇用來開發(fā)高性能、高穩(wěn)定性的應(yīng)用程序的重要工具之一,被廣泛應(yīng)用于各類桌面軟件、嵌入式設(shè)備、移動應(yīng)用以及服務(wù)器端組件等領(lǐng)域。

3.2 Qt版本介紹

在Qt發(fā)行版本中將要涉及兩個版本:Qt商業(yè)授權(quán)和Qt開源授權(quán)。

(1)Qt商業(yè)授權(quán)是設(shè)計商業(yè)軟件的開發(fā)環(huán)境,這些商業(yè)軟件使用了傳統(tǒng)的商業(yè)來發(fā)布,它包含了一些更新的功能、技術(shù)上的支持和大量的解決方案,開發(fā)了使用于行業(yè)的一些特定的組件,有一些特殊的功能只在商業(yè)用戶中使用。

(2)Qt開源授權(quán)是用來開發(fā)開源的軟件,它提供了一些免費的支持,并遵循QPL協(xié)議。

開放源代碼是免費的軟件,不牽涉用戶的某些權(quán)益。任何人都有使用開源軟件和參與它的修改的機會,這就意味著其他的人同樣可獲得你開發(fā)的代碼。目前 Qt 的開源授權(quán)有兩種,一種是 GPL 授權(quán),另一種是 LGPL 授權(quán)。

3.3 Qt開發(fā)環(huán)境安裝

Qt的中文官網(wǎng): https://www.qt.io/zh-cn/image-20221207160550486

image-20221207160606892

QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6

打開下載鏈接后選擇下面的版本進行下載:

qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details

軟件安裝時斷網(wǎng)安裝,否則會提示輸入賬戶。

如果下載不了,可以在網(wǎng)盤里找到安裝包下載: 飛書文檔記錄的網(wǎng)盤地址:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

安裝的時候,第一個復(fù)選框里勾選一個mingw 32編譯器即可,其他的不管默認就行,直接點擊下一步繼續(xù)安裝。

image-20221203151742653

選擇MinGW 32-bit 編譯器:

image-20221203151750344

3.4 開發(fā)第一個QT程序

在QT開發(fā)過程中,可以手動編寫代碼也可以使用UI設(shè)計師直接拖拽控件的方式編寫界面和布局,在實際的開發(fā)過程中一般是兩種方式結(jié)合使用,提高開發(fā)效率。

本小節(jié)用一個簡單的 “Hello QT” 程序介紹一下使用QtCreator新建工程的步驟。

(1)打開QtCreator軟件,選擇New Project,新建一個工程。

image-20240304134953164

(2)項目模板選擇QT Widgets Application

image-20240304135416497

(3)設(shè)置項目名稱和存放路徑

注意:QT項目路徑和名稱不能出現(xiàn)中文字符。

image-20240304135504345

(4)編譯工具套件選擇

編譯工具套件可以后面自己增加,比如增加Android的。套件是指 Qt 程序從編譯鏈接到運行環(huán)境的全部工具和 Qt 類庫的集合。

image-20240304135535341

(5)設(shè)置生成的類信息

在類信息設(shè)置界面選擇基類,目前有三種基類:QMainWindow,QWidget,QDialog。在基類里選擇QMainWindow,類名和文件名會根據(jù)基類自動修改,一般不需要修改,默認即可。

image-20240304135630942

(6)項目管理

在項目管理界面可以設(shè)置作為子項目,以及加入版本控制系統(tǒng)。這兩個功能暫時用不到,都用默認的 ,然后點擊 “完成”。

image-20240304135652922

(7)創(chuàng)建完成

image-20240304135728165

(8) 編輯代碼

展開main.cpp文件,添加內(nèi)容如下:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QLabel>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //MainWindow w;
    //w.show();
    QLabel *label =new QLabel("Hello Qt!");
    label->setGeometry(400,100,100,20);
    label->show();
    return a.exec();
}

代碼解析:

1)	#include <QApplication>和 #include <QLabel>是QT的類聲明頭文件,對于每個QT類都有一個與該類同名的頭文件,在這個頭文件包含了對該類的定義。
2)	main(int argc, char *argv[]) :main函數(shù)的標準寫法。
3)	QApplication a(argc, argv):創(chuàng)建一個QApplication對象,用于管理應(yīng)用程序的資源,QApplication類的構(gòu)造函數(shù)需要兩個參數(shù)。
4)	QLabel *label =new QLabel("Hello Qt!") :創(chuàng)建QLabel窗口部件,QLabel是一個Qt提供的窗口部件,可以用來顯示一行文本。
5)	label->setGeometry(400,100,100,20) : 設(shè)置控件顯示的位置。
6)	label->show():使Qlabel創(chuàng)建的窗口可見,就是顯示設(shè)置的文本。
7)	return a.exec():應(yīng)用程序?qū)⒖刂茩?quán)傳遞給QT,讓程序進入消息循環(huán)。等待可能的菜單,工具條,鼠標等的輸入,進行響應(yīng)。

image-20240304135908750

(9)行程序

運行程序可以點擊左下角的三角形符號或者按下快捷鍵Ctrl+R。

image-20240304135938848

3.5 調(diào)試輸出

QT中使用QDebug類輸出調(diào)試信息。主要用于調(diào)試代碼,類似于std::cout的替代品,支持QT的數(shù)據(jù)類型。使用前需要包含頭文件。

調(diào)試輸出的分類

qDebug 調(diào)試信息提示
qWarning 一般的警告提示
qCritical 嚴重錯誤提示
qFatal 致命錯誤提示

示例代碼:

qDebug("調(diào)試信息輸出");
qWarning("一般警告信息輸出");
qCritical("嚴重錯誤輸出");
qFatal("致命錯誤輸出");

qDebug輸出的信息會打印到QT軟件下邊的輸出面板。

在上節(jié)的HelloQt工程上加上調(diào)試輸出代碼,增加的main.cpp代碼如下:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //MainWindow w;
    //w.show();
    qDebug()<<"QT調(diào)試信息輸出";
    int data_int=8888;
    qDebug()<<data_int;
    float data_float=123.888;
    qDebug()<<data_float;
    return a.exec();
}

運行程序,觀察輸出的調(diào)試信息:

image-20240304140142790

3.6 QT Creator常用的快捷鍵

掌握一些適用的快捷鍵,可以提高程序開發(fā)的效率。

(1)F1 鍵,快速切換光標選中的函數(shù)或者類的幫助信息,按一次半屏顯示,按下兩次全屏顯示。

(2)F2 鍵,快速切換到光標選中的函數(shù)或者類的源碼定義處。

(3)F4鍵,快速在源文件和頭文件之間切換。

(4)Ctrl(按住)+ Tab,快速切換已打開的文件

(5)Ctrl+ I ,縮進光標選中行代碼(自動與上層代碼對齊)。

(6)Ctrl + / ,快速注釋或者取消注釋光標選中行。

(7)快速修改全局變量名

鼠標光標選中變量名,按下Ctrl+Shift+R,當(dāng)變量名稱出現(xiàn)紅色框表示已經(jīng)激活全局修改功能。修改一處,整個工程對應(yīng)變量名稱全部會修改。修改完畢之后,光標移開,再按下Ctrl+Shift+R保存修改。

image-20240304140242113

(8)快速修改全局函數(shù)名

快捷方式與變量修改一樣按下Ctrl+Shift+R,一處修改整個工程對應(yīng)的函數(shù)名稱也會跟著改。選中函數(shù)后,按下Ctrl+Shift+R后整個工程的對應(yīng)的函數(shù)名會高亮,并且在軟件下方彈出修改框。

image-20240304140311742

3.7 QT幫助文檔

Qt 幫助文檔太多,難以全部翻譯成中文,即使翻譯了一部分,翻譯花的時間太多,翻譯更新的時效性也難以保證,最終還是得看英文幫助,QtCreator 集成了幫助系統(tǒng),查找非常方便。

打開QtCreator,選擇菜單欄的最左邊的幫助選項,界面如下:

image-20240304140337833

(1)查看Qlabel控件的幫助信息:

image-20240304140357011

3.8 UI設(shè)計師使用

上節(jié)的Hello QT程序使用純C++代碼編寫,這一節(jié)使用QT界面設(shè)計模式實現(xiàn)與上一節(jié)Hello QT程序一樣的功能。仿照著上節(jié)新創(chuàng)建一個工程。雙擊打開mainwindow.ui文件,進入到UI設(shè)計界面。

(1)拖一個Label控件到編輯區(qū),雙擊Label控件可以修改文本內(nèi)容。

image-20240304140517858

(2)運行程序可以點擊左下角的三角形符號或者按下快捷鍵Ctrl+R。

image-20240304140600717

(3)UI設(shè)計師界面功能介紹

image-20240304140615717

3.9 按鈕控件組

QT Creator UI設(shè)計師界面的按鈕組截圖如下:

image-20240304140809093

以下是對按鈕組控件的一些功能介紹:

(1)Push Button按壓按鈕:最普通的按鈕,按(點擊)按鈕命令計算機執(zhí)行一些動作,或者回答問題,比如windows開始菜單里的重啟,注銷,關(guān)機等按鈕。

(2)Tool Button工具按鈕:工具按鈕通常是一個集合,一般集成在工具欄里。比如打開,保存,復(fù)制,粘貼,剪切等常用的操作。

(3)Radio Button單選按鈕:單選按鈕通常是兩個以上的形式出現(xiàn)在一塊,按鈕之間有互斥關(guān)系,每次只能選中一個。比如:一個人的性別只能選擇一個,不能同時是男性又是女性。

(4)Check Box復(fù)選框:復(fù)選框與單選按鈕概念相反,復(fù)選框通常表示多個可以同時存在的選項,比如一個人可以同時擁有多個愛好,比如讀書、看電影、爬山、游泳等。

(5)Command Link Button命令鏈接按鈕:一般用來打開的窗口或者網(wǎng)頁鏈接。

(6)Dialog Button Box標準按鈕盒:標準按鈕盒通常用于對話框程序;比如:常見的確認對話框有 “確定”“取消”等標準按鈕,Qt 將這些典型的按鈕做成標準按鈕盒,并將相應(yīng)的信號加以封裝,方便程序員使用。

3.10 布局控件組

開發(fā)一個圖形界面應(yīng)用程序,界面的布局影響到界面的美觀。前面的程序中都是使用UI界面拖控件,如果有多個按鈕,會出現(xiàn)大小難調(diào)整、位置難對齊等問題。Qt 提供的“布局管理“就很好的解決了控件擺放的問題。

以下是UI設(shè)計師界面的布局相關(guān)控件組:

image-20240304140914361

功能介紹:

(1)Vertical Layout:垂直布局

(2)Horizontal Layout:水平布局

(3)Grid Layout:網(wǎng)格布局

(4)Form Layout:窗體中布局

(5)Horizontal Spacers:水平空格,在布局中用來占位。

(6)Vertical Spacer:垂直空格,在布局中用來占位。

image-20240304140956243

3.11 基本布局控件

在UI設(shè)計界面添加一個布局控件,然后將需要布局的其他控件放入布局控件中即可完成布局,布局控件可以互相嵌套使用。(本節(jié)只介紹基本布局控件的使用)

以下是4種布局控件的效果:

image-20240304141035428

3.12 UI設(shè)計師的布局功能

在UI設(shè)計界面的左上角有一排快捷的布局選項,使用時選中兩個以上的控件,點擊其中一種布局方式就可以切換布局。

以下為布局的簡單示例圖:

image-20240304141115657

(1)為布局的選項。

(2)控件層次圖,可以看到控件的布局擺放層次。

如果想要控制某個控件的固定大小,不隨著布局改變大小,可以限定最大最小尺寸。選中控件鼠標右鍵–>大小限定->設(shè)置大小。

image-20240304141311256

水平布局與垂直布局:

image-20240304141335977

image-20240304141347209

水平布局將控件按照水平方式擺放,垂直布局將控件按照垂直方式擺放。鼠標拖動紅色布局框上的黑色方點,可以調(diào)整布局框的大小。隨著布局框的尺寸變化,包含的控件高度不會變化,寬度會隨著布局框變化。選中其中一個控件然后鼠標右鍵>點擊大小限定,可以限定控件的最大和最小尺寸。

分裂器水平布局與垂直布局:

image-20240304141412287

image-20240304141426088

分裂器方式布局,包含控件的高度和寬度都會隨著布局框的拉伸而改變。選中其中一個控件然后鼠標右鍵>點擊大小限定,可以限定控件的最大和最小尺寸。

窗體中布局與柵格布局:

image-20240304141449390

柵格(網(wǎng)格)布局器的基本單元是單元格,而窗體中布局(表單)的基本單元是行。隨著布局框的尺寸變化,包含的控件高度不會變化,寬度會隨著布局框變化。

設(shè)置主窗體布局方式:

設(shè)置主窗體的布局方式后,包含在主窗體內(nèi)的控件會隨著窗體的拉伸自動調(diào)整大小。

image-20240304141518067

image-20240304141529003

四、上位機開發(fā)

4.1 Qt開發(fā)環(huán)境安裝

Qt的中文官網(wǎng): https://www.qt.io/zh-cn/image-20221207160550486

image-20221207160606892

QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6

打開下載鏈接后選擇下面的版本進行下載:

如果下載不了,可以在網(wǎng)盤里找到安裝包下載: 飛書文檔記錄的網(wǎng)盤地址:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

軟件安裝時斷網(wǎng)安裝,否則會提示輸入賬戶。

安裝的時候,第一個復(fù)選框里的編譯器可以全選,直接點擊下一步繼續(xù)安裝。

image-20221203151742653

選擇編譯器: (一定要看清楚了)

image-20241028152725134

4.2 新建上位機工程

前面2講解了需要用的API接口,接下來就使用Qt設(shè)計上位機,設(shè)計界面,完成整體上位機的邏輯設(shè)計。

【1】新建工程

image-20240117144052547

【2】設(shè)置項目的名稱。

image-20250420200347498

【3】選擇編譯系統(tǒng)

image-20240117144239681

【4】選擇默認繼承的類

image-20240117144302275

【5】選擇編譯器

image-20241028153603487

【6】點擊完成

image-20240117144354252

【7】工程創(chuàng)建完成

image-20250420200411303

4.3 切換編譯器

在左下角是可以切換編譯器的。 可以選擇用什么樣的編譯器編譯程序。

目前新建工程的時候選擇了2種編譯器。 一種是mingw32這個編譯Windows下運行的程序。 一種是Android編譯器,可以生成Android手機APP。

不過要注意:Android的編譯器需要配置一些環(huán)境才可以正常使用,這個大家可以網(wǎng)上找找教程配置一下就行了。

windows的編譯器就沒有這么麻煩,安裝好Qt就可以編譯使用。

下面我這里就選擇的 mingw32這個編譯器,編譯Windows下運行的程序。

image-20250420200424965

4.4 編譯測試功能

創(chuàng)建完畢之后,編譯測試一下功能是否OK。

點擊左下角的綠色三角形按鈕。

image-20250420200442769

正常運行就可以看到彈出一個白色的框框。這就表示工程環(huán)境沒有問題了。 接下來就可以放心的設(shè)計界面了。

image-20250420200457319

4.5 設(shè)計UI界面與工程配置

【1】打開UI文件

image-20250420200514220

打開默認的界面如下:

image-20250420200526194

【2】開始設(shè)計界面

根據(jù)自己需求設(shè)計界面。

五、STM32代碼設(shè)計

5.1 硬件連線說明

序號 傳感器模塊 信號類型 接STM32引腳 說明
1 紅外避障傳感器 ×3 數(shù)字輸入 PA0(前) PA1(左) PA2(右) 高電平=障礙物,低電平=無障礙
2 超聲波測距模塊 HC-SR04 數(shù)字IO TRIG: PB0 ECHO: PB1 發(fā)送/接收測距信號
3 紅外跌落傳感器 ×3 數(shù)字輸入 PA3(前) PA4(左) PA5(右) 高電平=懸空,低電平=有地面
4 MPU6050 姿態(tài)模塊 I2C通信 SDA: PB7 SCL: PB6 默認地址0x68
5 灰塵傳感器 GP2Y1010 模擬輸出 PA6 連接ADC采集灰塵濃度
6 DS3231 RTC時鐘模塊 I2C通信 SDA: PB7 SCL: PB6 與MPU6050共用I2C總線
7 電壓檢測模塊 模擬輸出 PA7 電池電壓模擬量檢測
8 DFPlayer Mini語音模塊 串口通信 TX: PA9 RX: PA10 使用USART1
9 ESP8266通信模塊 串口通信 TX: PB10 RX: PB11 使用USART3
10 OLED 顯示屏(0.96寸) I2C通信 SDA: PB9 SCL: PB8

5.2 傳感器代碼

當(dāng)前項目使用的相關(guān)軟件工具已經(jīng)上傳到網(wǎng)盤:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

1. GPIO 輸入配置(避障、跌落)

void GPIO_Sensor_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    // 避障與跌落傳感器輸入引腳:PA0~PA5
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

2. ADC 模擬輸入配置(灰塵濃度、電壓檢測)

void ADC_Init(void)
{
    ADC_HandleTypeDef hadc1;

    __HAL_RCC_ADC1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;  // PA6:灰塵,PA7:電壓
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    hadc1.Instance = ADC1;
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    HAL_ADC_Init(&hadc1);
}

讀取ADC值函數(shù)(灰塵或電壓):

uint16_t Read_ADC_Value(ADC_HandleTypeDef* hadc, uint32_t channel)
{
    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = channel;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
    HAL_ADC_ConfigChannel(hadc, &sConfig);

    HAL_ADC_Start(hadc);
    HAL_ADC_PollForConversion(hadc, HAL_MAX_DELAY);
    uint16_t value = HAL_ADC_GetValue(hadc);
    HAL_ADC_Stop(hadc);

    return value;
}

3. 超聲波測距控制(TRIG/ECHO)

#define TRIG_PIN    GPIO_PIN_0
#define TRIG_PORT   GPIOB
#define ECHO_PIN    GPIO_PIN_1
#define ECHO_PORT   GPIOB

void Ultrasonic_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitStruct.Pin = TRIG_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = ECHO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
}

uint32_t Read_Ultrasonic(void)
{
    uint32_t t1, t2;

    HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
    HAL_Delay(1);
    HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
    HAL_Delay(0.01);
    HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);

    while(HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET);
    t1 = DWT->CYCCNT;
    while(HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_SET);
    t2 = DWT->CYCCNT;

    return (t2 - t1) / 72 / 58;  // 距離 cm(STM32 72MHz)
}

4. MPU6050、RTC、OLED 初始化建議(使用 I2C)

// I2C2 for MPU6050 + RTC
hi2c2.Instance = I2C2;
hi2c2.Init.ClockSpeed = 400000;
hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c2);

5. 串口初始化(語音/ESP8266通信)

// USART1 (PA9/PA10) for DFPlayer
// USART3 (PB10/PB11) for ESP8266

void UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart1);

    huart3.Instance = USART3;
    huart3.Init.BaudRate = 115200;
    huart3.Init.WordLength = UART_WORDLENGTH_8B;
    huart3.Init.StopBits = UART_STOPBITS_1;
    huart3.Init.Parity = UART_PARITY_NONE;
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart3.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart3);
}

5.3 項目核心代碼

當(dāng)前項目使用的相關(guān)軟件工具已經(jīng)上傳到網(wǎng)盤:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

(1)main.c 核心主流程框架

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "i2c.h"
#include "adc.h"
#include "tim.h"
#include "oled.h"
#include "motor.h"
#include "sensor.h"
#include "wifi.h"
#include "voice.h"
#include "rtc.h"
#include "mpu6050.h"
#include "path_planning.h"

void SystemClock_Config(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();

    // 初始化外設(shè)
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_USART3_UART_Init();
    MX_ADC1_Init();
    MX_I2C1_Init();
    MX_I2C2_Init();
    MX_TIM2_Init();
    MX_TIM3_Init();

    // 模塊初始化
    OLED_Init();
    Motor_Init();
    Sensor_Init();
    Voice_Init();
    MPU6050_Init();
    RTC_Init();
    WiFi_Init();

    OLED_ShowString(0, 0, "Robot Start");
    Voice_Play(1); // 播放“啟動成功”

    while (1)
    {
        if (RTC_CheckSchedule())  // 是否到達清掃時間
        {
            Clean_Start();
        }

        WiFi_Handle();  // MQTT通信處理

        HAL_Delay(100);  // 輪詢
    }
}

(2)掃地邏輯主控制 Clean_Start()

void Clean_Start(void)
{
    OLED_ShowString(0, 1, "Cleaning...");
    Voice_Play(2); // “開始清掃”

    PathPlanner_Init(); // 初始化路徑柵格

    while (!PathPlanner_Finished())
    {
        if (Sensor_IsFallDetected())
        {
            Motor_Stop();
            Voice_Play(3);  // “檢測到邊緣”
            Clean_EscapeEdge();
            continue;
        }

        if (Sensor_IsObstacleAhead())
        {
            Motor_Stop();
            Voice_Play(4);  // “前方有障礙”
            Clean_AvoidObstacle();
            continue;
        }

        if (Battery_Low())
        {
            Motor_Stop();
            Voice_Play(5);  // “電量不足,返回充電”
            Go_To_ChargingDock();
            return;
        }

        PathPlanner_Move();  // 路徑規(guī)劃并移動
        Sensor_CheckDustLevel(); // 檢測灰塵情況,決定清掃強度
        WiFi_UploadStatus();  // 上傳當(dāng)前位置與狀態(tài)
        HAL_Delay(100);
    }

    OLED_ShowString(0, 1, "Done!");
    Voice_Play(6); // “清掃完成”
    Go_To_ChargingDock();
}

(3)邊緣檢測與防跌落處理函數(shù)

void Clean_EscapeEdge(void)
{
    Motor_Backward();
    HAL_Delay(500);
    Motor_TurnRight();
    HAL_Delay(300);
    Motor_Stop();
}

(4)避障處理函數(shù)

void Clean_AvoidObstacle(void)
{
    Motor_Backward();
    HAL_Delay(300);
    Motor_TurnLeft();
    HAL_Delay(500);
    Motor_Stop();
}

(5)路徑規(guī)劃(Z字遍歷)

int map[20][20];
int cur_x = 0, cur_y = 0, dir = 1;

void PathPlanner_Init(void)
{
    memset(map, 0, sizeof(map));
    cur_x = 0;
    cur_y = 0;
    dir = 1;
}

void PathPlanner_Move(void)
{
    map[cur_y][cur_x] = 1; // 標記已清掃

    int next_x = cur_x + (dir == 1 ? 1 : -1);
    if (next_x >= 0 && next_x < 20)
    {
        cur_x = next_x;
    }
    else
    {
        cur_y++;
        dir = -dir;
    }

    Motor_Forward();
    HAL_Delay(200);
    Motor_Stop();
}

int PathPlanner_Finished(void)
{
    return cur_y >= 20;
}

(6)傳感器檢測函數(shù)(sensor.c

uint8_t Sensor_IsFallDetected(void)
{
    return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_SET ||  // 前
           HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_SET ||  // 左
           HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_SET;    // 右
}

uint8_t Sensor_IsObstacleAhead(void)
{
    return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET;  // 前避障傳感器
}

void Sensor_CheckDustLevel(void)
{
    uint16_t val = ADC_ReadValue(ADC_CHANNEL_6); // GP2Y1010 on PA6
    if (val > 3000)
    {
        Motor_SetSpeed(HIGH); // 增強清掃
    }
    else
    {
        Motor_SetSpeed(NORMAL);
    }
}

(7)語音提示控制(DFPlayer)

void Voice_Play(uint8_t track)
{
    uint8_t cmd[] = {0x7E, 0xFF, 0x06, 0x03, 0x00, 0x00, track, 0xEF};
    HAL_UART_Transmit(&huart1, cmd, sizeof(cmd), 100);
}

(8)WIFI與MQTT通信處理

void WiFi_Handle(void)
{
    if (ESP8266_ReceiveMQTT("robot/ctrl") == CMD_STOP)
    {
        Motor_Stop();
        Voice_Play(7); // “收到停止命令”
    }
}

void WiFi_UploadStatus(void)
{
    char buf[64];
    sprintf(buf, "{"x":%d,"y":%d,"bat":%d}", cur_x, cur_y, Battery_GetLevel());
    ESP8266_PublishMQTT("robot/status", buf);
}

(9)回充定位處理

void Go_To_ChargingDock(void)
{
    // 簡化邏輯:持續(xù)前進直到檢測到紅外充電基座信號
    while (!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12)) // 充電基座紅外
    {
        Motor_Forward();
        HAL_Delay(100);
    }
    Motor_Stop();
    Voice_Play(8); // “已回到充電樁”
}

5.4 程序下載

也有視頻教程:

講解如何編譯代碼,下載STM32程序: https://www.bilibili.com/video/BV1Cw4m1e7Yc

打STM32的keil工程,編譯代碼、然后,使用USB線將開發(fā)板的左邊的USB口(串口1)與電腦的USB連接,打開程序下載軟件下載程序。

具體下載過程看下面圖:

image-20240319223247836

打開程序下載軟件:[軟件就在資料包里的軟件工具目錄下]

image-20240120160735942

5.5 程序正常運行效果

設(shè)備運行過程中會通過串口打印調(diào)試信息,我們可以通過串口打印了解程序是否正常。

程序下載之后,可以打開串口調(diào)試助手查看程序運行的狀態(tài)信息。[軟件就在資料包里的軟件工具目錄下]

image-20240327212042050

5.6 取模軟件的使用

顯示屏上會顯示中文,字母,數(shù)字等數(shù)據(jù),可以使用下面的取模軟件進行取模設(shè)置。

[軟件就在資料包里的軟件工具目錄下]

image-20241024142522970

打開軟件之后:

image-20241127212320020

六、總結(jié)

本項目以STM32F103RCT6為核心控制器,完成了一套功能完善、運行穩(wěn)定的掃地機器人系統(tǒng)設(shè)計與實現(xiàn)。系統(tǒng)融合了路徑規(guī)劃、障礙物避讓、邊緣檢測、防跌落控制、灰塵識別、自動回充、定時清掃、狀態(tài)顯示與語音提示等多種功能,具備較強的環(huán)境適應(yīng)性與實用性。整機通過多傳感器協(xié)同感知環(huán)境變化,并結(jié)合智能算法進行決策,使得機器人能高效、安全地完成全覆蓋式清掃任務(wù)。

在系統(tǒng)軟硬件設(shè)計方面,充分發(fā)揮了STM32微控制器資源豐富、接口靈活、運算能力強等優(yōu)勢。硬件模塊選型明確,接口連接合理,保障了系統(tǒng)穩(wěn)定運行。軟件部分采用模塊化開發(fā)思路,邏輯清晰,功能劃分明確,便于后期維護與擴展。同時,通過ESP8266模塊實現(xiàn)了與手機APP之間的遠程通信,增強了用戶交互能力和系統(tǒng)智能化水平。

通過本項目的開發(fā)與調(diào)試,進一步驗證了STM32在智能機器人應(yīng)用中的可行性和實用性,提升了開發(fā)者在嵌入式系統(tǒng)設(shè)計、智能控制、通信協(xié)議、傳感器融合等方面的綜合能力。項目成果在家庭清潔機器人領(lǐng)域具有良好的推廣價值和應(yīng)用前景。

  • 更多詳細資料請聯(lián)系.docx
    下載
意法半導(dǎo)體

意法半導(dǎo)體

意法半導(dǎo)體(ST)集團于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導(dǎo)體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導(dǎo)體有限公司。意法半導(dǎo)體是世界最大的半導(dǎo)體公司之一,公司銷售收入在半導(dǎo)體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(17%),計算機(16%),汽車(16%),工業(yè)(16%)。 據(jù)最新的工業(yè)統(tǒng)計數(shù)據(jù),意法半導(dǎo)體是全球第五大半導(dǎo)體廠商,在很多市場居世界領(lǐng)先水平。例如,意法半導(dǎo)體是世界第一大專用模擬芯片和電源轉(zhuǎn)換芯片制造商,世界第一大工業(yè)半導(dǎo)體和機頂盒芯片供應(yīng)商,而且在分立器件、手機相機模塊和車用集成電路領(lǐng)域居世界前列.

意法半導(dǎo)體(ST)集團于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導(dǎo)體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導(dǎo)體有限公司。意法半導(dǎo)體是世界最大的半導(dǎo)體公司之一,公司銷售收入在半導(dǎo)體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(17%),計算機(16%),汽車(16%),工業(yè)(16%)。 據(jù)最新的工業(yè)統(tǒng)計數(shù)據(jù),意法半導(dǎo)體是全球第五大半導(dǎo)體廠商,在很多市場居世界領(lǐng)先水平。例如,意法半導(dǎo)體是世界第一大專用模擬芯片和電源轉(zhuǎn)換芯片制造商,世界第一大工業(yè)半導(dǎo)體和機頂盒芯片供應(yīng)商,而且在分立器件、手機相機模塊和車用集成電路領(lǐng)域居世界前列.收起

查看更多

相關(guān)推薦