1. 程式人生 > 其它 >用STM32F401和nRF24L01做無線調速小車

用STM32F401和nRF24L01做無線調速小車

硬體配置

在做這個小專案前, 深入考察過STM32F103C8T6, STM32F401CCU6和STC89C52這三個MCU, 並實際跑了一些用例

  • STC89C52在程式碼上要簡單得多, 它的問題是沒有ADC功能, 所以無法用於遙控器部分, 只能用於小車部分, 而且PWM輸出是軟輸出, 通過主迴圈實現的.
  • STM32F103C8T6的功能應對這個專案沒問題, 在網上這個型號的程式碼特別豐富, 問題在於現在價格太貴了, 一個原裝晶片的最小系統板價格為38RMB, CH版也要25RMB, 相對於高一代且系統板價格僅為15RMB的STM32F401CCU6沒有優勢.
  • STM32F401CCU6的劣勢是程式碼, 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的排針上, 另一個排針是地線.

小車部分

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

硬體部分的說明

  • 電機用的是普通的48:1減速電機, 工作電壓為6V, 另外L9110s雖然標稱能到12V, 市面上的L9110s大部分到不了這麼高, 安全電壓在7V左右, 所以這裡需要將電壓降到6V附近, 通過兩個1N4007能產生1.2V的壓降
  • 執行時每個電機的電流為0.15A, 合計0.6A, STM32F401,nRF24L01的耗電可以忽略不計, 1N4007的工作電流為1A, 應該是夠的
  • 因為有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的處理, 會卡在這個延時函式上, 將這個延時處理刪除後就未再出現這個情況

參考