お久しぶりです。
子供がRSウイルスに罹り、家庭内感染で家族みんな倒れてました。
さて、前回はESP32とDualShock4をBluetoothでつなぐことができたので今回はそのDualshock4の値を取得してサーボモーターを動かしていこうかと思います。
まず、用意するもの
・ESP32
・Dualshock4(PS4純正コントローラ)
・SG90(90度旋回サーボモーター)
以上3点になります。
回路図は下記のようになります。
サーボモーターの黄線が信号線で今回は13Pinにさしています。
赤線はプラスなので5V
茶線はマイナスなのでGNDに
それぞれ差してください。
作成したプログラムは下記になります。
#include <PS4Controller.h>
#include <Servo.h>
Servo myServo; //Servoオブジェクトを作成
int angle; //角度を格納する変数を宣言
uint8_t R_X; //Dualshock4から入力された値を格納する変数
int R_X2; //R_Xを絶対値にした値を格納する変数
void setup()
{
Serial.begin(115200);
PS4.begin();
Serial.println("Ready.");
myServo.attach(13); // サーボのPulseピンを13ピンに接続します
}
void loop()
{
R_X= PS4.RStickX();
R_X2=abs(R_X);
if(R_X2>128) //スティックを左に倒したとき
{
Serial.print(R_X);
Serial.println(R_X2);
angle = map(R_X2, 128, 252, 0, 90);
myServo.write(angle);
}else if(R_X2<128) //スティックを右に倒したとき
{
Serial.print(R_X);
Serial.println(R_X2);
angle = map(R_X2, 0, 128, 90, 180);
myServo.write(angle);
}
}
前回ダウンロードした
<PS4Controller.h>と<Servo.h>(初期状態である)のライブラリを使用していきます。
前回の接続のプログラムと少し違うところは
12行目のPS4.begin();でDualshock4の接続を行っているところです。
前回はアドレスを指定して、やらなんやらやっていましたが今回は1行で済ませてみました。
15行目のR_X= PS4.RStickX();で右のスティックを左右方向に倒した値を取得するのですがここで1点注意が必要で
返ってくる値は
スティックが真ん中にある時が0
スティックが右に倒れたらプラス
スティックが左に倒れたらマイナス
の値が返ってきます。
20行目でR_X2=abs(R_X);を書いていますが
abs()関数は受け取った値を絶対値にして返すという関数です。
なので、例えば
X = abs(10);
と
X = abs(-10);
は同じ10という値が返ってくるということになります。
そしてここから少しややこしいのですが
Dualshock4のスティックを左に目一杯に倒したら-128になり
ほんの少し左に倒すと-252となります。
逆にスティックを右に目一杯倒したときは127となり
ほんの少し右に倒すと1になります。
(ややこしいい!!!!!ここで躓いた!!!!)
この値を使って倒した角度によってサーボモーターを滑らかに動かしていきたいと思います。
まずはif文で条件分岐ですね。
スティックを右に倒したときの条件と左に倒したときの条件を下記のようにします。
if(R_X2>128) //スティックを左に倒したとき
else if(R_X2<128) //スティックを右に倒したとき
(正直、else ifじゃなくていいかも、、、)
そして値を使って滑らかに動かして生きたので
map関数を使います。
ただしmap関数は入力値に限り負の値が使えません!!!
これが先ほど負の値を絶対値で表した理由です。
負の値があると永遠と思った動きをしてくれませんので注意を。
map関数は
map(value(変換したい数値), fromLow(現在の範囲の下限), fromHigh(現在の範囲の上限), toLow(変換後の範囲の下限), toHigh(変換後の範囲の上限))
の内訳になっています。
なので
angle = map(R_X2(変換する値), 128(変換する値の下限), 252(変換する値の上限), 0(変換後の下限), 90(変換後の上限);
となります。
これで角度への変換ができます。
map関数を使えばたいていの入力はサーボモーターの角度に変換できるので便利ですね。
そしてmap関数によって返された値をServoライブラリの下記のプログラムで出力してあげれば動きはずです。
myServo.write(angle);
完成した動画がこれです。
それなりにスムーズに動いているのではないでしょうか!!!
次回はDCモーターをDualshock4で動かしていこうかと思います。
(DCモーターとモータードライバーはすでに買っていて作業しているけど苦戦しているのは秘密)
みなさんのいいね、コメントが励みになります!
一読してくださったらいいね、コメントしていただけると泣いて喜びます!!