坦克車左側和右側各有 1 只馬達,我們可以使用遙控器的左、右搖桿來控制坦克車的行走方向。如果想用單一搖桿來控制坦克車的行走方向,好像沒辦法做到,更別說是要去控制麥克納姆輪車可以獨立運作的 4 個輪子了。
有鑑於此,我們想出一個解決的辦法,就是利用 Arduino 讀取接收器的訊號後,做一些整合式的處理(註1),然後再下指令給馬達驅動模組或其它周邊模組作動。
註1:此處所謂的整合式處理,是指把一個以上的訊號指定為一組指令。例如我們想用一只搖桿(有2個頻道的訊號)控制麥克納姆輪車(4個馬達)的行進方向。
本章僅在說明如何解譯搖控接收器的訊號,如何將訊號作整合式應用會另篇說明。
電路接線
Arduino R/C Recever
5V VCC
GND GND
D2 Channel 1
程式
#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead
#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car
volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example
void setup()
{
// tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
// catching these changes will allow us to calculate how long the input pulse is
attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);
Serial.begin(9600);
}
void loop()
{
// if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
if(bNewThrottleSignal)
{
Serial.println(nThrottleIn);
// set this back to false when we have finished
// with nThrottleIn, while true, calcInput will not update
// nThrottleIn
bNewThrottleSignal = false;
}
// other processing ...
}
void calcInput()
{
// if the pin is high, its the start of an interrupt
if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
{
// get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
// easy to understand and works very well
ulStartPeriod = micros();
}
else
{
// if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
// start time ulStartPeriod from the current time returned by micros()
if(ulStartPeriod && (bNewThrottleSignal == false))
{
nThrottleIn = (int)(micros() - ulStartPeriod);
ulStartPeriod = 0;
// tell loop we have a new signal on the throttle channel
// we will not update nThrottleIn until loop sets
// bNewThrottleSignal back to false
bNewThrottleSignal = true;
}
}
}
Step1 打開 Serial Monitor,並將鮑率調到 9600。
Step2 輕輕搖動遙控器上面的搖桿,觀察 Selial Monitor 內的數值(註2)。置中時約為 1500,側邊時約為 1250 和 1750。
註2:如果搖桿置中時數值不為 1500,您可以使用遙控器上面的微調按鍵將它調整到接近 1500。
參考網頁
Instructables https://www.instructables.com/id/Rc-Controller-for-Better-Control-Over-Arduino-Proj/