Skip to content

Commit 94079c8

Browse files
authored
Add files via upload
2025年度版ESP Racer(ESP32S3対応)ソースコード
1 parent 381b899 commit 94079c8

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

ESP_Racer_2025.ino

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// update: 2025/04/30 v3 コア完全対応 + タイマー再設計 + 広告名明示
2+
3+
#include <BLEDevice.h>
4+
#include <BLEUtils.h>
5+
#include <BLEServer.h>
6+
#include <BLE2902.h>
7+
8+
/*========== BLE UUID ==========*/
9+
#define SERVICE_UUID "389CAAF0-843F-4D3B-959D-C954CCE14655"
10+
#define GET_BATTERY_VOLTAGE "389CAAF1-843F-4D3B-959D-C954CCE14655"
11+
#define SET_MOTOR_PWM "389CAAF2-843F-4D3B-959D-C954CCE14655"
12+
#define SET_PORT_OUT "389CAAF3-843F-4D3B-959D-C954CCE14655"
13+
#define SET_SERVO_POSITION "389CAAF4-843F-4D3B-959D-C954CCE14655"
14+
#define BURST_COMMAND "389CAAF5-843F-4D3B-959D-C954CCE14655"
15+
#define GET_FUNCTIONS "389CAAFF-843F-4D3B-959D-C954CCE14655"
16+
17+
/*========== I/O (Seeed Xiao ESP32-S3) ==========*/
18+
#define power_led 1
19+
#define servo_pin 2
20+
#define motor0_pin 3
21+
#define motor1_pin 4
22+
#define port0_led 5
23+
#define port1_led 6
24+
25+
/*========== globals ==========*/
26+
BLECharacteristic *pCharacteristic1;
27+
BLECharacteristic *pCharacteristic2;
28+
BLECharacteristic *pCharacteristic3;
29+
BLECharacteristic *pCharacteristic4;
30+
BLECharacteristic *pCharacteristic5;
31+
BLECharacteristic *pCharacteristic6;
32+
BLEAdvertising *pAdvertising;
33+
34+
unsigned char motor_power = 127;
35+
unsigned char servo_power = 127;
36+
37+
volatile uint32_t interruptCounter = 0; // 割り込みカウンタ
38+
hw_timer_t *timer = nullptr;
39+
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
40+
static int light = LOW; // LED トグル用
41+
42+
/*========== timer ISR ==========*/
43+
void IRAM_ATTR onTimer() {
44+
portENTER_CRITICAL_ISR(&timerMux);
45+
++interruptCounter;
46+
portEXIT_CRITICAL_ISR(&timerMux);
47+
}
48+
49+
/*========== BLE Callbacks ==========*/
50+
class MyCallbacks : public BLECharacteristicCallbacks {
51+
void onWrite(BLECharacteristic *pCharacteristic) override {
52+
String value = pCharacteristic->getValue();
53+
if (value.length() < 4) return; // データ不足時は無視
54+
55+
motor_power = value[1]; // DC モータ
56+
if (value[2] == 3) { // ポート LED
57+
digitalWrite(port0_led, HIGH);
58+
digitalWrite(port1_led, HIGH);
59+
} else {
60+
digitalWrite(port0_led, LOW);
61+
digitalWrite(port1_led, LOW);
62+
}
63+
servo_power = value[3]; // サーボ
64+
}
65+
};
66+
67+
class ServerCallbacks : public BLEServerCallbacks {
68+
void onConnect(BLEServer*) override {
69+
Serial.println("connect.");
70+
motor_power = servo_power = 127;
71+
timerAlarm(timer, 100'000, true, 0); // LED:0.1 s 周期
72+
}
73+
void onDisconnect(BLEServer*) override {
74+
Serial.println("disconnect.");
75+
motor_power = servo_power = 127;
76+
timerAlarm(timer, 500'000, true, 0); // LED:0.5 s 周期
77+
}
78+
};
79+
80+
/*========== SETUP ==========*/
81+
void setup() {
82+
Serial.begin(115200);
83+
Serial.print("starting...");
84+
85+
pinMode(servo_pin, OUTPUT);
86+
pinMode(motor0_pin, OUTPUT);
87+
pinMode(motor1_pin, OUTPUT);
88+
pinMode(power_led, OUTPUT);
89+
pinMode(port0_led, OUTPUT);
90+
pinMode(port1_led, OUTPUT);
91+
92+
/*----- ハードウェアタイマー -----*/
93+
timer = timerBegin(1'000'000); // 1 MHz (1 µs 分解能)
94+
timerAttachInterrupt(timer, &onTimer);
95+
timerAlarm(timer, 500'000, true, 0); // 初期:0.5 s 周期
96+
97+
/*----- BLE 初期化 -----*/
98+
BLEDevice::init("ESP Racer");
99+
BLEServer *pServer = BLEDevice::createServer();
100+
BLEService *pService = pServer->createService(SERVICE_UUID);
101+
102+
pCharacteristic1 = pService->createCharacteristic(GET_BATTERY_VOLTAGE, BLECharacteristic::PROPERTY_READ);
103+
pCharacteristic2 = pService->createCharacteristic(SET_MOTOR_PWM, BLECharacteristic::PROPERTY_WRITE_NR);
104+
pCharacteristic3 = pService->createCharacteristic(SET_PORT_OUT, BLECharacteristic::PROPERTY_WRITE_NR);
105+
pCharacteristic4 = pService->createCharacteristic(SET_SERVO_POSITION, BLECharacteristic::PROPERTY_WRITE_NR);
106+
pCharacteristic5 = pService->createCharacteristic(BURST_COMMAND, BLECharacteristic::PROPERTY_WRITE_NR);
107+
pCharacteristic6 = pService->createCharacteristic(GET_FUNCTIONS, BLECharacteristic::PROPERTY_READ);
108+
109+
pCharacteristic5->setCallbacks(new MyCallbacks());
110+
pServer->setCallbacks(new ServerCallbacks());
111+
112+
pService->start();
113+
114+
/*----- 広告データに名前を明示 -----*/
115+
pAdvertising = pServer->getAdvertising();
116+
pAdvertising->addServiceUUID(SERVICE_UUID);
117+
pAdvertising->setScanResponse(true); // 名前はスキャン応答へ
118+
BLEAdvertisementData scanData;
119+
scanData.setName("ESP Racer"); // ブラウザ等に表示される名前
120+
pAdvertising->setScanResponseData(scanData);
121+
pAdvertising->start();
122+
123+
Serial.println("done.");
124+
}
125+
126+
/*========== LOOP ==========*/
127+
void loop() {
128+
constexpr unsigned int control_phase = 16'000; // 16 ms
129+
unsigned int servo_on = 1'500 + (servo_power - 127) * 4; // 1012–1992 µs
130+
unsigned int motor_on = control_phase * abs(motor_power - 127) / 200;
131+
132+
/*----- 電源 LED 点滅 -----*/
133+
if (interruptCounter > 0) {
134+
portENTER_CRITICAL(&timerMux);
135+
--interruptCounter;
136+
portEXIT_CRITICAL(&timerMux);
137+
138+
light ^= 1;
139+
digitalWrite(power_led, light);
140+
}
141+
142+
/*----- DC モータ & サーボ制御 -----*/
143+
if (motor_on > servo_on) { // モータ優先
144+
if (motor_power > 127) { // 正転
145+
digitalWrite(motor0_pin, HIGH);
146+
digitalWrite(motor1_pin, LOW);
147+
motor_on += control_phase / 4;
148+
} else if (motor_power < 127) { // 逆転
149+
digitalWrite(motor0_pin, LOW);
150+
digitalWrite(motor1_pin, HIGH);
151+
motor_on += control_phase / 4;
152+
} else { // 停止
153+
digitalWrite(motor0_pin, HIGH);
154+
digitalWrite(motor1_pin, HIGH);
155+
}
156+
digitalWrite(servo_pin, HIGH);
157+
delayMicroseconds(servo_on);
158+
digitalWrite(servo_pin, LOW);
159+
delayMicroseconds(motor_on - servo_on);
160+
digitalWrite(motor0_pin, LOW);
161+
digitalWrite(motor1_pin, LOW);
162+
delayMicroseconds(control_phase - motor_on);
163+
164+
} else { // サーボのみ
165+
digitalWrite(servo_pin, HIGH);
166+
delayMicroseconds(servo_on);
167+
digitalWrite(servo_pin, LOW);
168+
delayMicroseconds(control_phase - servo_on);
169+
}
170+
}

0 commit comments

Comments
 (0)