免责声明!!!!
本程序仅供技术交流参考学习使用, 任何人不得从事非法内容, 若因使用者使用不当或私自更改造成的任何后果, 作者不承担任何责任!!!
简介:
1: 代码支持多个蓝牙RAW数据, 每次重启都会循环切换至下一个RAW信号
2: 支持自定义蓝牙设备名称与MAC地址
正文开始
所需要的库文件,没有的请查漏补缺
注意哈, 部分库文件版本不一样, 可能会导致程序卡在<读取下标>这一步,如出现卡死的情况, 请把画圈内的注释文件和前一句调换注释, 程序成功运行后再调换回来重新烧录即可, 若只有一个RAW数据, 也可直赋值,不用读取
有多个raw数据则依次给数组赋值即可
#include "BLEDevice.h"
#include "BLEUtils.h"
#include "esp_sleep.h"
#include "SPIFFS.h"//文件系统
#include <Arduino.h>
#include <Arduino_JSON.h>
BLEAdvertising *pAdvertising;
String id_f = "/Ble_pz_xb.txt"; //id下标变量存储地址
String ble_peiz_f = "/Ble_pz_f.ble"; //ble文件地址
int ts = 0; //调试模式
JSONVar ble_Array ;
String data = "";
String bleMac_S = "";
String ble_name = "";
String ble_xb = "0";
int cw = 0; //记录错误文件
int data_arr_longth;
uint8_t bleRaw[31], bleRaw32[13], bleMac[6];
boolean rawMoreThan31 = false;
void arr_to1() {
JSONVar json_arr;
json_arr[0]["BLE_Name"] = "blename2";//设备名称
json_arr[0]["MAC"] = "FF:FF:FF:FF:FF:FF";//mac地址
json_arr[0["BLE_V"] = "0x0............";//raw数据
//json_arr[1]["BLE_Name"] = "blename2";//设备名称
//json_arr[1]["MAC"] = "FF:FF:FF:FF:FF:FF";//mac地址
//json_arr[1]["BLE_V"] = "0x0............";//raw数据
String jsonString = JSON.stringify(json_arr);
// Serial.println(jsonString);
Serial.println();
Svd_peiz(ble_peiz_f, jsonString); //保存
}
//文件系统
String Svd_peiz(String f, String a) { //保存ble配置文件
File file = SPIFFS.open(f, FILE_WRITE);
file.println(a);
file.close();
Serial.println("保存: " + a);
return !file ? "ok" : "no";
}
//读取下标文件
String read_txt(String a) {
String txt = "";
File file = SPIFFS.open(a, FILE_READ); //读取文件
if (!file || file.isDirectory()) {
Serial.println("读取失败,无数据: " + a);
file.close();
return "SPIFFS_error";
} else {
Serial.println("开始读取SPIFFS: " + a);
while (file.available()) {
txt += char(file.read());
} file.close();
Serial.println(txt);
txt.trim();
}
return txt;
}
String q0x(String a) {
if (String(a.substring(0, 2)) == "0x") {
String b = String(a.substring(2, a.length()));
return b;
} else return a;
}
void arr_to() { //字符16进制 --> 16进制数组 String_16 --> uint_8
int zt_arr = 0;
int xb = ble_xb.toInt();
xb = xb % data_arr_longth; //防止数据修改后出错
if (ble_Array[xb].hasOwnProperty("BLE_V")) {
data = q0x(String((const char*)ble_Array[xb]["BLE_V"]));
}
if (ble_Array[xb].hasOwnProperty("MAC")) {
bleMac_S = String((const char*)ble_Array[xb]["MAC"]);
}
if (ble_Array[xb].hasOwnProperty("BLE_Name")) {
ble_name = String((const char*)ble_Array[xb]["BLE_Name"]);
}
if (data != "" && data.length() % 2 == 0) {
Serial.println();
zt_arr = 1;
ble_xb = String((xb + 1) % data_arr_longth);
JSONVar json_peiz_xb;
json_peiz_xb["ble_xb"] = ble_xb;
String att = JSON.stringify(json_peiz_xb);
Svd_peiz(id_f, att); //保存下一次id
Serial.println("当前文件下标: " + String(xb));
Serial.println(data);
bleMac_S.trim();
if (bleMac_S.length() > 0) {
String bleMac_S_t = "";
for (int i = 0; i < bleMac_S.length(); i++) {
if (bleMac_S[i] != ' ') {
if (bleMac_S[i] != ':') {
bleMac_S_t += bleMac_S[i];
}
}
}
if (bleMac_S_t.length() == 12) {
zt_arr += 2;
String abc = "";
for (int i = 0; i < 12; i++) {
abc += bleMac_S_t[i];
if (i % 2 == 1 and i < 11) {
abc += ":";
}
}
Serial.println(abc);
byte mac_ble[6];
string_byte(mac_ble, bleMac_S_t.c_str());
for (int i = 0; i < 6; i++) {
bleMac[i] = (uint8_t)mac_ble[i];
}
} else Serial.println("MAC地址错误,将使用默认地址");
}
int dat = data.length() / 2;
byte bytearr[dat] = {0};
data.trim();
string_byte(bytearr, data.c_str());
uint8_t arr[dat];
for (int i = 0; i < dat; i++) {
arr[i] = (uint8_t)bytearr[i];
}
if (dat > 31) {
rawMoreThan31 = true;
for (int i = 0; i < 31; i++) {
bleRaw[i] = arr[i];
}
for (int i = 31; i < dat; i++) {
bleRaw32[i - 31] = arr[i];
}
} else rawMoreThan31 = false;
ble_name = ble_name.length() > 0 ? ble_name : "";
Serial.println(ble_name);
}
if (ts == 0)ble_go(zt_arr);
}
void ble_go(int a) {
if (a > 0) {
if (a > 2) {
if (UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR) {
bleMac[5] -= 2;
} else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
bleMac[5] -= 1;
}
esp_base_mac_addr_set(bleMac);
}
BLEDevice::init(ble_name.c_str());
pAdvertising = BLEDevice::getAdvertising();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
pAdvertising->setScanResponseData(oScanResponseData);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
pAdvertising->setAdvertisementData(oAdvertisementData);
esp_err_t errRc = ::esp_ble_gap_config_adv_data_raw(bleRaw, 31);
if (errRc != ESP_OK) {
Serial.printf("esp_ble_gap_config_adv_data_raw: %d\n", errRc);
}
// 超过31
if (rawMoreThan31) {
errRc = ::esp_ble_gap_config_scan_rsp_data_raw(bleRaw32, sizeof(bleRaw32) / sizeof(bleRaw32[0]));
if (errRc != ESP_OK) {
Serial.printf("esp_ble_gap_config_scan_rsp_data_raw: %d\n", errRc);
}
}
pAdvertising->start();
}
else {
cw++;
if (cw <= data_arr_longth) {
ble_xb = String((ble_xb.toInt() + 1) % data_arr_longth);
arr_to();
} else Serial.println("Raw数据不完整");
}
}
void string_byte(byte *bytearr, const char *hSt)
{
bool hst_len = strlen(hSt) & 1;
byte by1 = 0;
byte byte_xb = 0;
for (byte char_xb = 0; char_xb < strlen(hSt); char_xb++)
{
bool char_xb_f = char_xb & 1;
if (hst_len)
{
if (char_xb_f)
{
by1 = char_byte(hSt[char_xb]) << 4;
}
else
{
by1 |= char_byte(hSt[char_xb]);
bytearr[byte_xb++] = by1;
by1 = 0;
}
}
else
{
if (!char_xb_f)
{
by1 = char_byte(hSt[char_xb]) << 4;
}
else
{
by1 |= char_byte(hSt[char_xb]);
bytearr[byte_xb++] = by1;
by1 = 0;
}
}
}
}
byte char_byte(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0;
}
void setup() {
Serial.begin(115200);
if (!SPIFFS.begin(true)) {
Serial.println("文件系统挂载失败");
return;
} else Serial.println("文件系统OK!");
arr_to1();//临时数据
String ble_txt = read_txt(ble_peiz_f); //读取ble文件
ble_Array = JSON.parse(ble_txt);
data_arr_longth = ble_Array.length();
// String txt = read_txt(id_f); //有多个raw数据启用这一段,若卡死在读取 下标,则先启用下面那一段烧录一次
String txt = "{'ble_xb':'0'}"; //若只有一个raw数据且卡死在读取下标这一步,则启用这一段
JSONVar myObject = JSON.parse(txt); //数据为const char* 格式
if (myObject.hasOwnProperty("ble_xb")) {
const char* ls = myObject["ble_xb"];
ble_xb = String(ls);
}
Serial.println("缓存OK!");
arr_to();
}
void loop() {
delay(1000);
// 1分钟后关机
if (millis() > 60000) {
Serial.println("已关机");
esp_deep_sleep_start();//深度睡眠
}
}