左右モータを駆動させるためのPWMをSTM32F446から出力します。
駆動させるPWM周波数が同じであれば、1つのタイマーから4ピン分のPWMが出力できます。
回路図
TI製モータドライバDRV8424Pで構成した回路図はこちらです。回路図の詳細説明は過去のブログを参照してください。
マイコンに繋げたピンは、PWMを出力する4ポート(PA0~3)と、nSLEEPピンを出力する1ポート(PA6)、エラー値を入力する1ポート(PA7)の合計6つとなります。
STM32CubeMX
CubeMXのPWMの設定です。
鉄鼠では、PWMを生成するタイマーはTIM2を使います。TIM2に使うタイマーのベースクロックは、APB1 Timer clocksになるのでSTM32F446の最高設定90MHzになるようにしました。
nSLEEPとnFAULTはそれぞれGPIOのOutとInだけ設定。また、プログラムをわかりやすくするためUser Lablを回路図のラベルと同じになるよう変更します。エラー表示用にD1もGPIO_Outに設定。
PWMの周期をモータドライバの入力限界である100kHzになるよう設定。
PWM周波数=(クロックソース/プリスケーラ)/カウンタピリオド
100,000=(90,000,000/2)/450
Prescaler:2-1=1
Counter Reriod:450-1=449
2022年7月改善案:
100,000=(90,000,000/1)/900
Prescaler:1-1=0
Counter Reriod:900-1=899
モータPWM周波数
後ほどわかったのですが、1717T003SR-3Vのスペックでは、電気的時定数が速すぎるため、PWM周波数100kHzなら、数十uHのインダクタを直列で追加して電気的時定数を遅くしたり、そもそもインダクタ値が大きい1717T003SR-6Vにするとかにすれば、電流リップルが小さくなり、電力制御の向上やモータの発熱を抑えられるようです。
DCモータ1717T003SR-3V:
端子間抵抗1.07Ω
インダクタ17uH
モータドライバDRV8424P:
Ron抵抗0.33Ω
電気的時定数Te = インダクタンスL / 総合抵抗R = 17[uH] / (1.07+0.33)[Ω] ≒ 12.14[us]
アニキさんの「PWM周波数を高くすると低速域でトルクが出ない」とか、小島さんの「20kHzにしてみた.改善した.」などの話題があります。それらの原因と思われるのは、最近だとこうへいさんの「LAP方式とSMB方式」「デッドタイムの影響」の話が有力そうです。
PWM周波数を落とすと、Decayモードによっては電流不連続モードになるので、バッテリの電圧降下によるマイコンのAD変換時定数の計測誤差も考慮する必要があるかもという話もあり、想定しておくことが多くてとても頭痛が痛いです。小型で2chの電流制御ICとか早く出て欲しい。
Decay Modeを省エネっぽい「Smart tune Ripple Control Decay Mode」にしていますが、実際に走らせて、後でパターンカットして「Mixed Decay Mode」に変更したりするかもしれません。
プログラム
HAL_TIM_PWM_Start関数と、HAL_TIM_SET_COMPARE関数を使います。
/* USER CODE BEGIN 2 */ HAL_GPIO_WritePin(nSLEEP_GPIO_Port, nSLEEP_Pin, GPIO_PIN_SET); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4); /* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_GPIO_ReadPin(nFAULT_GPIO_Port, nFAULT_Pin)==0){ //Motor Driver Error HAL_GPIO_TogglePin(D1_GPIO_Port, D1_Pin); } else{ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 30); //Left motor Forward __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0); //Left motor Back __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); //Right motor Back __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 30); //Right motor Forward HAL_Delay(1000); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0); //Left motor Forward __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 30); //Left motor Back __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 30); //Right motor Back __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 0); //Right motor Forward } HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
実行
簡易オシロでPWM100kHzのデューティ比30/450が出ているか確認します。オシロだと30/45usになっています。
(改善:60/899)
床に置いて走らせた動画です。
デューティ比1/2で実行して、タイヤを押さえつけたときの動画です。
LEDが点滅します。そして、電源をON/OFFしても点滅したままです…
嫌な予感…
さてさて、次はエンコーダ入力の確認をします。
参考URL


