範例十
L9110S 直流馬達
此範例搭配 V7RC 軟體來遙控,使用的是 BLE 來傳資料. 硬體只用左下方的 L9110S 的兩路直流馬達,若使用者要用到兩片 L9110S 變成四路直流馬達,請自行參考以下範例擴充修改.
V7RC 需使用坦克模式來控制 .
// 範例十:
// L9110S 插在左下方,接上兩顆 TT 直流馬達 (5V 供電)
// BLE 無線遙控軟體為 V7RC (請自行從 google play 下載)
// 需要的 library :
// FB : https://www.facebook.com/mason.chen.1420
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "soc/soc.h" //disable brownout problems
#include "soc/rtc_cntl_reg.h" //disable brownout problems
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "driver/rtc_io.h"
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
String receive_data = "";
int t_speed_l =0;
int t_speed_r =0;
// Motor A : gpio12/gpio13 , Motor B : gpio14/gpio15
int motor_A_1 = 26; // left wheel
int motor_A_2 = 25;
int motor_B_1 = 33; // right wheel
int motor_B_2 = 32;
// Setting PWM properties
int pwm_A = 6; // channel
int pwm_B = 7;
void forward() {
digitalWrite(motor_A_1, LOW);
ledcWrite(pwm_A, abs(t_speed_l));
digitalWrite(motor_B_1, LOW);
ledcWrite(pwm_B, abs(t_speed_r));
#ifdef debug1
Serial.print("F");
#endif
}
void backward() {
digitalWrite(motor_A_1, HIGH);
ledcWrite(pwm_A, abs(255-t_speed_l));
digitalWrite(motor_B_1, HIGH);
ledcWrite(pwm_B, abs(255-t_speed_r));
#ifdef debug1
Serial.print("B");
#endif
}
void turn_right() {
digitalWrite(motor_A_1, HIGH);
ledcWrite(pwm_A, abs(255-t_speed_l));
digitalWrite(motor_B_1, LOW);
ledcWrite(pwm_B, abs(t_speed_r));
#ifdef debug1
Serial.print("R");
#endif
}
void turn_left() {
digitalWrite(motor_A_1, LOW);
ledcWrite(pwm_A, abs(t_speed_l));
digitalWrite(motor_B_1, HIGH);
ledcWrite(pwm_B, abs(255-t_speed_r));
#ifdef debug1
Serial.print("L");
#endif
}
void Stop() //Code to stop both the wheels
{
digitalWrite(motor_A_1, LOW);
ledcWrite(pwm_A, 0);
digitalWrite(motor_B_1, LOW);
ledcWrite(pwm_B, 0);
#ifdef debug
Serial.print("S");
#endif
}
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
receive_data ="";
for (int i = 0; i < rxValue.length(); i++) {
receive_data = receive_data + rxValue[i]; }
// Serial.println(receive_data);
// decode V7RC protocol //
if (receive_data.startsWith("SRT")&&(receive_data.length()==20)){
int ch1_data=(receive_data.substring(3,7)).toInt();
int ch2_data=(receive_data.substring(7,11)).toInt();
int ch3_data=(receive_data.substring(11,15)).toInt();
int ch4_data=(receive_data.substring(15,19)).toInt();
receive_data ="";
if (abs(ch1_data-1500)<100 && abs(ch2_data-1500)<100) {
Stop() ;
} else if (abs(ch1_data-1500) > abs(ch2_data-1500)) {
if (ch1_data > 1500) { // r
turn_right();
} else { // l
turn_left();
}
} else {
if (ch2_data > 1500) {
t_speed_l = int(floor(map(ch2_data, 1500, 2000, 50, 250)));
t_speed_r = t_speed_l;
forward();
} else {
t_speed_l = int(floor(map(ch2_data, 1000, 1500, 250, 50)));
t_speed_r = t_speed_l;
backward();
}
}
}
}
};
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
#ifdef debug
Serial.begin(115200);
#endif
pinMode(motor_A_1, OUTPUT);
pinMode(motor_B_1, OUTPUT);
ledcSetup(pwm_A, 1000, 8);
ledcAttachPin(motor_A_2, pwm_A);
ledcSetup(pwm_B, 1000, 8);
ledcAttachPin(motor_B_2, pwm_B);
// Create the BLE Device
BLEDevice::init("");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
// https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEAdvertising.cpp
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEUUID uuid("6E400001");
//Device Name
String device_name = "ESP_CAR";
oAdvertisementData.setName(device_name.c_str());
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
pAdvertising->start();
// Serial.println("Characteristic defined! Now you can read it in your phone!");
}
void loop() {
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(100); // give the bluetooth stack the chance to get things ready
BLEDevice::startAdvertising(); // restart advertising
// Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}