有时您需要通过Wi-Fi远程连接到ESP32,但您不知道IP地址,或者ESP32每次都用新的IP地址重新连接。
查找无法访问的板的IP地址的最简单方法是通过蓝牙串行将其传输到手机。但是蓝牙和Wi-Fi在ESP32上并不能很好地共存,因为它们共享同一无线电系统。一旦开始将Wi-Fi连接用于数据,就需要关闭蓝牙连接。
在本教程和示例代码中,您可以看到如何使用Bluetooth串行读取IP地址,然后关闭连接,以便只有Wi-Fi使用无线电。
该演示应用程序使用基于ESP32的摄像头板,但可适用于需要通过Wi-Fi访问ESP32的其他项目。
本教程分为三个部分-上传草图,将手机与ESP32配对以及使用串行蓝牙应用程序进行连接。
从此处将代码复制到https://github.com/robotzero1/esp32-bluewifi到新的Sketch中,并将其上传到您的ESP32开发板。如果您使用的是ESP32-CAM,请记住断开引脚0的连接,然后按Reset键。
打开串行监视器,以便您可以检查以下步骤的进度。
我有Android 9,但其他手机应该非常相似。
从Play商店安装串行蓝牙终端应用程序– https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&hl=zh-CN
如果这是ESP32首次连接到该Wi-Fi网络或密码已更改,则您将看到以下输出。
ESP32连接到Wi-Fi网络时,将显示ESP32 IP地址且蓝牙已断开连接:
如果ESP32已经具有正确的连接凭证,则仅显示ESP32的IP地址:
下面解释了代码的一些重要部分:
该代码使用“枚举状态机”。可以将枚举视为具有固定数量的值的变量,例如SCAN_START,SCAN_COMPLETE,SSID_ENTERED,PASS_ENTERED,LOGIN_FAILED
这些值在主循环的switch语句中使用。根据当前枚举值设置函数运行或变量值:
case SCAN_START:
SerialBT.println("Scanning Wi-Fi networks");
Serial.println("Scanning Wi-Fi networks");
scan_wifi_networks();
SerialBT.println("Please enter the number for your Wi-Fi");
wifi_stage = SCAN_COMPLETE;
break;
case SSID_ENTERED:
SerialBT.println("Please enter your Wi-Fi password");
Serial.println("Please enter your Wi-Fi password");
wifi_stage = WAIT_PASS;
break;
case PASS_ENTERED:
SerialBT.println("Please wait for Wi-Fi connection...");
Serial.println("Please wait for Wi_Fi connection...");
wifi_stage = WAIT_CONNECT;
preferences.putString("pref_ssid", client_wifi_ssid);
preferences.putString("pref_pass", client_wifi_password);
if (init_wifi()) { // Connected to WiFi
connected_string = "ESP32 IP: ";
connected_string = connected_string + WiFi.localIP().toString();
SerialBT.println(connected_string);
Serial.println(connected_string);
bluetooth_disconnect = true;
} else { // try again
wifi_stage = LOGIN_FAILED;
}
break;
case LOGIN_FAILED:
SerialBT.println("Wi-Fi connection failed");
Serial.println("Wi-Fi connection failed");
delay(2000);
wifi_stage = SCAN_START;
break;
根据Wi-Fi是否已连接,Sketch使用两个蓝牙回调:
if (!init_wifi()) { // Connect to Wi-Fi fails
SerialBT.register_callback(callback);
} else {
SerialBT.register_callback(callback_show_ip);
}
如果ESP32无法连接到Wi-Fi,则初始化第一个回调。这侦听发送到ESP32的蓝牙数据。根据数据类型和枚举的当前值,设置各种变量并运行函数:
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
if (event == ESP_SPP_SRV_OPEN_EVT) {
wifi_stage = SCAN_START;
}
if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == SCAN_COMPLETE) { // data from phone is SSID
int client_wifi_ssid_id = SerialBT.readString().toInt();
client_wifi_ssid = ssids_array[client_wifi_ssid_id];
wifi_stage = SSID_ENTERED;
}
if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == WAIT_PASS) { // data from phone is password
client_wifi_password = SerialBT.readString();
client_wifi_password.trim();
wifi_stage = PASS_ENTERED;
}
}
或者,如果ESP32已成功连接到Wi-Fi,则初始化第二个回调并等待来自蓝牙连接的输入:
void callback_show_ip(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
if (event == ESP_SPP_SRV_OPEN_EVT) {
SerialBT.print("ESP32 IP: ");
SerialBT.println(WiFi.localIP());
bluetooth_disconnect = true;
}
}
代码中要注意的最后重要一点是,一旦用户知道了Wi-Fi IP地址,则应该关闭蓝牙。当IP地址已显示在手机上或用户在浏览器中连接到IP时,就会发生这种情况。上面的代码中显示了一个示例。通过网络套接字连接摄像机时,下面显示了另一个:
if (socket_server.poll()) {
disconnect_bluetooth();
...
}
视频示范
下面显示了通过蓝牙连接和设置Wi-Fi访问详细信息的演示。
引用: Jacktang 发表于 2021-5-22 21:04 多谢分享 文中的几个图应该是看不到
应该是图片的服务器被屏蔽了,正常网络原帖也无法查看,我编辑了一下,下载到本地了。
在“ESP32开发板IOT蓝牙WIFI米思齐”上做一个小项目:用这个开发板截获原设备控制板的输入信号,同时将输入信号转发至原控制板输入端和通过wif转发至手机APP端程序(这样通过手机可以获知原设备的输入);同时,手机APP可以直接发送控制信号到原设备的信号输入端,实现设备控制。可以做的话请联系!