Last post show my exercise of "ESP-32S as Bluetooth classic Server, bi-direction communication with Raspberry Pi/Python". Here is the ESP32 implementation for the Client side, to connect to the ESP32 server in last post.
NodeMCU ESP-32S act as a server (in last post):
It echo what received from bluetooth back to sender, and display on SPI ST7735 display.
ESP32-DevKitC-V4 as client (this post):
Connect to server, forward data from serial, to Bluetooth. Display data from Bluetooth on I2C SSD1306 OLED display.
The code start from ESP32 example of SerialToSerialBTM. But I found that the code SerialBT.connect() always return "true", and prompt "Connected Succesfully!", no matter the device name and MAC address, even no server exist.
To solve it, I implement my bluetooth callback function to double check if ESP_SPP_OPEN_EVT raised. I don't know is it a long time solution, anyway it work in this exercise.
SPPClient_ESP32_ssd1306_20201231b.ino/*
* SPP Client on ESP32
* Display on SSD1306
*/
#include "ssd1306.h"
#include "ssd1306_console.h"
#include "BluetoothSerial.h"
Ssd1306Console console;
BluetoothSerial SerialBT;
String ServerMACadd = "3C:71:BF:0D:DD:6A";
uint8_t ServerMAC[6] = {0x3C, 0x71, 0xBF, 0x0D, 0xDD, 0x6A};
String ServerName = "ESP32_SPP";
char *pin = "1234"; //<- standard pin would be provided by default
bool connected;
bool isSppOpened = false;
/*
.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/
BluetoothSerial/src/BluetoothSerial.cpp
*/
void btCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){
switch (event)
{
case ESP_SPP_INIT_EVT:
Serial.println("ESP_SPP_INIT_EVT");
break;
case ESP_SPP_SRV_OPEN_EVT://Server connection open
Serial.println("ESP_SPP_SRV_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT://Client connection closed
Serial.println("ESP_SPP_CLOSE_EVT");
isSppOpened = false;
break;
case ESP_SPP_CONG_EVT://connection congestion status changed
Serial.println("ESP_SPP_CONG_EVT");
break;
case ESP_SPP_WRITE_EVT://write operation completed
Serial.println("ESP_SPP_WRITE_EVT");
break;
case ESP_SPP_DATA_IND_EVT://connection received data
Serial.println("ESP_SPP_DATA_IND_EVT");
break;
case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete
Serial.println("ESP_SPP_DISCOVERY_COMP_EVT");
break;
case ESP_SPP_OPEN_EVT://Client connection open
Serial.println("ESP_SPP_OPEN_EVT");
isSppOpened = true;
break;
case ESP_SPP_START_EVT://server started
Serial.println("ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT://client initiated a connection
Serial.println("ESP_SPP_CL_INIT_EVT");
break;
default:
Serial.println("unknown event!");
break;
}
}
static void startupScreen()
{
ssd1306_setFixedFont(ssd1306xled_font6x8);
ssd1306_clearScreen();
ssd1306_printFixed(0, 0, "arduiino-er.blogspot.com", STYLE_BOLD);
ssd1306_printFixed(0, 24, "ESP32 SPP Client", STYLE_NORMAL);
}
void setup()
{
Serial.begin(115200);
Serial.println("\n------ begin ----------------\n");
ssd1306_128x64_i2c_init();
ssd1306_clearScreen();
startupScreen();
delay(500);
Serial.println("- to connect -");
ssd1306_printFixed(0, 32, "...to connect", STYLE_NORMAL);
SerialBT.begin("ESP32_Client", true);
SerialBT.register_callback(btCallback);
//connected = SerialBT.connect(ServerName);
connected = SerialBT.connect(ServerMAC);
/*
* In my trial,
* SerialBT.connect() always return true, even no server exist.
* To solve it, I implemented bluetooth event callback function,
* double varify if ESP_SPP_OPEN_EVT raised.
*/
if(connected) {
Serial.println("SerialBT.connect() == true");
} else {
Serial.println("Failed to connect! Reset to re-try");
Serial.println("SerialBT.connect() == false");
ssd1306_printFixed(0, 32,
"Failed to connect! Reset to re-try", STYLE_NORMAL);
while(true){
}
}
//may be there are some delay to call callback function,
//delay before check
delay(500);
if(isSppOpened == false){
Serial.println("isSppOpened == false");
Serial.println("Reset to re-try");
ssd1306_printFixed(0, 32,
"SPP_OPEN not raised! Reset to re-try", STYLE_NORMAL);
while(true){
}
}
Serial.println("isSppOpened == true");
Serial.println("CONNECTED");
ssd1306_clearScreen();
ssd1306_setFixedFont(ssd1306xled_font6x8);
console.println("CONNECTED:");
}
void loop()
{
if(!isSppOpened){
Serial.println("isSppOpened == false : DISCONNECTED");
Serial.println("Reset to re-connect");
console.println("DISCONNECTED");
console.println("Reset to re-connect");
while(true){
}
}
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
char c = SerialBT.read();
//Serial.write(c);
console.print(c);
}
delay(20);
}
For the setup of SPI ST7735 IPS used on server side, refer to the post "ESP32 display with 0.96" 80x160 SPI ST7735 IPS Display, using TFT_eSPI lib".
For the setup of I2C SSD1306 OLED used on client side, refer to the post "I2C SSD1306 OLED@ESP32 (ESP32-DevKitC-V4), using SSD1306 lib".