用STM32F401和nRF24L01制作無線調速小車


硬件配置

在做這個小項目前, 考察過STM32F103C8T6, STM32F401CCU6STC89C52這三個MCU, 並實際跑了一些用例

  • STC89C52在代碼上要簡單得多, 它的問題是沒有ADC功能, 所以無法用於遙控器部分, 只能用於小車部分, 而且PWM輸出是軟輸出, 通過主循環實現的. 帶ADC功能的STC單片機型號有STC12C5A系列和STC15F, STC15W系列, 但是現在市場價格都很貴, 單單芯片就需要22RMB.
  • STM32F103C8T6的功能應對這個項目沒問題, 在網上這個型號的代碼特別豐富, 問題在於現在價格太貴了, 一個原裝芯片的最小系統板價格為38RMB, CH版也要25RMB, 相對於高一代且系統板價格僅為15RMB的STM32F401CCU6沒有優勢.
  • STM32F401CCU6最小系統板價格15RMB, 功能應對這個項目沒有問題, 它的劣勢是可參考的資料少. STM32F4系列在國內使用的較少, 代碼例子在網上少並且很多是針對F407這些高級型號的, 如果用在F401上需要額外的調整.

最終選擇的是STM32F401CCU6, 代碼上的問題都不是問題, 對嗎?

遙控器部分

  • 電源: 3.7V 18650鋰電
  • 3.3V穩壓: 一個1N4148二極管
  • MCU: STM32F401CCU6最小系統板
  • 輸入: 雙軸搖桿模塊
  • 無線: nRF24L01模塊

硬件部分的說明

  • 1N4148能產生0.6V的壓降, 對於3.7V的鋰電來說是足夠的, 實際測試18650兩端電壓約4.0V, 通過1N4148后輸出的電壓是3.2V. STM32F401CCU6, nRF24L01和雙軸搖桿耗電量都非常小, 1N4148應付這個沒問題.
  • 因為單節18650電池盒輸出線是裸的多芯軟線, 不方便直接連到模塊上, 並且因為這部分兩個模塊nRF24L01和雙軸搖桿都需要用到3.3V電壓, 所以另外用萬能板做了一個中轉, PCB接線端子用來連接電源線, 3V3通過一個1N4148后接到3V3的排針上, 另一個排針是地線.
  • 這個接線端子是從炸掉的L9110s模塊上拆的

小車部分

  • 電源: 7.4V (18650鋰電x2)
  • 6V穩壓: 串聯兩個IN4007
  • 3.3V穩壓: AMS1117 3.3V模塊
  • MCU: STM32F401CCU6
  • 無線: nRF24L01模塊
  • 電機驅動: L9110雙路x2
  • 小車底盤
  • 48:1減速電機x4

硬件部分的說明

  • 電機用的是普通的48:1減速電機, 工作電壓為6V, 另外L9110s雖然標稱能到12V, 市面上的L9110s大部分到不了這么高, 安全電壓在7V左右, 所以這里需要將電壓降到6V附近, 通過兩個1N4007能產生1.2V的壓降
  • 運行時每個電機的電流為0.15A, 合計0.6A, STM32F401,nRF24L01的耗電可以忽略不計, 1N4007的工作電流為1A, 應該是夠的
  • STM32需要的3.3V和電源電壓相差較遠, 直接用AMS1117模塊做降壓了
  • 因為有4個電機, 所以需要兩個雙通道L9110s模塊
  • 電池盒引出的是裸的多芯軟線, 不方便直接連到模塊上, 因此另外用萬能板做了個中間板, 加了接線端子連接電池盒, 正極串聯兩個1N4007輸出到正極排針, 另外還有地線排針, 以及四組排針用於L9110s的輸入(各側的兩個通道共用一組PWM)

接線

遙控器部分

MCU需要的接口如下

  • UART: 方便調試
    • PA9 => USB2TTL的RX
    • PA10 => USB2TTL的TX
  • SPI: 連接nRF24L01
    • PA5,PA6,PA7, PB13,PB14,PB15
  • ADC: 兩個pin, 連接雙軸搖桿
    • PA0 => 搖桿AXIS X
    • PA1 => 搖桿AXIS Y
  • VCC
  • GND

與nRF24L01的接線

STM32 nRF24L01
PA4 SPI1_NSS N/A
PA5 SPI1_SCK SCK
PA6 SPI1_MISO MISO
PA7 SPI1_MOSI MOSI
PB13 IRQ
PB14 CE
PB15 CSN

小車部分

MCU需要的接口如下

  • UART: 方便調試
    • PA9,PA10, 同上
  • SPI: 連接nRF24L01
    • PA5,PA6,PA7, PB13,PB14,PB15
  • PWM: 4個pin, 輸出4組PWM, 分別對應左右側的兩組 L9110
    • PA0,PA2: 左側電機
    • PA1,PA3: 右側電機

nRF24L01接線同上.

功能實現

遙控器部分

這一塊主要是通過兩個ADC通道采集搖桿電壓, ADC采集使用的DMA的模式, 在主循環中定時(幾十到幾百毫秒)去讀取電壓, 並轉換到[0, FF]區間, 通過nRF24L01發射出去. ADC采集電壓時, 每個通道使用4個u16做緩存, 輸出的數值是對這個4個數值做平均, 抑制抖動.

涉及的技術名詞: UART, ADC, DMA, TIMER, SPI

小車部分

小車部分的功能有幾部分:

  1. nRF24L01的中斷接收. 需要將nRF24L01的接收配置為中斷模式, 這樣只有在遙控端發出指令時, 小車才做相應的動作, 相比在循環中檢測接收信息並調整輸出的實現方式更及時高效.
  2. PWM輸出控制小車的速度和方向.
  3. 將接收得到的X軸Y軸向量, 映射到兩路電機的方向和強度.

