モータドライブ部の製作
回路設計
ステアリングに続いて、モータドライブ部の回路を設計します。
モータドライバは市販の基板を買ってきて使おうかと思っていましたが、車両のサイズに対して大きすぎるので、部品箱を探したら、昔買った東芝TA7291Pが出てきたのでこれを使うことにしました。
IN1とIN2のピンにそれぞれHigh、Lowを与えることで、正転、逆転、停止、ブレーキなどの4つの動作モードを切り替えられます。
速度はどうやって変えるか?というと、Vrefというピンに与える電圧を可変することで、モータへの供給電圧が制御できるようです。DCモータなので、単純に電圧を上げれば回転数が上昇し、電圧を下げれば回転数も下がります。
最初はESP32でPWMを出力し、ローパスフィルタを通すことで、Vrefに供給するアナログ電圧を制御しようかと思いましたが、ESP32にはD/Aコンバータが2chついていることに気づき、これを使うことにしました。
製作したものの全体ブロック図です。

モータは定格が3Vぐらいのもの(単3電池×2)ですので、5Vから3.3Vを作る三端子レギュレータを入れましたが、後で考えたらESP32は3.3V系なので、Vrefに供給するDACの最大値も3.3V以上出ず、必然的にモータ供給電圧も3.3V以下になりますね。よって、三端子REGはいらなかったかも。
また、TA7291Pのロジック系は5V動作なので、IN1とIN2の信号は5V系にする必要があります。
前述したように、ESP32は3.3V系なので、トランジスタで簡単なレベル変換回路を作りました。

ただし、論理が反転してまうので、ソフト側で意図的に反転させて出力する必要があります。
回路の製作
部品は全部、家にストックしてあるものですので、回路定数とかはいい加減です。
(トランジスタとかは、何かの基板から型番もわからないものを取り外したりしたもの。。)
とりあえず、搭載とかは後で考えるとして、一気に製作です。
完成写真がこちら。

裏面側。

ソフト設計
作成したソフトは以下です。
なんとなく、バックするときは直進時より速度を落とした方が良いかなと思い、バック時はVrefの上限を直進時より下げてます。
またデータシートに、正転、逆転などの入力切り替え時にSTOPモードを100μs入れて下さいとの記述があるため、ジョイスティックがゼロ付近を通る際に少しディレイ(10ms)を持たせました。
勢いで作ってますので汚いコードかもしれませんが、とりあえず個人の趣味の為、動けばOKとします。
#include<ESP32Servo.h>
#include <Ps3Controller.h>
#define SERVO_OUT 5 //5PINをサーボ用PWM
#define DAC1 25 //25PINをDAC
#define IN1 17 //16PINをTA7291のIN1
#define IN2 16 //17PINをTA7291のIN2
#define VREF_MAX_CW 232 // 正転方向の速度制限 3.3V * 232 /255 = 3.0V
#define VREF_MAX_CCW 127 // 逆転方向の速度制限 3.3V * 127 /255 = 1.64V
#define INIT_ANGLE 90 //初期サーボ角
Servo myServo;
int joy_left_y; //左ジョイスティックのy軸
int joy_right_x; //右ジョイスティックのx軸
int servo_angle; //サーボ角
int vref; //TA7291のVref 入力電圧 0~255 0~3.3V
const float joy2servo = 0.2344f; //ジョイスティック読み値 to サーボ角 変換ゲイン
void setup() {
myServo.attach(SERVO_OUT);
myServo.write(INIT_ANGLE); //サーボを初期位置へ
Ps3.begin("##:##:##:##:##:##"); //PS3コントローラに書き込んだMACアドレス
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
digitalWrite(IN1,HIGH); //トランジスタでレベル変換(3.3V⇒5V)するので、論理を逆にする。
digitalWrite(IN2,HIGH); //同上
vref = 0;
dacWrite(DAC1,vref);
}
void loop() {
if(!Ps3.isConnected())
return;
//--------------------------------------//
// 左側ジョイスティックのy軸制御 //
//--------------------------------------//
if( Ps3.event.analog_changed.stick.ly ){
joy_left_y = Ps3.data.analog.stick.ly;
//ジョイスティック値をVREF値へ変換
vref = abs(joy_left_y * 2);
//------正転制御-------//
if(joy_left_y < -10){
//vrefの制限
if(vref > VREF_MAX_CW)
vref = VREF_MAX_CW;
dacWrite(DAC1,vref);
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
}
//------逆転制御--------//
else if(joy_left_y > 10){
//vrefの制限
if(vref > VREF_MAX_CCW)
vref = VREF_MAX_CCW;
dacWrite(DAC1,vref);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
}
//------停止処理--------//
else{
dacWrite(DAC1,0);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,HIGH);
delay(10); //ジョイスティック値が±5に入ったら10ms待つ。急激な正・逆回転の切り替えを防止する
}
}
//------------------------------------//
// 右側ジョイスティックのx軸制御 //
//-----------------------------------//
if( Ps3.event.analog_changed.stick.rx ){
joy_right_x = Ps3.data.analog.stick.rx;
//なくても大丈夫だけど、±5を不感帯とする。
if(abs(joy_right_x) < 5){
joy_right_x = 0;
}
//ジョイスティックの読み値をサーボ角に変換
servo_angle = (int)(-joy2servo * joy_right_x + INIT_ANGLE);
myServo.write(servo_angle);
}
}
まとめ
細かいバグなどありましたが、予定通り、左側ジョイスティックの上下動作で、直進とバックができることが確認できました。
また、ステアリング動作も特に問題なし。
PS3のコントローラで思い通りに動くラジコンがほぼ完成です。
あとは、車両への搭載をもう少し何とかしないとですかね。
もっと小さいモバイルバッテリにしないと。。



コメント