/*
以麥克納姆輪製作的四輪驅動車
搭配四個1:90 TT馬達,
控制板:ESP32+擴展版
直流馬達控制器:L298N 二個
控制介面製作:RemoteXY
控制器:手機+安裝RemoteXY APP
RemoteXY 免費板可以在APP上使用四個部件
預計畫面有
1.搖桿:控制前後及左轉右轉
2.兩個按鈕:控制左平移、右平移
3.一個滑桿(slider):控制速度
手機執行RemoteXY APP
選擇Wifi
找到MCAR
輸入密碼C12345678
*/
//////////////////////////////////////////////
// RemoteXY include library //
//////////////////////////////////////////////
// you can enable debug logging to Serial at 115200
//#define REMOTEXY__DEBUGLOG
// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__WIFI_POINT
#include <WiFi.h>
// RemoteXY connection settings
#define REMOTEXY_WIFI_SSID "MCAR"
#define REMOTEXY_WIFI_PASSWORD "C12345678"
#define REMOTEXY_SERVER_PORT 6377
#include <RemoteXY.h>
// RemoteXY GUI configuration
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] = // 55 bytes
{ 255,5,0,0,0,48,0,19,0,0,0,0,31,1,106,200,1,1,4,0,
5,6,16,95,95,32,2,26,31,4,5,171,99,15,128,2,26,1,9,120,
30,30,0,2,31,0,1,70,121,30,30,0,2,31,0 };
// this structure defines all the variables and events of your control interface
struct {
// input variables
int8_t joystick_01_x; // from -100 to 100
int8_t joystick_01_y; // from -100 to 100
int8_t slider_01; // from 0 to 100
uint8_t button_01; // =1 if button pressed, else =0
uint8_t button_02; // =1 if button pressed, else =0
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop)
/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
// L298N 馬達驅動模組接腳定義
// 第一組L298N(前輪)
//前右輪
#define ENA_PIN 4 //前右輪速度PWM
#define IN1_PIN 16
#define IN2_PIN 17
//前左輪
#define IN3_PIN 5
#define IN4_PIN 18
#define ENB_PIN 19 //前左輪速度PWM
// 第二組L298N(後輪)
//後左輪
#define ENA2_PIN 33 //後左輪速度PWM
#define IN1_PIN2 25
#define IN2_PIN2 26
//後右輪
#define IN3_PIN2 27
#define IN4_PIN2 14
#define ENB2_PIN 12 //後右輪速度PWM
int currentSpeed = 200; // 初始速度
bool speedUpMode = true;
void setup() {
RemoteXY_Init ();
// 設定馬達控制接腳
pinMode(ENA_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
pinMode(IN3_PIN, OUTPUT);
pinMode(IN4_PIN, OUTPUT);
pinMode(ENB_PIN, OUTPUT);
pinMode(ENA2_PIN, OUTPUT);
pinMode(IN1_PIN2, OUTPUT);
pinMode(IN2_PIN2, OUTPUT);
pinMode(IN3_PIN2, OUTPUT);
pinMode(IN4_PIN2, OUTPUT);
pinMode(ENB2_PIN, OUTPUT);
// 設定PWM通道
ledcAttach(ENA_PIN, 12000, 8);
ledcAttach(ENB_PIN, 12000, 8);
ledcAttach(ENA2_PIN, 12000, 8);
ledcAttach(ENB2_PIN, 12000, 8);
RemoteXY.slider_01 = 50 ;
}
void setMotorSpeed() {
// 統一設定所有馬達速度
currentSpeed = RemoteXY.slider_01 + 150 ; //RemoteXY.slider_01的值為0-100,+150也就是修改為150-250,這裡要注意電壓,一般TT馬達最高電壓6V
ledcWrite(ENA_PIN, currentSpeed); // 前右輪
ledcWrite(ENB_PIN, currentSpeed); // 前左輪
ledcWrite(ENA2_PIN, currentSpeed); // 後左輪
ledcWrite(ENB2_PIN, currentSpeed); // 後右輪
}
void moveBackward() {
// 麥克納姆輪後退模式
digitalWrite(IN1_PIN, HIGH); // 前右反轉
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, HIGH); // 前左反轉
digitalWrite(IN4_PIN, LOW);
digitalWrite(IN1_PIN2, HIGH); // 後左反轉
digitalWrite(IN2_PIN2, LOW);
digitalWrite(IN3_PIN2, HIGH); // 後右反轉
digitalWrite(IN4_PIN2, LOW);
}
void moveForward() {
// 麥克納姆輪前進模式
digitalWrite(IN1_PIN, LOW); // 前右正轉
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, LOW); // 前左正轉
digitalWrite(IN4_PIN, HIGH);
digitalWrite(IN1_PIN2, LOW); // 後左正轉
digitalWrite(IN2_PIN2, HIGH);
digitalWrite(IN3_PIN2, LOW); // 後右正轉
digitalWrite(IN4_PIN2, HIGH);
}
void moveLeft() {
// 右平移模式(根據輪子安裝方向調整)
digitalWrite(IN1_PIN, LOW); // 前右反轉
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, HIGH); // 前左正轉
digitalWrite(IN4_PIN, LOW);
digitalWrite(IN1_PIN2, LOW); // 後左反轉
digitalWrite(IN2_PIN2, HIGH);
digitalWrite(IN3_PIN2, HIGH); // 後右正轉
digitalWrite(IN4_PIN2, LOW);
}
void moveRight() {
// 左平移模式(根據輪子安裝方向調整)
digitalWrite(IN1_PIN, HIGH); // 前右正轉
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW); // 前左反轉
digitalWrite(IN4_PIN, HIGH);
digitalWrite(IN1_PIN2, HIGH); // 後左正轉
digitalWrite(IN2_PIN2, LOW);
digitalWrite(IN3_PIN2, LOW); // 後右反轉
digitalWrite(IN4_PIN2, HIGH);
}
void whirlLeft() {
// 左旋轉模式(根據輪子安裝方向調整)
digitalWrite(IN1_PIN, HIGH); // 前右正轉
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW); // 前左反轉
digitalWrite(IN4_PIN, HIGH);
digitalWrite(IN1_PIN2, LOW); // 後左反轉
digitalWrite(IN2_PIN2, HIGH);
digitalWrite(IN3_PIN2, HIGH); // 後右正轉
digitalWrite(IN4_PIN2, LOW);
}
void whirlRight() {
// 右旋轉模式(根據輪子安裝方向調整)
digitalWrite(IN1_PIN, LOW); // 前右反轉
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, HIGH); // 前左正轉
digitalWrite(IN4_PIN, LOW);
digitalWrite(IN1_PIN2, HIGH); // 後左正轉
digitalWrite(IN2_PIN2, LOW);
digitalWrite(IN3_PIN2, LOW); // 後右反轉
digitalWrite(IN4_PIN2, HIGH);
}
void stopMotors() {
// 停止所有馬達
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, LOW);
digitalWrite(IN1_PIN2, LOW);
digitalWrite(IN2_PIN2, LOW);
digitalWrite(IN3_PIN2, LOW);
digitalWrite(IN4_PIN2, LOW);
}
void loop() {
RemoteXY_Handler ();
// 檢測方向按鈕 目前搖桿沒有控制速度,只有數值超過30時讓車子前進、後退、左轉、右轉
if (RemoteXY.button_01 != 0 ){ moveLeft(); } //左平移
else if (RemoteXY.button_02 != 0 ){ moveRight(); } //右平移
else if (RemoteXY.joystick_01_y >= 30 ){ moveForward(); } //前進
else if (RemoteXY.joystick_01_y <= -30 ){ moveBackward(); } //後退
else if (RemoteXY.joystick_01_x >= 30 ){ whirlRight(); } //右轉
else if (RemoteXY.joystick_01_x <= -30 ){ whirlLeft(); } //左轉
else { stopMotors(); } //停止
// 調整速度
setMotorSpeed();
delay(30); // 降低CPU負載
}