实验九:语音广播
一、实验目的
ESP32通过一线串口通信,通过DATA线给WTN6系列语音芯片,发送相应的数据,播放第一段的语音。结合相应的锁操作,播放相应的语音内容,如蓝牙开门操作后,播放已开门。
二、实验内容
1.ESP连接语音模块 2.上传程序ESP32 3.语音模块与喇叭连接,相应操作后播放相应的语音
三、实验设备
WTN6系列语音模块 ESP32开发板 8R/0.5W喇叭
四、实验步骤
1)连接引脚
语音模块:
语音模块的引脚:PA1接ESP32的32脚,PWM 和PWM-接喇叭
连接图:
2)上传程序
/*Author :王滨伟 * Time :2020.6.11 */ #include <dummy.h> #include <Servo.h> #include <BLEDevice.h> #include <BLE2902.h> #include <String.h> #include <Keypad.h> #include <SPI.h> #include <MFRC522.h> #include <Adafruit_Fingerprint.h> #include <WiFi.h> /* * ESP32 引脚17(TX)和16(RX)上的Serial2 * 指纹模块 连 接 ESP32 RX黄 --- 17 TX绿 --- 16 */ #define mySerial Serial2 #define Horn_Pin 32 ///定义语音模块脚位 #define SS_PIN 21 //定义RC522的SDA引脚的接线位置 #define RST_PIN 22 //定义RC522的RST引脚的接线位置 #define SERVO_PIN 15 //舵机的脚位 #define NormolClose 13 #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 3000 #define fpInterval 5000 BLECharacteristic *pCharacteristic; bool deviceConnected = false; char* SSID = "TP-LINK_9C1F"; //wifi名称 char* PassWord = "cyykj2018"; //wifi密码 /* * 按键初始量 */ cont byte ROWS = 4; //four rows const byte COLS = 3; //three columns char keys[ROWS][COLS] = { { '1','2','3'}, { '4','5','6'}, { '7','8','9'}, { '*','0','#'} }; byte rowPins[ROWS] = { 33, 27, 14, 12}; //connect to the row pinouts of the keypad byte colPins[COLS] = { 4, 0, 2}; //connect to the column pinouts of the keypad /* * RFID
标签结构体 */ struct RFIDTag { //Tag标签结构体 uint8_t uid[4]; char *name; }; MFRC522 rfid(SS_PIN, RST_PIN); //实例化类 struct RFIDTag tags[20] = { // 初始化结构资料,请自行修改RFID识别码 { { 219, 25, 26, 28}, "Mini_Tag"}, { { 0, 0, 0, 0}, "Mini_Tag1"}, { { 1, 1, 1, 1}, "Mini_Tag2"}, }; /*wifi IP和端口配置*/ const IPAddress serverIP(192,168,0,113); //欲访问的地址 uint16_t serverPort = 53123; //服务器端口号,修改自己服务器的端口号 WiFiClient client; //声明一个客户端对象,用于与服务器进行连接 byte totalTags = sizeof(tags) / sizeof(RFIDTag); //计算结构资料的数量 bool door_open_flag; //开门动作标志位 bool alarm_flag;//报警标志位 static bool lock_back_flag=false; //回锁标志位 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte ble_rx_buffer[20]; //接收蓝牙指令 byte verfi_code[6] = { 0x31,0x32,0x33,0x34,0x35,0x36};//初始密码 byte init_pw[6] = { 1,2,3,4,5,6};//初始按键密码 Servo myservo; Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); bool FP_busy=false; short active_fp = -1; //激活指纹模块, -1休眠,1激活,2指纹模块正在激活时间 int pos=0; bool toggle; //开锁判断位 byte message_type;//上传信息的类型 void locker(bool toggle) { //开锁 myservo.attach(SERVO_PIN); if (toggle) { myservo.write(90); // 开锁 } else { myservo.write(0); // 关锁 } delay(500); // 等马达转到定位 myservo.detach(); } class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; /* C++多态,创建类MyCallbacks,继承类BLECharacteristicCallbacks * 类MyCallbacks,下的成员函数onWrite(),接收蓝牙消息处理函数 * 55aa1000313233343536 蓝牙发送开门指令,hex 16进制发送 * 55aa2000363534333231 蓝牙修改密码指令 * 55aa3000000000000000 蓝牙查询指令 * 55aa3100310000000000 蓝牙注册指纹 注册id号为01 * 55aa3200330000000000 蓝牙删除指纹 删除id号为03 */ 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[2]; switch(op){ case 0x10:{ //蓝牙开门 if(memcmp(ble_rx_buffer+4,verfi_code,6) == 0 && lock_back_flag==false){ //匹配成功,切不在回锁状态 toggle = true; message_type = 6; Serial.println("开门成功"); } else{ Serial.println("密码错误"); } break; } case 0x20:{ //设置密码 static byte temp_pw[6]; //临时密码 for(byte i=0;i<6;i++){ if(ble_rx_buffer[i+4]<=0x39 && ble_rx_buffer[i+4]>=0x30){ //保证密码在0-9之间 temp_pw[i]=ble_rx_buffer[i+4]-0x30; } else{ //无效字符 break; } if(i==5){ //密码修改完成 Serial.println("密码修改完成"); memcpy(init_pw,temp_pw,6); } } break; } case 0x30:{ //查看指纹 FP_busy = true; finger.getTemplateCount(); //查当前指纹模板的数量 Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates"); FP_busy = false; break; } case 0x31:{ //添加指纹 byte id; FP_busy = true; id = ble_rx_buffer[4] - 0x30; //注册指纹id getFingerprintEnroll(id); FP_busy = false; break; } case 0x32:{ //删除指纹 byte id; FP_busy = true; id = ble_rx_buffer[4] - 0x30; //删除指纹id Serial.print("Deleting ID #"); Serial.println(id); deleteFingerprint(id); FP_busy = false; break; } } } } }; /*配置蓝牙 * 参数:BLEName 蓝牙名字 * 返回值: 无 */ 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..."); } /*配置Wifi函数 * 输入参数: ssid: wifi名字,password: wifi密码 * 返回值:无 */ void configure_Wifi(char* ssid, char* password){ WiFi.mode(WIFI_STA); WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度 WiFi.begin(ssid, password); if(WiFi.status() != WL_CONNECTED){ delay(500); Serial.println("Connecting to WiFi fail.."); } else{ Serial.println("Connected to the WiFi network"); Serial.print("IP Address:"); Serial.println(WiFi.localIP()); } } /*TCP上传消息函数 * 输入值:type=value * value=1时,表示撬门 * value=2时, 表示门未关好 * value=3时,表示RFID开门 * value=4时,表示指纹开门 * value=5时,表示按键开门 * value=6时,表示蓝牙开门 * 返回值:true时,表示TCP连接成功 * false时,表示TCP连接失败 */ bool SendOnCloud(byte type){ char value = type+'0'; if(type>0 && type<=6){ //在消息协议范围内 if (client.connect(serverIP, serverPort)){ //尝试访问目标地址 Serial.print("访问成功:"); Serial.println(value); client.println(value);//向服务器发送数据 message_type =0; return 1; } else{ Serial.println("访问失败"); client.stop(); //关闭客户端 message_type =0; return 0; } } else{ //无效协议 //Serial.println("Invalid Message"); return 0; } } /*按键输入的匹配函数 * 参数:key为一次按键输入的值 */ bool compare_pw(char key){ static byte pw[20]; static byte keys_len = 0; bool pw_flag = false; //匹配密码的标志位 if(key){ //FP_busy = false;//唤醒指纹模块,可以开始匹配 Serial.println(key); play_voice(4); active_fp = 1; //Serial.println(active_fp); switch(key){ case '#':{ //确认键 if(keys_len == 6 && memcmp(pw,init_pw,6)==0){ //匹配成功,开锁 Serial.println("开门成功"); pw_flag = true; message_type = 5; } else{ Serial.println("密码错误"); } keys_len=0; //清零 break; } case '*':{ //回退键 if(keys_len >0) keys_len--; break; } default:{ //默认数字键0-9 pw[keys_len++]=key-'0'; if(keys_len>19){ Serial.println("OverSize"); keys_len=0; } break; } } } return pw_flag; } void printDec(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++){ //Serial.print(buffer[i] < 0x10 ? " 0" : ""); Serial.print(buffer[i]); Serial.print(" "); } } /* * RFID匹配函数 * 参数:card_num为卡片资料的总数 */ bool Match_Card(byte card_num){ bool foundTag = false; //是否找到记录中的标签,初始是false if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) { //寻找新卡 byte *id = rfid.uid.uidByte; // 取得卡片的UID byte idSize = rfid.uid.size; // 取得UID的长度 Serial.print("十进制UID:"); printDec(rfid.uid.uidByte, rfid.uid.size); Serial.println(); for (byte i = 0; i < card_num; i++) { if (memcmp(tags[i].uid, id, idSize) == 0) { // 比对阵列资料值 Serial.println(tags[i].name); //显示标签名字 foundTag = true; message_type=3; break; } if(i==card_num-1){ Serial.println("验证失败"); } } // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 rfid.PICC_HaltA(); // 停止读卡模块编码 rfid.PCD_StopCrypto1(); } return foundTag; } /*门磁中断函数 * 参数 open_flag:正常开门的标志位 */ void handleInterrupt() { delay(100); if (digitalRead(NormolClose)){ // 电平高,门开 detachInterrupt(digitalPinToInterrupt(NormolClose)); //屏蔽中断脚位 door_open_flag = 1; if(!lock_back_flag){ //门没在开锁时间,门磁变化,算撬门报警 alarm_flag = 1; } Serial.println("door open"); } } /*指纹模块配置函数 * configure_FP() */ void configure_FP(){ finger.begin(57600); 标签: 报pw传感器e905门磁传感器