便宜上、2022年にAD1で作成した基板を「2022バージョン」、
2023年にAD1で作成した基板を「2023バージョン」と呼ぶことにします。
両者は基板(ピンアサインなど)が少し異なるのでコメントを参考にして適宜変更ください。
#include <Arduino.h> |
#include <Arduino.h> |
#include <Arduino.h> |
岡田先生がAD2の競技会の事前学習として用意したもの。2022、2023共通。
#include <Arduino.h> |
ESP32入門の9と同じです。
#include <Arduino.h>
#include <ESP32Servo.h>
#define SERVO_PIN 13
Servo myServo;
void setup() {
myServo.attach(SERVO_PIN);
}
void loop() {
myServo.write(0);
delay(1000);
myServo.write(90);
delay(1000);
myServo.write(180);
delay(1000);
myServo.write(90);
delay(1000);
}
永田先生提供作品をESP用に改変。ピンアサインは2022バージョン。
#include <Arduino.h>
#define Trig 14
#define Echo 12
#define LF 25
#define LB 26
#define RF 5
#define RB 15
#define ledR 27
int Search () {
float Duration = 0.0;
float CM = 0.0;
digitalWrite (Trig, LOW);
delayMicroseconds (2);
digitalWrite (Trig, HIGH);
delayMicroseconds (10);
digitalWrite (Trig, LOW);
Duration = pulseIn (Echo, HIGH);
CM = (Duration / 58.8);
return CM;
}
void setup() {
Serial.begin(115200);
pinMode (Trig, OUTPUT);
pinMode (Echo, INPUT);
pinMode (RF, OUTPUT);
pinMode (LF, OUTPUT);
pinMode (RB, OUTPUT);
pinMode (LB, OUTPUT);
pinMode (ledR, OUTPUT);
}
void loop() {
int Distance = Search ();
if (Distance > 20){
digitalWrite (LF, LOW);
digitalWrite (LB, HIGH);
digitalWrite (RF, LOW);
digitalWrite (RB, HIGH);
delay (100);
digitalWrite (ledR, LOW);
}
else{
digitalWrite (LF, HIGH);
digitalWrite (LB, HIGH);
digitalWrite (RF, HIGH);
digitalWrite (RB, HIGH);
digitalWrite (ledR, HIGH);
delay (100);
}
}
永田先生提供作品をESP用に改変。ピンアサインは2022バージョン。
#include <Arduino.h>
#define Trig 14
#define Echo 12
#define LF 25
#define LB 26
#define RF 5
#define RB 15
#define ledR 27
int Search () {
float Duration = 0.0;
float CM = 0.0;
digitalWrite (Trig, LOW);
delayMicroseconds (2);
digitalWrite (Trig, HIGH);
delayMicroseconds (10);
digitalWrite (Trig, LOW);
Duration = pulseIn (Echo, HIGH);
CM = (Duration / 58.8);
return CM;
}
void setup() {
Serial.begin(115200);
pinMode (Trig, OUTPUT);
pinMode (Echo, INPUT);
pinMode (RF, OUTPUT);
pinMode (LF, OUTPUT);
pinMode (RB, OUTPUT);
pinMode (LB, OUTPUT);
pinMode (ledR, OUTPUT);
}
void loop() {
int Distance = Search ();
if (Distance < 10){
digitalWrite (ledR, LOW);
digitalWrite (LF, LOW);
digitalWrite (LB, HIGH);
digitalWrite (RF, LOW);
digitalWrite (RB, HIGH);
}
else{
digitalWrite (ledR, HIGH);
digitalWrite (LF, HIGH);
digitalWrite (LB, LOW);
digitalWrite (RF, HIGH);
digitalWrite (RB, LOW);
delay (100);
digitalWrite (LF, HIGH);
digitalWrite (LB, LOW);
digitalWrite (RF, LOW);
digitalWrite (RB, HIGH);
delay (100);
}
}
左右に超音波センサーを振りながら走行。障害物を発見したら一旦バックし、左右を広角で確認し、空間距離が大きい方向に舵を切る。
目的値は与えないので
どこに行くかはわからない。
#include <Arduino.h>
#include <ESP32Servo.h>
#define Trig 14
#define Echo 12
#define LEDB 16
#define LEDG 17
#define LEDR 27
#define in1 25
#define in2 26
#define in3 32 // 2022バージョンでは5
#define in4 33 // 2022バージョンでは15
Servo servo1;
int Search () {
float Duration = 0.0;
float CM = 0.0;
digitalWrite (Trig, LOW);
delayMicroseconds (2);
digitalWrite (Trig, HIGH);
delayMicroseconds (10);
digitalWrite (Trig, LOW);
Duration = pulseIn (Echo, HIGH);
CM = (Duration / 58.8);
return CM;
}
int LeftDistance, RightDistance;
float Distance = 0.00;
int servoR = 30;
int servoL = 150;
int servoN = 90;
int servoscanpos[4]={50,90,130,90};
int i = 0;
void setup () {
Serial.begin(9600);
pinMode (Trig, OUTPUT);
pinMode (Echo, INPUT);
pinMode (LEDB, OUTPUT);
pinMode (LEDG, OUTPUT);
pinMode (LEDR, OUTPUT);
pinMode (in1, OUTPUT);
pinMode (in2, OUTPUT);
pinMode (in3, OUTPUT);
pinMode (in4, OUTPUT);
servo1.attach (13);
digitalWrite (in1, HIGH);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, HIGH);
servo1.write (90);
delay (2000);
}
void loop () {
if(i > 3){
i=0 ;
}
servo1.write (servoscanpos[i]);
delay (200);
Distance = Search ();
if (Distance < 30) {
//Stop
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, HIGH);
digitalWrite (in1, HIGH);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, HIGH);
delay (500);
//Backward
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
delay (500);
//Stop
digitalWrite (in1, HIGH);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, HIGH);
delay (500);
//Move Servo Right Turn
servo1.write (servoR);
delay (300);
RightDistance = Search ();
delay (500);
//Move Servo Left Turn
servo1.write (servoL);
delay (500);
LeftDistance = Search ();
delay (500);
//Move Servo Neutral
servo1.write (servoN);
delay (300);
//Compare Distance
if (RightDistance > LeftDistance) {
//Turn Right 緑点灯し旋回
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, HIGH);
digitalWrite (LEDR, LOW);
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
delay (700);
digitalWrite (LEDG, LOW);
}
else if (LeftDistance > RightDistance) {
//Turn Left 青点灯し旋回
digitalWrite (LEDB, HIGH);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, LOW);
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
delay (700);
digitalWrite (LEDB, LOW);
}
else {
//Turn Around
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
delay (1400);
}
}
else if (Distance >= 30) {
//Forward 青点灯し走行
digitalWrite (LEDB, HIGH);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, LOW);
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
}
i++ ;
// serial monitor
// Serial.print(F("\r\nDistance Cm: "));
// Serial.print(Distance);
// Serial.print(F("\tRightDistance Cm: "));
// Serial.print(RightDistance);
// Serial.print(F("\tLeftDistance Cm: "));
// Serial.print(LeftDistance);
}
前後に行ったり来たり永遠に繰り返す。 一方で、電池電圧を常時監視し、2本のうち1本でも電池電圧が3V以下なら赤LEDを点灯し車両を止める。
#include <Arduino.h>
#define ATT1 34
#define ATT2 35
#define LEDB 16
#define LEDR 27
const int in1 = 25;
const int in2 = 26;
const int in3 = 32;
const int in4 = 33;
float volt1,volt2;
void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
pinMode(LEDB, OUTPUT);
pinMode(LEDR, OUTPUT);
pinMode(ATT1, ANALOG);
pinMode(ATT2, ANALOG);
analogSetAttenuation(ADC_11db);
}
void loop() {
volt1= analogRead(ATT1) *3500/4095*4;
volt2= analogRead(ATT2) *3500/4095*4;
if(volt1>6000 && volt2>3000){
digitalWrite(LEDB,HIGH);
digitalWrite(LEDR,LOW);
} else {
digitalWrite(LEDB,LOW);
digitalWrite(LEDR,HIGH);
while(1) {
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
digitalWrite(LEDR,LOW);
delay (300);
digitalWrite(LEDR,HIGH);
delay (300);
}
}
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(600);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(600);
}
ESP32用の標準ライブラリにあるLEDC関数は本来LEDの調光を目的とするのもだが、機能自体はanalogWriteと同じもの。
モーター制御ピンに使用すればモーターの速度調整に使える。
ここでのサンプルは
#include <Arduino.h>
#define Trig 14 // ESP32の標準ライブラリに含まれるのでinclude命令は不要
#define Echo 12
#define LEDB 16
#define LEDG 17
#define LEDR 27
#define in1 25
#define in2 26
#define in3 32
#define in4 33
#define LEDC_CHANNEL_1 3 // サーボと干渉するチャネルがありそうなので避ける 3~5chではとりあえずOKだった。
#define LEDC_CHANNEL_2 4
#define LEDC_CHANNEL_3 5
#define LEDC_CHANNEL_4 6
#define LEDC_BASE_FREQ 1200.0 // キャリア周波数設定 1200Hz
#define LEDC_TIMER_BIT 8 // 分解能8bit(0-255)
int duty1 = 0; // デューティ比1 ここでは0% に設定
int setBit1 = 255*duty1/100;
int duty2 = 50; // デューティ比2 ここでは50% に設定
int setBit2 = 255*duty2/100;
void setup () {
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_2, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_4, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in2, LEDC_CHANNEL_2);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcAttachPin(in4, LEDC_CHANNEL_4);
ledcWrite(LEDC_CHANNEL_1, setBit1);
ledcWrite(LEDC_CHANNEL_2, setBit2);
ledcWrite(LEDC_CHANNEL_3, setBit1);
ledcWrite(LEDC_CHANNEL_4, setBit2);
delay (2000);
}
void loop () {
}
#include <Arduino.h>
#include <ESP32Servo.h>
#define Trig 14
#define Echo 12
#define LEDB 16
#define LEDG 17
#define LEDR 27
#define in1 25
#define in2 26
#define in3 32
#define in4 33
#define SERVO_PIN 13
Servo servo1;
int Search () {
float Duration = 0.0;
float CM = 0.0;
digitalWrite (Trig, LOW);
delayMicroseconds (2);
digitalWrite (Trig, HIGH);
delayMicroseconds (10);
digitalWrite (Trig, LOW);
Duration = pulseIn (Echo, HIGH);
CM = (Duration / 58.8);
return CM;
}
int leftDistance, rightDistance;
float Distance = 0.00;
int servoR = 30;
int servoL = 150;
int servoN = 90;
int servoscanpos[4]={50,90,130,90};
int i = 0;
void setup () {
Serial.begin(9600);
pinMode (Trig, OUTPUT);
pinMode (Echo, INPUT);
pinMode (LEDB, OUTPUT);
pinMode (LEDG, OUTPUT);
pinMode (LEDR, OUTPUT);
pinMode (in1, OUTPUT);
pinMode (in2, OUTPUT);
pinMode (in3, OUTPUT);
pinMode (in4, OUTPUT);
digitalWrite (in1, HIGH);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, HIGH);
servo1.attach(SERVO_PIN);
delay (2000);
}
void loop () {
if(i > 3){
i=0 ;
}
servo1.write (servoscanpos[i]);
delay (200);
Distance = Search ();
if(i==0){
rightDistance = Distance;
}
if(i==2){
leftDistance = Distance;
}
if (Distance < 30) {
if (i==0) { // move left
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, HIGH);
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
} if (i==2) { // move right
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, HIGH);
digitalWrite (LEDR, LOW);
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
} if (i==3 || i==1) {
if(rightDistance > leftDistance) { // move right
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, HIGH);
digitalWrite (LEDR, LOW);
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
} if(rightDistance <= leftDistance) { // move left
digitalWrite (LEDB, LOW);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, HIGH);
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
}
}
} else{
digitalWrite (LEDB, HIGH);
digitalWrite (LEDG, LOW);
digitalWrite (LEDR, LOW);
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
}
i++;
}
スマホアプリ Bluefruit Connect を使ってリモコン化
/*This sketch was applied to my TJ5-ROBOT with the sketch for ESP32_BLE_server_UART_Robot
posted on pcbreflux's GitHub as a hint.*/
#include <Arduino.h>
#include <ESP32Servo.h>
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
#include "BLE2902.h"
Servo servo1;
int UA1 = 25; // ↑ button
int LA1 = 26; // ↑ button
int UA2 = 15; // ↓ button
int LA2 = 5; // ↓ button
int SV1 = 13; // Servo
int LED_1 = 27; // 1 button to LED
int LED_2 = 17; // 2 button to LED
int LED_3 = 16; // 3 button to LED
int servoR = 20;
int servoL = 140;
int servoN = 80;
BLECharacteristic *pCharacteristic;
BLEDescriptor *pDescriptor;
bool deviceConnected = false;
bool deviceNotifying = false;
uint8_t txValue = 0;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
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();
if (rxValue.length() > 0) {
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
if (rxValue == "!B516") { // ↑ button push
digitalWrite(UA1, LOW);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, LOW);
digitalWrite(LA2, HIGH);
} else if (rxValue == "!B507") { // ↑ button Release
digitalWrite(UA1, HIGH);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, HIGH);
}
else if (rxValue == "!B615") { // ↓ button push
digitalWrite(UA1, HIGH);
digitalWrite(LA1, LOW);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, LOW);
} else if (rxValue == "!B606") { // ↓ button Release
digitalWrite(UA1, HIGH);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, HIGH);
}
else if (rxValue == "!B714") { // ← button push
digitalWrite(UA1, HIGH);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, LOW);
digitalWrite(LA2, HIGH);
} else if (rxValue == "!B705") { // ← button Release
digitalWrite(UA1, HIGH);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, HIGH);
}
else if (rxValue == "!B813") { // → button push
digitalWrite(UA1, LOW);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, HIGH);
} else if (rxValue == "!B804") { // → button Release
digitalWrite(UA1, HIGH);
digitalWrite(LA1, HIGH);
digitalWrite(UA2, HIGH);
digitalWrite(LA2, HIGH);
}
if (rxValue == "!B11:") { // 1 button push
digitalWrite(LED_1, HIGH); // LED ON
digitalWrite(LED_2, LOW); // LED OFF
digitalWrite(LED_3, LOW); // LED OFF
}
else if (rxValue == "!B10;") { // 1 button Release
digitalWrite(LED_1, LOW); // LED OFF
}
if (rxValue == "!B219") { // 2 button push
digitalWrite(LED_2, HIGH); // LED ON
digitalWrite(LED_1, LOW); // LED OFF
digitalWrite(LED_3, LOW); // LED OFF
}
else if (rxValue == "!B20:") { // 2 button Release
digitalWrite(LED_2, LOW); // LED OFF
}
if (rxValue == "!B318") { // 3 button push
}
else if (rxValue == "!B309") { // 3 button Release
}
if (rxValue == "!B417") { // 4 button push
}
else if (rxValue == "!B408") { // 4 button Release
}
Serial.println();
}
}
};
class MyDisCallbacks: public BLEDescriptorCallbacks {
void onWrite(BLEDescriptor *pDescriptor) {
uint8_t* rxValue = pDescriptor->getValue();
if (pDescriptor->getLength() > 0) {
if (rxValue[0] == 1) {
//deviceNotifying=true;
} else {
deviceNotifying = false;
}
Serial.print("Received Descriptor Value: ");
for (int i = 0; i < pDescriptor->getLength(); i++)
Serial.print(rxValue[i]);
Serial.println();
}
}
};
void setup() {
Serial.begin(115200);
pinMode(UA1, OUTPUT);
pinMode(LA1, OUTPUT);
pinMode(UA2, OUTPUT);
pinMode(LA2, OUTPUT);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
digitalWrite(LED_1, LOW); //Motor POWER OFF
digitalWrite(LED_2, LOW); //Motor POWER OFF
digitalWrite(LED_3, LOW); //Motor POWER OFF
digitalWrite(UA1, HIGH); //Motor POWER OFF
digitalWrite(UA2, HIGH); //Motor POWER OFF
digitalWrite(LA1, HIGH); //Motor POWER OFF
digitalWrite(LA2, HIGH); //Motor POWER OFF
pinMode(SV1, OUTPUT);
servo1.attach(SV1);
// Create the BLE Device
BLEDevice::init("UART Service"); // Device Name
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLE2902();
pCharacteristic->addDescriptor(pDescriptor);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pDescriptor->setCallbacks(new MyDisCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
servo1.write (servoN);
}
void loop() {
if (deviceConnected && deviceNotifying) {
Serial.printf("*** Sent Value: %d ***\n", txValue);
pCharacteristic->setValue(&txValue, 1);
pCharacteristic->notify();
txValue++;
}
}
ESP32をwifiアクセスポイント化し、スマホからこれにアクセスする。
4輪車の電源を入れ、スマホのwifi設定画面でESPを選ぶ。ブラウザで192.168.30.5に接続する。
/* WiFi-Control-Car(softAP) */
// 2022ピンアサイン、額縁なし、左右逆は直した
#include <Arduino.h>
#include <WiFi.h>
const int in1 = 25;
const int in2 = 26;
const int in3 = 32;
const int in4 = 33;
const char ssid[] = "SkynsESP32-2";
const char pass[] = "hatumei";
const IPAddress ip(192,168,30,5);
const IPAddress subnet(255,255,255,0);
const char html[] =
"<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>\
<style>body {zoom: 2.0;-moz-transform: scale(1.0);}\
input {margin:8px;width:80px;}\
div {font-size:16pt;color:red;text-align:center;}</style>\
<title>WiFi_Car Controller</title></head>\
<body><div>RC Car Controller<br>\
<form method='get'>\
<input type='submit' name='le' value='左' />\
<input type='submit' name='fo' value='前' />\
<input type='submit' name='ri' value='右' /><br>\
<input type='submit' name='st' value='停止' /><br>\
<input type='submit' name='ba' value='後ろ' />\
</form></div></body></html>";
void stop(){
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
//digitalWrite(0, LOW);
//digitalWrite(2, LOW);
//digitalWrite(4, LOW);
//digitalWrite(5, LOW);
}
WiFiServer server(80);
void setup()
{
Serial.begin(115200);
WiFi.softAP(ssid,pass);
delay(100);
WiFi.softAPConfig(ip,ip,subnet);
IPAddress myIP = WiFi.softAPIP();
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
delay(10);
server.begin();
Serial.print("SSID: ");
Serial.println(ssid);
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.println("Server start!");
}
void loop(){
WiFiClient client = server.available();
if (client) {
String currentLine = "";
Serial.println("New Client.");
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
if (c == '\n') {
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print(html);
client.println();
break;
} else {
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
if (currentLine.endsWith("GET /?fo")) {
stop();
digitalWrite(in1, LOW);
digitalWrite(in3, LOW);
}
if (currentLine.endsWith("GET /?le")) {
stop();
digitalWrite(in3, LOW);
}
if (currentLine.endsWith("GET /?ri")) {
stop();
digitalWrite(in1, LOW);
}
if (currentLine.endsWith("GET /?ba")) {
stop();
digitalWrite(in2, LOW);
digitalWrite(in4, LOW);
}
if (currentLine.endsWith("GET /?bl")) {
stop();
digitalWrite(in2, LOW);
}
if (currentLine.endsWith("GET /?br")) {
stop();
digitalWrite(in4, LOW);
}
if (currentLine.endsWith("GET /?st")) {
stop();
}
}
}
client.stop();
Serial.println("Client Disconnected.");
}
}
赤字部分は各自のESP32のMACアドレスを調べて書き換える必要がある
// ==== ESP32 Bluetooth Serial Master Sample Sketch ====
#include <Arduino.h>
#include <BluetoothSerial.h>
#include <Ticker.h>
BluetoothSerial SerialBT;
Ticker blinker;
String MACadd = "70:B8:F6:70:76:2E"; // リモコン側ESP32のMACアドレスを書き込む
uint8_t address[6] = { 0xD0,0xEF,0x76,0x09,0xF9,0x72 }; // 4輪車側ESP32のMACアドレスを書き込む(書式に注意)
bool connected;
#define builtinLED 2
void ledBlink() {
digitalWrite(builtinLED, !digitalRead(builtinLED));
}
void setup() {
pinMode(builtinLED, OUTPUT);
// pinMode(LED17, OUTPUT);
pinMode(26, OUTPUT);
pinMode(27, OUTPUT);
pinMode(12,ANALOG);
pinMode(14,ANALOG);
pinMode(13, INPUT_PULLUP);
digitalWrite(27, HIGH);
digitalWrite(26, LOW);
analogSetAttenuation(ADC_11db);
Serial.begin(115200);
SerialBT.begin("ESP32test", true);
Serial.println("device start");
connected = SerialBT.connect(address);
if (connected) {
Serial.println("Connect OK");
} else {
while (!SerialBT.connected(10000)) {
Serial.println("No connect");
}
}
if (SerialBT.disconnect()) {
Serial.println("Disconnected Succesfully!");
}
SerialBT.connect();
// blinker.attach(0.1, ledBlink);
}
void loop() {
// send data Package
uint8_t send_data[4];
send_data[0] = !digitalRead(13);
send_data[1] = analogRead(14)/16; // joystick X position
send_data[2] = analogRead(12)/16; // joystick Y position
send_data[3] = 0;
SerialBT.write(send_data, 4);
delay(5);
// receive data Package
if (SerialBT.available()) {
digitalWrite(builtinLED, HIGH);
Serial.print(F("\r\njoystickX: "));
Serial.print(send_data[1]);
Serial.print(F("\tjoystickY: "));
Serial.print(send_data[2]);
Serial.print(F("\tbutton: "));
Serial.print(send_data[0]);
}
delay(5);
}
// A-1 Mac Address [Master] = D0:EF:76:48:BC:1E Mac Address [Slave] = 0xD0,0xEF,0x76,0x48,0xBC,0x1E
// A-2 Mac Address [Master] = D0:EF:76:08:16:BE Mac Address [Slave] = 0xD0,0xEF,0x76,0x08,0x16,0xBE
// A-3 Mac Address [Master] = CC:7B:5C:27:9C:9E Mac Address [Slave] = 0xCC,0x7B,0x5C,0x27,0x9C,0x9E
// A-4 Mac Address [Master] = 70:B8:F6:70:72:4A Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0x72,0x4A
// A-5 Mac Address [Master] = 70:B8:F6:71:44:9E Mac Address [Slave] = 0x70,0xB8,0xF6,0x71,0x44,0x9E
// A-6 Mac Address [Master] = D0:EF:76:0A:13:8E Mac Address [Slave] = 0xD0,0xEF,0x76,0x0A,0x13,0x8E
// A-7 Mac Address [Master] = 70:B8:F6:71:DB:52 Mac Address [Slave] = 0x70,0xB8,0xF6,0x71,0xDB,0x52
// A-8 Mac Address [Master] = 70:B8:F6:70:66:C2 Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0x66,0xC2
// A-9 Mac Address [Master] = 70:B8:F6:70:76:2E Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0x76,0x2E
// A-10 Mac Address [Master] = D0:EF:76:09:F9:72 Mac Address [Slave] = 0xD0,0xEF,0x76,0x09,0xF9,0x72
// A-11 Mac Address [Master] = 70:B8:F6:72:0D:EE Mac Address [Slave] = 0x70,0xB8,0xF6,0x72,0x0D,0xEE
// A-12 Mac Address [Master] = 70:B8:F6:70:67:4E Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0x67,0x4E
// A-13 Mac Address [Master] = D0:EF:76:48:47:02 Mac Address [Slave] = 0xD0,0xEF,0x76,0x48,0x47,0x02
// A-14 Mac Address [Master] = 70:B8:F6:70:B9:F6 Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0xB9,0xF6
// A-15 Mac Address [Master] = D0:EF:76:48:11:BA Mac Address [Slave] = 0xD0,0xEF,0x76,0x48,0x11,0xBA
// A-16 Mac Address [Master] = 70:B8:F6:70:6E:5E Mac Address [Slave] = 0x70,0xB8,0xF6,0x70,0x6E,0x5E
// B-1 Mac Address [Master] = C8:F0:9E:F2:9A:82 Mac Address [Slave] = 0xC8,0xF0,0x9E,0xF2,0x9A,0x82
// B-2 Mac Address [Master] = C8:F0:9E:F2:8F:62 Mac Address [Slave] = 0xC8,0xF0,0x9E,0xF2,0x8F,0x62
// B-3 Mac Address [Master] = E0:5A:1B:A1:E3:DE Mac Address [Slave] = 0xE0,0x5A,0x1B,0xA1,0xE3,0xDE
// B-4 書き込めず
// B-5 Mac Address [Master] = C8:F0:9E:F2:89:62 Mac Address [Slave] = 0xC8,0xF0,0x9E,0xF2,0x89,0x62
// ==== ESP32 Bluetooth Serial Slave Sample Sketch ====
#include <Arduino.h>
#include <BluetoothSerial.h>
#include <Ticker.h>
#include <ESP32Servo.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
Ticker blinker;
#define builtinLED 2
#define LEDR 27
#define LEDG 17
#define LEDB 16
#define in1 25
#define in2 26
#define in3 32
#define in4 33
#define LEDC_CHANNEL_1 3 // サーボと干渉するチャネルがありそうなので避ける 3~5chではとりあえずOKだった。
#define LEDC_CHANNEL_2 4
#define LEDC_CHANNEL_3 5
#define LEDC_CHANNEL_4 6
#define LEDC_BASE_FREQ 1000.0 // キャリア周波数設定 8kHz
#define LEDC_TIMER_BIT 8 // 分解能8bit(0-255)
int xAxis = 510;
int yAxis = 510;
int button5;
int speedLeft = 100; // 反転回路があるので100が最弱、0が最強である
int speedRight = 100;
int data0,data1,data2,data3;
void ledBlink() {
digitalWrite(builtinLED, !digitalRead(builtinLED));
}
#define SERVO_PIN 13
Servo myServo;
void setup() {
myServo.attach(SERVO_PIN);
Serial.begin(115200);
pinMode(5,INPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
digitalWrite(in1,HIGH);
digitalWrite(in2,HIGH);
digitalWrite(in3,HIGH);
digitalWrite(in4,HIGH);
SerialBT.begin("ESP32test");
Serial.println("device start");
pinMode(builtinLED, OUTPUT);
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
blinker.attach(0.1, ledBlink);
myServo.write(90);
delay(1000);
}
void loop() {
// send data Package
// uint8_t send_data[4];
// send_data[0] = !digitalRead(Button5);
// send_data[1] = !digitalRead(Button5);
// send_data[2] = !digitalRead(Button5);
// send_data[3] = !digitalRead(Button5);
// SerialBT.write(send_data, 1);
// delay(5);
// receive data Package
while (!SerialBT.available()) {
}
digitalWrite(builtinLED, HIGH);
uint8_t recv_data[4];
SerialBT.readBytes(recv_data, 4);
data0 = recv_data[0];
data1 = recv_data[1];
data2 = recv_data[2];
data3 = recv_data[3];
delay(5);
xAxis = map (data2, 0, 230, 0, 1023); // data2はジョイスティックのVRYの読み ジョイスティックが90度回っているのでのxyを逆にする
yAxis = map (data1, 0, 230, 0, 1023);
button5 = data0;
// Forward
if (yAxis > 550) {
speedLeft = map(yAxis, 510, 1160, 100, 0); //
speedRight = map(yAxis, 510, 1160, 100, 0);
pinMode(in2,OUTPUT);
pinMode(in4,OUTPUT);
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in2,HIGH);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in4,HIGH);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_3, speedRight);
}
// Backward
if (yAxis < 470) {
speedLeft = map(yAxis, 510, 0, 100, 0);
speedRight = map(yAxis, 510, 0, 100, 0);
pinMode(in1,OUTPUT);
pinMode(in3,OUTPUT);
ledcSetup(LEDC_CHANNEL_2, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in1,HIGH);
ledcSetup(LEDC_CHANNEL_4, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in3,HIGH);
ledcAttachPin(in2, LEDC_CHANNEL_2);
ledcAttachPin(in4, LEDC_CHANNEL_4);
ledcWrite(LEDC_CHANNEL_2, speedLeft);
ledcWrite(LEDC_CHANNEL_4, speedRight);
}
// Pivot Left turn
if (yAxis > 470 && yAxis < 550 && xAxis < 470) {
speedLeft = map(xAxis, 510, 0, 100, 0);
speedRight = map(xAxis, 510, 0, 100, 0);
pinMode(in1,OUTPUT);
pinMode(in4,OUTPUT);
ledcSetup(LEDC_CHANNEL_2, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in1,HIGH);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in4,HIGH);
ledcAttachPin(in2, LEDC_CHANNEL_2);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcWrite(LEDC_CHANNEL_2, speedLeft);
ledcWrite(LEDC_CHANNEL_3, speedRight);
}
// Left turn
else if (xAxis < 470) {
int xMapped = map(xAxis, 510, 0, 100, 0);
speedLeft = speedLeft - xMapped;
speedRight = speedRight + xMapped;
if (speedLeft < 0) {speedLeft = 0;}
if (speedRight > 100) {speedRight = 100;}
pinMode(in2,OUTPUT);
pinMode(in4,OUTPUT);
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in2,HIGH);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in4,HIGH);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_3, speedRight);
}
// Pivot Right turn
if (yAxis > 470 && yAxis < 550 && xAxis > 550) {
speedLeft = map(xAxis, 510, 1160, 100, 0);
speedRight = map(xAxis, 510, 1160, 100, 0);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in1,HIGH);
ledcSetup(LEDC_CHANNEL_4, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in4,HIGH);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in4, LEDC_CHANNEL_4);
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_4, speedRight);
}
// Right turn
else if (xAxis > 550) {
int xMapped = map(xAxis, 510, 1160, 100, 0);
speedLeft = speedLeft + xMapped;
speedRight = speedRight - xMapped;
if (speedLeft > 100) {speedLeft = 100;}
if (speedRight < 0) {speedRight = 0;}
pinMode(in2,OUTPUT);
pinMode(in4,OUTPUT);
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in2,HIGH);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
digitalWrite(in4,HIGH);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_3, speedRight);
}
// Joystick neutral
if ((yAxis > 470 && yAxis < 550) && (xAxis > 470 && xAxis < 550)) {
speedLeft = 100;
speedRight = 100;
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
digitalWrite(in1,HIGH);
digitalWrite(in2,HIGH);
digitalWrite(in3,HIGH);
digitalWrite(in4,HIGH);
}
// joystick button LED
if (button5 == 1) {
digitalWrite(LEDB, HIGH);
myServo.write(130);
}
else {
digitalWrite(LEDB, LOW);
myServo.write(90);
}
// Motor Drive LED
if (speedLeft < 95 || speedRight < 95) {
digitalWrite(LEDG, HIGH);
}
else {
digitalWrite(LEDG, LOW);
}
// serial monitor
Serial.print(F("\r\nxAxis: "));
Serial.print(xAxis);
Serial.print(F("\tyAxis: "));
Serial.print(yAxis);
Serial.print(F("\tspeedLeft: "));
Serial.print(speedLeft);
Serial.print(F("\tspeedRight: "));
Serial.print(speedRight);
Serial.print(F("\tbutton5: "));
Serial.print(button5);
}
書き込み後、Arduino IDE画面右上の虫眼鏡アイコンをクリックしてシリアルモニタを表示(通信速度は115200)させ、ESP32のリセットボタン(USB端子の隣のEN)を押す。
MACアドレスはシリアルモニタの一番最後に "E0:5A:1B:A1:D2:76" のように表示されるので。これをメモしておく。
/* === ESP32 Get MAC Address === */
#include <Arduino.h>
#include "esp_mac.h" // required - exposes esp_mac_type_t values
String getDefaultMacAddress() {
String mac = "";
unsigned char mac_base[6] = {0};
if (esp_efuse_mac_get_default(mac_base) == ESP_OK) {
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]);
mac = buffer;
}
return mac;
}
String getInterfaceMacAddress(esp_mac_type_t interface) {
String mac = "";
unsigned char mac_base[6] = {0};
if (esp_read_mac(mac_base, interface) == ESP_OK) {
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]);
mac = buffer;
}
return mac;
}
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Serial.println("Interface\t\t\t\t\t\tMAC address (6 bytes, 4 universally administered, default)");
Serial.print("Wi-Fi Station (using 'esp_efuse_mac_get_default')\t");
Serial.println(getDefaultMacAddress());
Serial.print("WiFi Station (using 'esp_read_mac')\t\t\t");
Serial.println(getInterfaceMacAddress(ESP_MAC_WIFI_STA));
Serial.print("WiFi Soft-AP (using 'esp_read_mac')\t\t\t");
Serial.println(getInterfaceMacAddress(ESP_MAC_WIFI_SOFTAP));
Serial.print("Bluetooth (using 'esp_read_mac')\t\t\t");
Serial.println(getInterfaceMacAddress(ESP_MAC_BT));
Serial.print("Ethernet (using 'esp_read_mac')\t\t\t\t");
Serial.println(getInterfaceMacAddress(ESP_MAC_ETH));
}
void loop() { /* Nothing in loop */ }
2022バージョン用
#include <Arduino.h>
#define in1 25
#define in2 26
#define in3 5
#define in4 15
#define piL 36
#define piR 39
int thlev=200;
int ir1 = 0.00;
int ir2 = 0.00;
void setup () {
Serial.begin(115200);
pinMode (in1, OUTPUT);
pinMode (in2, OUTPUT);
pinMode (in3, OUTPUT);
pinMode (in4, OUTPUT);
pinMode (piL, ANALOG);
pinMode (piR, ANALOG);
analogSetAttenuation(ADC_11db);
}
void loop () {
ir1 = analogRead(piL);
ir2 = analogRead(piR);
if (ir1 > thlev && ir2 <= thlev) {
//Turn Right
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
}
else if (ir1 < thlev && ir2 >= thlev) {
//Turn Left
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
} else if (ir1 < thlev && ir2 < thlev ) {
digitalWrite (in1, LOW);
digitalWrite (in2, HIGH);
digitalWrite (in3, LOW);
digitalWrite (in4, HIGH);
} else if (ir1 >= thlev && ir2 >= thlev ) {
digitalWrite (in1, HIGH);
digitalWrite (in2, HIGH);
digitalWrite (in3, HIGH);
digitalWrite (in4, HIGH);
}
//serial monitor
Serial.print(F("\r\nDistance IR1: "));
Serial.print(ir1);
Serial.print(F(" \tRightDistance IR2: "));
Serial.print(ir2);
delay(10);
}
3つのUUIDの頭8桁を本体側と共通の自分固有のコードにしておきましょう。
1つめはSERVICE_UUID、2つめは受信用(RX)、3つめは送信用(TX)のUUID。
これを3つともプログラムに書き込んでおく。
本体側にも同じUUIDを書き込んでおいて相互に相手を認識する。
リモコンと本体(No.19)とはRXとTXが逆なので注意。
// === ESP32 BLE Server sample skech ===
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <Ticker.h>
Ticker ticker;
BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
// 3つのUUIDを下に書き込む。hatumei1を自分の好きな(本体と同じ)8文字に変えてください。
#define SERVICE_UUID "hatumei1-23f3-4fd7-9271-96aee32da1a3"
#define CHARACTERISTIC_UUID_RX "hatumei1-ce72-452f-af50-67cb23484128"
#define CHARACTERISTIC_UUID_TX "hatumei1-7116-4d54-b676-b81a86e3f407"
#define SERVER_NAME "esp32ble"
// I/O configuration
#define potGND 26
#define potVCC 27
#define potX 12
#define potY 14
#define joyK 13
#define BuiltinLED 2
uint16_t neutral_potX;
uint16_t neutral_potY;
uint16_t potX_val;
uint16_t potY_val;
uint16_t potX_data;
uint16_t potY_data;
uint16_t Txflag_F;
uint16_t button_K;
uint16_t data0 = 0;
std::string rx_Data;
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();
if (rxValue.length() > 0) {
for (int i = 0; i < rxValue.length(); i++)
rx_Data = rx_Data + rxValue[i];
}
}
};
// LED Blink
void ledBlink() {
volatile static int led = HIGH;
digitalWrite(BuiltinLED, led);
led = !led;
}
void setup() {
Serial.begin(115200);
pinMode(potX, INPUT);
pinMode(potY, INPUT);
pinMode(joyK, INPUT_PULLUP);
pinMode(potVCC, OUTPUT);
pinMode(potGND, OUTPUT);
pinMode(BuiltinLED, OUTPUT);
digitalWrite(potVCC, HIGH);
digitalWrite(potGND, LOW);
analogReadResolution(12);
neutral_potX = map(analogRead(potX), 0, 4095, 0, 255);
neutral_potY = map(analogRead(potY), 0, 4095, 0, 255);
ticker.attach(0.1, ledBlink);
Serial.println("BLE_Server_start");
delay(1000);
// Create the BLE Device
BLEDevice::init(SERVER_NAME);
// Create the BLE Server
BLEServer *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
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
digitalWrite(potVCC, HIGH);
digitalWrite(potGND, LOW);
analogReadResolution(12);
Txflag_F = 1; // Flag data
potX_val = map(analogRead(potX), 0, 4095, 0, 255); // Pot_x data
potY_val = map(analogRead(potY), 0, 4095, 0, 255); // Pot_y data
button_K = !digitalRead(joyK); // Joystick Button data
// convert potX neutral value
if (neutral_potX >= potX_val) {
potX_data = map(potX_val, neutral_potX, 0, 128, 0);
} else if (neutral_potX < potX_val) {
potX_data = map(potX_val, neutral_potX, 255, 128, 255);
}
// convert potY neutral value
if (neutral_potY >= potY_val) {
potY_data = map(potY_val, neutral_potY, 0, 128, 0);
} else if (neutral_potY < potY_val) {
potY_data = map(potY_val, neutral_potY, 255, 128, 255);
}
if (deviceConnected) {
//char buffer[10];
char buffer[20];
// Send data write
sprintf(buffer, "F:%d,X:%03d,Y:%03d,K:%d", Txflag_F, potX_data, potY_data, button_K);
pTxCharacteristic->setValue(buffer);
pTxCharacteristic->notify();
Serial.printf("*** NOTIFY: F:%d,X:%03d,Y:%03d,K:%d ***\n", Txflag_F, potX_data, potY_data, button_K);
// Receive data read
String Rxdata = rx_Data.c_str();
String str(Rxdata);
String subf = str.substring(0, 1);
data0 = subf.toInt(); // receive flag
//Serial.printf("%s", rx_Data.c_str());
//delay(1000);
} else {
data0 = 0;
}
// Connected LED
if (data0 == 1) {
digitalWrite(BuiltinLED, HIGH);
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
//Serial monitor
// Serial.print(F("\n\rTxflag: "));
// Serial.print(Txflag_F);
// Serial.print(F("\tpotX_data: "));
// Serial.print(potX_val);
// Serial.print(F("\tpotY_data: "));
// Serial.print(potY_val);
// Serial.print(F("\tbutton_K: "));
// Serial.print(button_K);
}
3つのUUIDの頭8桁をリモコン側と共通の自分固有のコードにしておきましょう。
1つめはSERVICE_UUID、2つめは送信用(TX)、3つめは受信用(RX)のUUID。リモコン(No.18)とはRXとTXが逆なので注意。
// === ESP32 BLE Client sample skech ===
#include <Arduino.h>
#include <BLEDevice.h>
#include <ESP32Servo.h>
#include <Ticker.h>
Ticker ticker;
Servo myServo;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
// 3つのUUIDを下に書き込む。hatumei1を自分の好きな(リモコンと同じ)8文字に変えてください。
#define SERVICE_UUID "hatumei1-23f3-4fd7-9271-96aee32da1a3"
#define CHARACTERISTIC_UUID_TX "hatumei1-ce72-452f-af50-67cb23484128"
#define CHARACTERISTIC_UUID_RX "hatumei1-7116-4d54-b676-b81a86e3f407"
#define SERVER_NAME "esp32ble"
#define Tx_value '1' // send to Server "1"
// Board Using pin
#define builtinLED 2 // Onboard Blue LED LEDC_BASE_FREQ, LEDC_TIMER_BIT
#define SERVO_PIN 13 // Servo Orange Wire
#define LEDR 27 // Red LED
#define LEDG 17 // Green LED
#define LEDB 16 // Blue LED
#define in1 25 // PWM pin
#define in2 26 // PWM pin
#define in3 32 // PWM pin
#define in4 33 // PWM pin
#define LEDC_CHANNEL_1 3 // Channel 3
#define LEDC_CHANNEL_2 4 // Channel 4
#define LEDC_CHANNEL_3 5 // Channel 5
#define LEDC_CHANNEL_4 6 // Channel 6
#define LEDC_BASE_FREQ 100.0 // キャリア周波数設定 100Hz
#define LEDC_TIMER_BIT 8 // 分解能8bit(0-255)
int Rx_flag = 0; // received flag
int xAxis = 512; // Joystick X-Nutral Value
int yAxis = 512; // Joystick Y-Nutral Value
int speedLeft = 255; // 反転回路があるので255が最弱、0が最強である
int speedRight = 255;
int stop_speed = 255; // DC Motor Stop Value
int lowest_speed_bitL = 140; // DC Motor lowest rotation Value
int lowest_speed_bitR = 160; // DC Motor lowest rotation Value
int data0, data1, data2, data3; // Recieve data 0-3
unsigned long previoustime0 = 0;
unsigned long previoustime1 = 0;
unsigned long previoustime2 = 0;
static BLEUUID serviceUUID(SERVICE_UUID);
static BLEUUID charUUID_RX(CHARACTERISTIC_UUID_RX);
static BLEUUID charUUID_TX(CHARACTERISTIC_UUID_TX);
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic *pRemoteCharacteristicRX;
static BLERemoteCharacteristic *pRemoteCharacteristicTX;
static void notifyCallback(
BLERemoteCharacteristic *pBLERemoteCharacteristic,
uint8_t *pData,
size_t length,
bool isNotify)
{
Serial.print("Notify callback for characteristic ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
Serial.println((char *)pData);
}
class MyClientCallback : public BLEClientCallbacks
{
void onConnect(BLEClient *pclient)
{
}
void onDisconnect(BLEClient *pclient)
{
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer(BLEAddress pAddress)
{
Serial.print("Forming a connection to ");
Serial.println(pAddress.toString().c_str());
BLEClient *pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server
pClient->connect(pAddress);
Serial.println(" - Connected to server");
pClient->setMTU(517); // set client to request maximum MTU from server
BLERemoteService *pRemoteService = pClient->getService(serviceUUID);
Serial.print(" - Connected to server :");
Serial.println(serviceUUID.toString().c_str());
if (pRemoteService == nullptr)
{
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
// Get the reference of the characteristic for Receive
pRemoteCharacteristicRX = pRemoteService->getCharacteristic(charUUID_RX);
if (pRemoteCharacteristicRX == nullptr)
{
Serial.print("Failed to find characteristic RX ID: ");
Serial.println(charUUID_RX.toString().c_str());
pClient->disconnect();
return false;
}
Serial.print(" - Found characteristic RX ID: ");
Serial.println(charUUID_RX.toString().c_str());
// Get the reference of the characteristic for Send
pRemoteCharacteristicTX = pRemoteService->getCharacteristic(charUUID_TX);
if (pRemoteCharacteristicTX == nullptr)
{
Serial.print("Failed to find characteristic TX ID ");
Serial.println(charUUID_TX.toString().c_str());
pClient->disconnect();
return false;
}
Serial.print(" - Found characteristic TX ID: ");
Serial.println(charUUID_TX.toString().c_str());
// Read the value of the characteristic
if (pRemoteCharacteristicRX->canRead())
{
std::string value = pRemoteCharacteristicRX->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if (pRemoteCharacteristicRX->canNotify())
// pRemoteCharacteristicRX->registerForNotify(notifyCallback);
// Serial.println("End of notify");
return true;
}
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice)
{
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
Serial.println(advertisedDevice.getName().c_str());
if (advertisedDevice.getName() == SERVER_NAME)
{
Serial.println(advertisedDevice.getAddress().toString().c_str());
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
doConnect = true;
}
}
};
void get_scan()
{
BLEScan *pBLEScan = BLEDevice::getScan();
Serial.println("getScan");
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
Serial.println("setAdvertisedDeviceCallbacks");
pBLEScan->setActiveScan(true);
pBLEScan->start(5);
Serial.println("");
Serial.println("End of scan");
}
// LEDC Setup Attach Channel
void ledc_attach_channel()
{
ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_2, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_3, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcSetup(LEDC_CHANNEL_4, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
ledcAttachPin(in1, LEDC_CHANNEL_1);
ledcAttachPin(in2, LEDC_CHANNEL_2);
ledcAttachPin(in3, LEDC_CHANNEL_3);
ledcAttachPin(in4, LEDC_CHANNEL_4);
}
void ledBlink()
{
volatile static int led = HIGH;
digitalWrite(builtinLED, led);
led = !led;
}
void setup()
{
Serial.begin(115200);
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
pinMode(builtinLED, OUTPUT);
Serial.println("BLE_Cliant_start");
BLEDevice::init("");
get_scan();
Serial.println("BLE End of setup");
ticker.attach(0.1, ledBlink);
myServo.attach(SERVO_PIN);
ledc_attach_channel();
delay(500);
}
void loop()
{
unsigned long currenttime = millis();
if (doConnect == true)
{
if (connectToServer(*pServerAddress))
{
Serial.println("We are now connected to the BLE Server.");
connected = true;
}
else
{
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
connected = false;
}
doConnect = false;
}
if (connected)
{
// Connection Handling
ticker.detach();
digitalWrite(builtinLED, HIGH);
// Receive data read
std::string Rxvalue = pRemoteCharacteristicRX->readValue();
String Rxdata = Rxvalue.c_str(); // copy str(value)
String str(Rxdata);
String subf = str.substring(2, 3); // Flag
String subx = str.substring(6, 9); // potX data
String suby = str.substring(12, 15); // potY data
String subk = str.substring(18, 19); // buttonK data
// Convert int flag xyAxis and buttonK
data0 = subf.toInt(); // receive flag
data1 = subx.toInt(); // joystick X value
data2 = suby.toInt(); // joystick Y value
data3 = subk.toInt(); // joystick button
// Serial Monitor Received Data
char buffer[20];
// sprintf(buffer, "F:%d X:%03d Y:%03d K:%d", data0, data1, data2, data3);
// Serial.println(buffer);
// to Server Send data
pRemoteCharacteristicTX->writeValue(Tx_value);
// Serial.println(Tx_value);
// delay(1000);
}
else
{
digitalWrite(builtinLED, LOW);
ticker.attach(0.1, ledBlink);
// reconnecting
Serial.println("Not connected");
doConnect = false;
get_scan();
}
// Connected Receive Flag
if (data0 == 1)
{
// Pot data Numeric Replace
xAxis = map(data1, 0, 255, 0, 1023);
yAxis = map(data2, 0, 255, 0, 1023);
// Forward
if (yAxis > 660)
{
speedLeft = map(yAxis, 510, 1023, lowest_speed_bitL, 0);
speedRight = map(yAxis, 510, 1023, lowest_speed_bitR, 0);
// Left turn
if (xAxis < 360)
{
// int xMapped = map(xAxis, 0, 510, 255, 0);
speedLeft = lowest_speed_bitL;
if (speedRight < 0)
{
speedRight = 0;
}
if (speedLeft > 100)
{
speedLeft = 100;
}
}
// Right turn
else if (xAxis > 660)
{
// int xMapped = map(xAxis, 510, 1023, 0, 255);
speedRight = lowest_speed_bitR;
}
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_2, stop_speed);
ledcWrite(LEDC_CHANNEL_3, speedRight);
ledcWrite(LEDC_CHANNEL_4, stop_speed);
}
// Backward
if (yAxis < 360)
{
speedLeft = map(yAxis, 510, 0, lowest_speed_bitL, 0);
speedRight = map(yAxis, 510, 0, lowest_speed_bitR, 0);
// Left turn (back)
if (xAxis < 360)
{
// int xMapped = map(xAxis, 0, 510, 255, 0);
speedLeft = lowest_speed_bitL;
}
// Right turn (back)
else if (xAxis > 660)
{
// int xMapped = map(xAxis, 510, 1023, 0, 255);
speedRight = lowest_speed_bitR;
}
ledcWrite(LEDC_CHANNEL_1, stop_speed);
ledcWrite(LEDC_CHANNEL_2, speedLeft);
ledcWrite(LEDC_CHANNEL_3, stop_speed);
ledcWrite(LEDC_CHANNEL_4, speedRight);
}
// Pivot Left turn
if (yAxis >= 360 && yAxis <= 660 && xAxis < 360)
{
speedLeft = map(xAxis, 510, 0, lowest_speed_bitL, 0);
speedRight = map(xAxis, 510, 0, lowest_speed_bitR, 0);
ledcWrite(LEDC_CHANNEL_1, stop_speed);
ledcWrite(LEDC_CHANNEL_2, speedLeft);
ledcWrite(LEDC_CHANNEL_3, speedRight);
ledcWrite(LEDC_CHANNEL_4, stop_speed);
}
// Pivot Right turn
if (yAxis >= 360 && yAxis <= 660 && xAxis > 660)
{
speedLeft = map(xAxis, 510, 1023, lowest_speed_bitL, 0);
speedRight = map(xAxis, 510, 1023, lowest_speed_bitR, 0);
ledcWrite(LEDC_CHANNEL_1, speedLeft);
ledcWrite(LEDC_CHANNEL_2, stop_speed);
ledcWrite(LEDC_CHANNEL_3, stop_speed);
ledcWrite(LEDC_CHANNEL_4, speedRight);
}
// Joystick neutral
if ((yAxis >= 360 && yAxis <= 660) && (xAxis >= 360 && xAxis <= 660))
{
ledcWrite(LEDC_CHANNEL_1, stop_speed);
ledcWrite(LEDC_CHANNEL_2, stop_speed);
ledcWrite(LEDC_CHANNEL_3, stop_speed);
ledcWrite(LEDC_CHANNEL_4, stop_speed);
}
// joystick button LED
if (data3 == 1)
{
digitalWrite(LEDB, HIGH);
myServo.write(150);
}
else
{
digitalWrite(LEDB, LOW);
myServo.write(90);
}
// Motor Drive LED
if (speedLeft < 95 || speedRight < 95)
{
digitalWrite(LEDG, HIGH);
}
else
{
digitalWrite(LEDG, LOW);
}
// serial monitor
// Serial.print(F("\r\nxAxis: "));
// Serial.print(xAxis);
// Serial.print(F("\tyAxis: "));
// Serial.print(yAxis);
// Serial.print(F("\tspeedLeft: "));
// Serial.print(speedLeft);
// Serial.print(F("\tspeedRight: "));
// Serial.print(speedRight);
// Serial.print(F("\tbutton5: "));
// Serial.print(data3);
}
}