实训一:蓝牙开锁
一、实验目的
ESP32的蓝牙模块接收手机传过来的开锁命令和密码,通过判断密码是否正确来确定舵机是否转动
二、实验内容
1.ESP32与舵机进行连接
2.ESP32连接手机蓝牙
3.手机通过BLE调试助手向ESP32发送开锁命令和密码
4.ESP32接收数据后判断舵机是否转动
ps:开锁命令是
三、实验设备
1.ESP32开发板
2.SG90舵机
3.手机APP BLE调试助手
四、实验步骤
1) 环境配置
1.打开Arduino IDE,选择左上角 工具–开发板,选择对应的开发板(ESP32DevModule)
2.选择 工具–端口 , 选择对应的端口
3.此实训需要的ESP32的servo库之前已经导入
2)连接引脚
SG90:
SG90 的引脚:红色的连接5V电压,黄色为PWM信号线,棕色为接地线
连接:
3)上传程序
#include <dummy.h>
#include <Servo.h>
#include <BLEDevice.h>
#include <BLE2902.h>
#include <String.h>
#define SERVO_PIN 15
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
#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"
#define openInterval 5000
byte ble_rx_buffer[20]; //接收蓝牙指令
byte verfi_code[6] = {0x31,0x32,0x33,0x34,0x35,0x36};//初始密码
Servo myservo;
int pos=0;
bool toggle; //开锁判断位
void locker(bool toggle) { //开锁
myservo.attach(SERVO_PIN);
if (toggle) {
myservo.write(90); // 开锁
} else {
myservo.write(0); // 关锁
}
delay(250); // 等马达转到定位
myservo.detach();
}
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
//55aa0010313233343536 蓝牙发送开门指令,hex 16进制发送
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
byte op;
for (int i = 0; i < rxValue.length(); i++){
ble_rx_buffer[i] = rxValue[i];
Serial.print(rxValue[i]);
}
if(ble_rx_buffer[0] == 0x55 && ble_rx_buffer[1] == 0xaa){
op=ble_rx_buffer[3];
switch(op){
case 0x10:{ //蓝牙开门
if(memcmp(ble_rx_buffer+5,verfi_code,6)){
toggle = true;
Serial.println("开门成功");
}
else{
Serial.println("密码错误");
}
break;
}
case 0x20:{ //设置密码
break;
}
case 0x30:{ //查看指纹
break;
}
case 0x31:{//添加指纹
break;
}
case 0x32:{ //删除指纹
break;
}
}
//locker(toggle);
}
}
};
void setupBLE(String BLEName){ //连接蓝牙
const char *ble_name = BLEName.c_str();
BLEDevice::init(ble_name);
BLEServer *pServer = BLEDevice::createServer(); //创建服务
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX,BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic->addDescriptor(new BLE2902()); //添加描述
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX,BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks()); //receive message callback
pService->start();// Start the service
pServer->getAdvertising()->start();// Start advertising
Serial.println("Waiting a client connection to notify...");
}
void setup() {
Serial.begin(115200);
setupBLE("ESP32 Device");//设置蓝牙名称
myservo.attach(SERVO_PIN); //引脚12为PWM脚
}
void loop() {
static unsigned long toggle_time = millis();
static bool lock_back_flag=false;
if(toggle){ //开门计时
locker(toggle); //开锁
toggle = false;
lock_back_flag = true;
toggle_time = millis();
}
if(millis() - toggle_time > openInterval && lock_back_flag){ //回锁时间
lock_back_flag = false;
locker(toggle);//回锁
}
}
4)手机APP发送信息
通讯协议:
字段 | 帧头 | 标识 | 校验和 | 数据 |
---|---|---|---|---|
长度 | 2B | 1B | 1B | 16B |
帧头:55aa
标识:
10 : 蓝牙开门
20:设置密码
30:查看指纹
31:添加指纹
32:删除指纹
检验和:目前不做校验,填00即可
数据: 16字节,可以不填满
蓝牙开门
字段 | 帧头 | 标识 | 校验和 | 数据 |
---|---|---|---|---|
内容 | 55aa | 10 | 00 | 6B初始密码 |
蓝牙开门发送消息案例:55aa1000313233343536
ps:都是以16进制发送,对应相应的ASCII码
5)发送成功观察串口监视器内容和舵机状态
串口监视器:
舵机:转90度后5s回转