涉及的技術名詞: UART, TIMER, EXTI, SPI, PWM
以下具體說明

nRF24L01的中斷接收

這部分需要在STM32上新增一個EXTI中斷源, 映射到nRF24L01的IRQ PIN腳. 這個中斷是低電平觸發, 注意在處理完中斷后, 需要清空接收緩沖, 不然下一次還會讀到舊值.
中斷處理的方法內根據接收到的數值調整PWM輸出, 實現遙控功能.

這里還有一個定時器TIM3, 當前設置的定時時間為0.5秒, 每次中斷處理時會將定時器初始化, 在定時器經過0.5秒后觸發時, 會將PWM輸出歸零, 歸零后電機都會停止. 通過這個機制, 在遙控器發出指令后小車會在當前指令下輸出PWM 0.5秒, 如果持續收到指令則持續輸出, 如果未收到指令, 則在0.5秒后停止輸出, 體現在小車運動上, 就是每次指令下小車會移動0.5秒.

PWM輸出控制速度和方向

PWM的頻率選擇: 48:1減速電機是淘寶上最便宜常見的減速電機, 最佳PWM頻率是25Hz-50Hz. 這個頻率的來源在這里, 里面有很詳細的說明和實驗測試結果. 我把我關心的部分內容翻譯了一下, 可以看這里. 我在實際使用中觀察到的結果是符合這篇文章的結論的.

這里多說幾句. 關於電機的PWM頻率選擇, 在網上查了很久, 得到的結果大部分是錯誤的, 很多人文章里寫的頻率是6-20KHz. 這里需要注意區分一下, 如果你用的是直流有刷電機, 那么用這么高的PWM頻率是會出問題的, 建議在幾十到幾百Hz的范圍去測試.

PWM控制速度比較好理解, 但是控制方向的具體實現需要通過兩個PWM配合. 嘗試過通過1路PWM+1路GPIO進行方向切換, 但是無法正常工作, 最后還是要通過兩路PWM. 根據方向, 設置其中一路PWM輸出為0. 這里為了避免出現雙高電平(網上有很多人提到雙高導致L9110s燒毀), 在程序中先設置輸出為0的一路PWM, 再輸出另一路不為0的PWM.

X軸Y軸向量映射到左右兩路電機

這一塊花了我一些時間. 在網絡上找到的資料看, 實現方式更多是通過Y軸計算出左右電機整體的前進后退占空比, 然后通過X軸計算左右電機占空比差值, 再將這兩個結果疊加, 得到最后的左右電機占空比. 這個計算方式的問題是當工作點在Y軸區間兩端的時候, 此時疊加的差值會使Y軸的值超出區間, 但是實際上這個數值是不可能的, 所以要么將兩個通道的數值都往回拉, 要么就忽略Y軸超出區間的部分, 都不是很合理.

我使用的計算方式, 是先規定搖桿圓周4個方向上對應LR通道的值:

  • 0° => L:FF, R:-FF
  • 90° => L:FF, R:FF
  • 180° => L:-FF, R:FF
  • 270° => L-FF, R:-FF

將搖桿得到的XY軸的值做成向量, 將這個向量投影為圓周上某一點, 再根據圓周上這個點兩端的值計算當前點的LR值.

因為搖桿得到的XY軸空間, 實際上是一個正方形, 將其映射到圓上時, 有一個有趣的現象, 當角度位於0°到45°時, 向量的長度等於X軸的值, 而在45°到90°時, 向量長度等於Y軸的值, 這個使得計算簡便了許多.

遇到的問題

L9110s發熱燒毀

電源為兩節18650, 電壓為3.7x2=7.4V, 兩路pwm輸出, 當從0,0 -> 0,全速時, 電機無動作, L9110s發燙然后冒煙燒毀. 這個直接導致兩個模塊各燒了一片L9110s. 於是上網查相關的資料

相關的討論

因為模塊已經帶了輸出電容和上拉電阻, 所以
可能的原因是

  1. 電機啟動電流過大導致模塊燒毀. 電機靜態電阻為6.5Ω, 電壓7.4V時電流超過1A,
    應對方案: 串聯一個5Ω的限流電阻, 可以將電流降到7.4/(6.5+5)=0.64A, 避免超出L9110s的最大電流, 運轉中的電機阻抗為40Ω - 45Ω, 此時電阻上的分壓不到1V, 影響不大.
  2. L9110s耐壓超限. 有人說最高到6.5V.
    應對方案: 在L9110s輸入電壓前串聯2個1N4007, 將電壓降到7.4-1.4=6V, 串聯2個時,啟動電流1A,正向電阻0.7Ω, 空轉時0.15A,正向電阻5Ω
  3. PWM頻率過高. 過高的PWM頻率會導致電機在低占空比時無法啟動,
  4. PWM同時輸出高電平

最終解決方案

  1. 串聯兩個1N4007將電壓降到6.2V
  2. PWM頻率降到100Hz

有些占空比下電機不動

在逐漸增大占空比的過程中, 有些值下電機不轉, 能聽到吱吱聲, 如果手摸着L9110s芯片, 能感覺到此時有一陣發燙, 所以此時電流到位了, 但是沒能驅動電機.

這個原因和前一個問題是一樣的, 因為PWM頻率過高(17.5KHz), 無法驅動電機, 在將頻率降到100Hz后這個問題就沒再出現.

小車在運行一段時間后中斷燈常亮, 失去響應

經過檢查, 是因為在處理nRF24L01接收中斷時, 加入了一個延時1ms的處理, 會卡在這個延時函數上, 將這個延時處理刪除后就未再出現這個情況

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM