上回已經成功做出用手機藍芽遙控小車,但是是以按鍵的方式來遙控,感覺還是有一點點點沒那麼直覺的操控,那還有甚麼方式可以來控制小車呢??
你說用像手機玩一些平衡球遊戲或賽車遊戲時,需要傾斜手機來控制畫面中的東西,那麼透過傾斜手機來控制藍芽小車呢??
哦哦哦,感覺就挺有趣的,讓我們來試做看看吧~
內容目錄
加速度感測器是甚麼?
原理
簡單來說,就是透過兩端固定電極片,中間有一個可動的電極,而他連接著彈簧,當物體運動時會有慣性,使中間電極片移動,導致兩端的電容值發生改變,再經由運算就可以知道物體的加速度及方向。
影片中約00:30~1:00的部分為說明加速度感測器
手機讀取加速度感測器
把這個小東西安裝在手機裡面,就可以偵測手機的方向及是否有晃動等等。
一般就是感測三軸的加速度(X、Y、Z軸)
因為重力的關係,物體傾斜時會有分力,使我們感測到X軸方向的加速度,以及Z軸方向的加速度,進而推算傾斜程度。
使用App inventor先試做讀取X、Y、Z軸的數值
手機三軸加速度顯示影片
從影片中可以看出,某個軸的加速度數值越大傾斜角度越大,之後我們就可以用加速度作為參數來控制我們的小車了。
控制架構
方向控制策略
這裡使用兩輪的差速來達成轉彎目的
所以我們的想法是要個別控制左輪與右輪的速度
因為手機只有用到前後傾跟左右傾,故只用X、Y兩軸而已。
X軸用來控制前後速度,傾斜越大速度越快,Y軸用來控制左右速差,藉此產生轉彎。
建立公式:
RightSpeed=dX+dY; //右馬達速度
LeftSpeed=dX-dY; //左馬達速度
以下為舉例:
我手機前傾X軸會是為負數,後傾則為正數。
套用公式後:左右馬達速度為-10會前進,10則會後退
手機向右傾的話,Y軸會是正數,左傾是負數。
套用公式後可發現,左圖右馬達為0因此不會轉動,左馬達為-10會正轉,因此產生向右轉彎的效果;右圖同理,得出左轉的效果。
上述是舉例說明而已,實際控制馬達輸出時,馬達速度範圍會在0~255,因此還會再做一些計算。
實際用手機加速度感測器遙控小車
履帶玩具車硬體部分可參考這篇: [教學]arduino藍芽遙控車,改造履帶玩具車。
如果沒有想做履帶車,也可以買現成的arduino基本底盤車,以前大學第一次玩巡跡車就是用這種小車,非常方便。
App inventor 程式
App介面,主要是顯示X軸跟Y軸的數值而已,記得要加入”加速度感測器”跟”計時器”
App積木程式:
App inventor 專案檔案(.aia):
https://drive.google.com/file/d/1eFZOSaLtcAjJToGp6hxIW8HpuMBXoWC2/view?usp=sharing
Arduino 程式
#include <SoftwareSerial.h>
#include <Wire.h>
//輸出到L298N的腳位
#define MT_L 3 //ENA
#define IN1 4
#define IN2 5
#define IN3 7
#define IN4 8
#define MT_R 9 //ENB
SoftwareSerial BT(10,11);
String XYValue;
int dX,dY;
int RightSpeed;
int LeftSpeed;
void setup() {
BT.begin(9600); // 設定和 HC-06 通訊的速度 (預設 9600)
BT.setTimeout(50); //設定每50ms結束一次讀取
Serial.begin(9600);
pinMode(MT_L,OUTPUT);
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(MT_R,OUTPUT);
}
void loop() {
while(BT.available()) {
XYValue=BT.readString();
ValueTransform();
RightSpeed=(dX+dY)*2;
LeftSpeed=(dX-dY)*2;
char MR_DIR=Motor_R_DIR();
char ML_DIR=Motor_L_DIR();
analogWrite(MT_R,abs(RightSpeed));//輸出右馬達速度
analogWrite(MT_L,abs(LeftSpeed)); //輸出左馬達速度
Serial.print(LeftSpeed);
Serial.print(',');
Serial.print(ML_DIR);
Serial.print(',');
Serial.print(RightSpeed);
Serial.print(',');
Serial.println(MR_DIR);
}
}
//將收到的字串處理成X、Y整數
void ValueTransform(){
String X, Y;
for(int i=0; i<XYValue.length(); i++){
if(i<XYValue.indexOf(',')){
X=X+XYValue[i];
}
else if(i>XYValue.indexOf(',')){
Y=Y+XYValue[i];
}
}
dX=X.toInt();
dY=Y.toInt();
}
//以右馬達速度正或負來決定正反轉
char Motor_R_DIR()
{
if(RightSpeed>0){
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
return 'B';
}
else if(RightSpeed<0){
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
return 'F';
}
}
//以左馬達速度正或負來決定正反轉
char Motor_L_DIR()
{
if(LeftSpeed>0){
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
return 'B';
}
else if(LeftSpeed<0){
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
return 'F';
}
}
最後!! 如果你喜歡這篇文章,或是這篇文章對你有幫助的話,也歡迎分享出去給需要的人,訂閱免費電子報獲得最新資訊😄😄😄