範例十

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;

}

}