feat: basic ir mode

This commit is contained in:
玖叁 2024-12-27 11:32:09 +08:00
parent c1112b65c5
commit fc0aac6803
9 changed files with 126 additions and 29 deletions

View File

@ -46,4 +46,10 @@ git clone https://github.com/colour93/esp32-car.git
同时一些状态信息会主动发送。 同时一些状态信息会主动发送。
[数据包格式](./packet.md) [数据包格式](./packet.md)
## Android APP
这是一个配套的 Android APP基于 Kotlin + Compose通信协议使用上面的 BLE 串口通信协议。
[colour93/esp32-car-android](https://github.com/colour93/esp32-car-android)

View File

@ -15,6 +15,14 @@
#define HC_SR04_TRIG 23 #define HC_SR04_TRIG 23
#define HC_SR04_ECHO 22 #define HC_SR04_ECHO 22
// 红外循迹模块引脚
// 模式选择
#define IR_MODE IRMode::IR_MODE_GPIO
// GPIO 模式
#define IR_PINS {34, 35, 12, 13, 15}
// 串口模式
// #define IR_PINS {34, 35}
// TB6612 #1 控制 A B 电机 // TB6612 #1 控制 A B 电机
// A 电机 左前轮 // A 电机 左前轮
#define MOTOR_A_PWMA 21 // 电机 A PWM #define MOTOR_A_PWMA 21 // 电机 A PWM

View File

@ -7,6 +7,7 @@
#include "ultrasound.h" #include "ultrasound.h"
#include "transmit.h" #include "transmit.h"
#include "pid.h" #include "pid.h"
#include "ir.h"
#include "utils.h" #include "utils.h"
// 指令定义 // 指令定义

33
include/ir.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef IR_H
#define IR_H
#include <Arduino.h>
enum IRMode
{
IR_MODE_GPIO,
IR_MODE_UART
};
struct IRConfig
{
IRMode mode;
uint8_t pins[5];
};
struct IRData
{
uint8_t length;
uint8_t data[8];
};
class IR
{
public:
static IRConfig config;
static IRData data;
static void init(IRConfig config);
static void update();
};
#endif

View File

@ -132,8 +132,15 @@
## 状态回报 ## 状态回报
### 电机状态汇`0xE0` ### 设备状态回`0xE0`
包体 `01 0C E0 电机A_IN_1_2 电机A_PWM 电机B_IN_1_2 电机B_PWM 电机C_IN_1_2 电机C_PWM 电机D_IN_1_2 电机D_PWM FE` 包体 `01 0E E0 电机A_IN_1_2 电机A_PWM 电机B_IN_1_2 电机B_PWM 电机C_IN_1_2 电机C_PWM 电机D_IN_1_2 电机D_PWM 红外引脚数量 红外数据 FE`
示例 `01 0C E0 01 FF 02 FF 02 FF 01 FF FE` | 数据 | 类型 | 表示 |
| -------- | ---- | ---- |
| IN_1_2 | 无符号整数 | 按位表示 IN1 IN2 的值, 0000 00 IN2 IN1 |
| PWM | 无符号整数 | - |
| 红外引脚数量 | 无符号整数 | - |
| 红外数据 | 无符号整数 | 按位表示红外循迹模块数据, 0001 1111 |
示例 `01 0E E0 01 FF 02 FF 02 FF 01 FF 05 1F FE`

View File

@ -18,27 +18,29 @@ void Handlers::getBTStatus(BLECharacteristic &characteristic)
void Handlers::getSPIFFSStatus(BLECharacteristic &characteristic) void Handlers::getSPIFFSStatus(BLECharacteristic &characteristic)
{ {
Serial.println("CMD_GET_SPIFFS_STATUS"); Serial.println("CMD_GET_SPIFFS_STATUS");
uint8_t bufferIndex = 0;
// 构建响应数据 // 构建响应数据
buffer[0] = PACKET_T_HEAD; buffer[bufferIndex++] = PACKET_T_HEAD;
buffer[1] = 0x05; buffer[bufferIndex++] = 0x05;
buffer[2] = CMD_GET_SPIFFS_STATUS; buffer[bufferIndex++] = CMD_GET_SPIFFS_STATUS;
buffer[3] = (uint8_t)(Storage::isMounted ? 0x01 : 0x00); buffer[bufferIndex++] = (uint8_t)(Storage::isMounted ? 0x01 : 0x00);
buffer[4] = PACKET_T_TAIL; buffer[bufferIndex++] = PACKET_T_TAIL;
characteristic.setValue(buffer, 5); characteristic.setValue(buffer, bufferIndex);
characteristic.notify(); characteristic.notify();
} }
void Handlers::getDistance(BLECharacteristic &characteristic) void Handlers::getDistance(BLECharacteristic &characteristic)
{ {
float distance = Ultrasonic::getDistance(); float distance = Ultrasonic::getDistance();
uint8_t bufferIndex = 0;
Serial.println("CMD_GET_DISTANCE, distance: " + String(distance)); Serial.println("CMD_GET_DISTANCE, distance: " + String(distance));
// 构建响应数据 // 构建响应数据
buffer[0] = PACKET_T_HEAD; buffer[bufferIndex++] = PACKET_T_HEAD;
buffer[1] = 0x08; buffer[bufferIndex++] = 0x08;
buffer[2] = CMD_GET_DISTANCE; buffer[bufferIndex++] = CMD_GET_DISTANCE;
floatToBytes(distance, &buffer[3]); floatToBytes(distance, &buffer[bufferIndex]);
buffer[7] = PACKET_T_TAIL; buffer[bufferIndex++] = PACKET_T_TAIL;
characteristic.setValue(buffer, 8); characteristic.setValue(buffer, bufferIndex);
characteristic.notify(); characteristic.notify();
} }

28
src/ir.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "ir.h"
IRConfig IR::config;
IRData IR::data;
void IR::init(IRConfig config)
{
IR::config = config;
if (config.mode == IRMode::IR_MODE_GPIO)
{
data.length = 5;
for (int i = 0; i < 5; i++)
{
pinMode(config.pins[i], INPUT);
}
}
}
void IR::update()
{
if (config.mode == IRMode::IR_MODE_GPIO)
{
for (int i = 0; i < 5; i++)
{
data.data[i] = digitalRead(config.pins[i]);
}
}
}

View File

@ -4,6 +4,7 @@
#include "storage.h" #include "storage.h"
#include "ble.h" #include "ble.h"
#include "led.h" #include "led.h"
#include "ir.h"
#include "consts.h" #include "consts.h"
void setup() void setup()
@ -24,6 +25,9 @@ void setup()
{MOTOR_C_PWMA, MOTOR_C_AIN1, MOTOR_C_AIN2}, {MOTOR_C_PWMA, MOTOR_C_AIN1, MOTOR_C_AIN2},
{MOTOR_D_PWMB, MOTOR_D_BIN1, MOTOR_D_BIN2}); {MOTOR_D_PWMB, MOTOR_D_BIN1, MOTOR_D_BIN2});
// 初始化红外循迹模块
IR::init({IR_MODE, IR_PINS});
// 初始化状态灯 // 初始化状态灯
if (STATUS_LED_ENABLE) if (STATUS_LED_ENABLE)
{ {

View File

@ -115,19 +115,27 @@ void sendStatus(BLECharacteristic &characteristic)
lastMotorStatusUpdate = currentMillis; lastMotorStatusUpdate = currentMillis;
uint8_t buffer[PACKET_MAX_LENGTH]; uint8_t buffer[PACKET_MAX_LENGTH];
buffer[0] = PACKET_T_HEAD; uint8_t bufferIndex = 0;
buffer[1] = 0x0C; buffer[bufferIndex++] = PACKET_T_HEAD;
buffer[2] = CMD_STATUS_MOTOR; buffer[bufferIndex++] = 0x0C;
buffer[3] = (MotorController::getMotorStatus('A').in2 << 1) | MotorController::getMotorStatus('A').in1; buffer[bufferIndex++] = CMD_STATUS_MOTOR;
buffer[4] = MotorController::getMotorStatus('A').pwm; buffer[bufferIndex++] = (MotorController::getMotorStatus('A').in2 << 1) | MotorController::getMotorStatus('A').in1;
buffer[5] = (MotorController::getMotorStatus('B').in2 << 1) | MotorController::getMotorStatus('B').in1; buffer[bufferIndex++] = MotorController::getMotorStatus('A').pwm;
buffer[6] = MotorController::getMotorStatus('B').pwm; buffer[bufferIndex++] = (MotorController::getMotorStatus('B').in2 << 1) | MotorController::getMotorStatus('B').in1;
buffer[7] = (MotorController::getMotorStatus('C').in2 << 1) | MotorController::getMotorStatus('C').in1; buffer[bufferIndex++] = MotorController::getMotorStatus('B').pwm;
buffer[8] = MotorController::getMotorStatus('C').pwm; buffer[bufferIndex++] = (MotorController::getMotorStatus('C').in2 << 1) | MotorController::getMotorStatus('C').in1;
buffer[9] = (MotorController::getMotorStatus('D').in2 << 1) | MotorController::getMotorStatus('D').in1; buffer[bufferIndex++] = MotorController::getMotorStatus('C').pwm;
buffer[10] = MotorController::getMotorStatus('D').pwm; buffer[bufferIndex++] = (MotorController::getMotorStatus('D').in2 << 1) | MotorController::getMotorStatus('D').in1;
buffer[11] = PACKET_T_TAIL; buffer[bufferIndex++] = MotorController::getMotorStatus('D').pwm;
characteristic.setValue(buffer, 12); buffer[bufferIndex++] = IR::data.length;
uint16_t irData = 0;
for (uint8_t i = 0; i < IR::data.length; i++)
{
irData |= (IR::data.data[i] << (i * 2));
}
buffer[bufferIndex++] = irData;
buffer[bufferIndex++] = PACKET_T_TAIL;
characteristic.setValue(buffer, bufferIndex);
characteristic.notify(); characteristic.notify();
} }
} }