硬件电路连接:
ESP32主站:数据线连PC
ESP32从站:
设备:
oled:
VCC-3.3V
GND-GND
SDA-D15
SCL-D4
红绿灯:
G-13
Y-12
R-14
软件:
ESP32主站:
//主机模式
#include <Arduino.h>
#include <BluetoothSerial.h>
//#include<dht.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SdFat.h>
#include <ArduinoJson.h>
#include<NewPing.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
#define Master 1 //主从机模式选择 1主机 0从机
String SlaveName="ESP32_SLAVE";
int RT;
int GT;
String input_string;
void Bluetooth_Event(esp_spp_cb_event_t event, esp_spp_cb_param_t *param); //蓝牙事件回调函数
uint8_t address[6]={0xB0,0xB2,0x1C,0xA8,0x10,0xD0}; //从机MAC地址 不同的蓝牙地址不同 需要自己修改
//B0B21CA810D0(com3)
void setup() {
Serial.begin(115200);
SerialBT.register_callback(Bluetooth_Event); //设置事件回调函数 连接 断开 发送 接收
Serial.flush();
delay(20);
if(Master)
{
SerialBT.begin("ESP32_MASTER",true); //开启蓝牙 名称为:"ESP32_MASTER" 主机
Serial.printf("Init Complete - Master\r\n");
SerialBT.connect(SlaveName);
}
else
{
SerialBT.begin("ESP32_SLAVE"); //开启蓝牙 名称为:"ESP32_SLAVE" 从机
Serial.printf("Init Complete - Slave\r\n");
SerialBT.connect(address);
}
}
void GetSerialStuff(String& input_string)
{
String temp_string = ""; // 声明变量 temp_string,用于临时存储串口输入的数据
while(Serial.available())
{ // 当串口有数据时,循环执行
temp_string += (char)Serial.read(); // 把读取的串口数据,逐个组合到inStr变量里
delay(2);
}
input_string = temp_string; // 把引用指针的变量赋值为 tempStr
}
void loop()
{
int len=0;
int tt=0;
int stt=0;
GetSerialStuff(input_string); // 获取串口的数据
len=input_string.length();
Serial.println(len);
Serial.println(input_string);
if(input_string != ""&&len==6)
{
tt = input_string.substring(0, 3).toInt(); // 从字符串中截取 秒 的数据并转换成int数据类型
stt=input_string.substring(4).toInt();//状态
Serial.println(stt);
}
if(stt==1)
{
RT=tt;
}
if(stt==2)
{
GT=tt;
}
Serial.println(tt);
Serial.println(stt);
bool ok1=SerialBT.write(stt); //状态
bool ok2=SerialBT.write(tt); //红绿灯设定时间
while(ok1!=1&&ok2!=1)
{
ok1=SerialBT.write(stt); //状态
ok2=SerialBT.write(tt);
}
if(ok1==1&&ok2==1){
Serial.println("sender finined!");
ok1=ok2=0;
}
delay(2000);
}
void Bluetooth_Event(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) //蓝牙事件回调函数
{
if(event == ESP_SPP_OPEN_EVT || event == ESP_SPP_SRV_OPEN_EVT) //蓝牙连接成功标志
{ //蓝牙主机和从机模式对应的标志不同,前面的是主机模式的,后面是从机模式
Serial.write("connection successful!\r\n");
}
else if(event == ESP_SPP_CLOSE_EVT) //蓝牙断开连接标志
{
Serial.write("disconnect successful!\r\n");
}
else if(event == ESP_SPP_DATA_IND_EVT) //数据接收标志
{
while(SerialBT.available())
{
Serial.write(SerialBT.read());
}
Serial.write("receive complete! \r\n");
}
else if(event == ESP_SPP_WRITE_EVT) //数据发送标志
{
Serial.write(" send complete! \r\n");
}
}
ESP32从站:
//#include<dht.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SdFat.h>
#include <ArduinoJson.h>
#include<NewPing.h>
#include <Arduino.h>
#include <BluetoothSerial.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int positionX = 0;
//#define OLED_RESET 4 //2560开发板
//Adafruit_SSD1306 display(OLED_RESET);
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
String input_string;
int tt;
int state;
char adress;
#define Master 0 //主从机模式选择 1主机 0从机
String MasterName="ESP32_MASTER";
void Bluetooth_Event(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
#define OLED_RESET -1 // Arduino uno 和ESP32以及ESP8266使用 Reset pin # (or -1 if sharing Arduino reset pin)uno开发板
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const uint8_t cn_xin [] PROGMEM =
{ 0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x7F, 0x78, 0x00, 0x40, 0x22, 0x40, 0x14, 0x40, 0xFF, 0x7E,
0x08, 0x48, 0x08, 0x48, 0x7F, 0x48, 0x08, 0x48, 0x2A, 0x48, 0x49, 0x48, 0x88, 0x88, 0x28, 0x88,
0x11, 0x08
};/*"新",0*/
const uint8_t cn_jiang [] PROGMEM =
{ 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFE, 0x08, 0x00, 0x09, 0xFC, 0xF9, 0x24, 0x81, 0xFC, 0x81, 0x24,
0xFB, 0xFE, 0x48, 0x00, 0x49, 0xFC, 0xE9, 0x24, 0x49, 0xFC, 0x69, 0x24, 0x89, 0xFC, 0x50, 0x00,
0x23, 0xFE
};/*"疆",1*/
const uint8_t cn_li [] PROGMEM =
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0xFD, 0x24, 0x11, 0x24, 0x11, 0xFC, 0x11, 0x24, 0x11, 0x24,
0x7D, 0xFC, 0x10, 0x20, 0x10, 0x20, 0x11, 0xFC, 0x10, 0x20, 0x1C, 0x20, 0xE0, 0x20, 0x43, 0xFE,
0x00, 0x00
};/*"理",2*/
const uint8_t cn_gong [] PROGMEM =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFE, 0x00, 0x00,
0x00, 0x00
};/*"工",3*/
const uint8_t cn_xue [] PROGMEM =
{ 0x00, 0x00, 0x22, 0x08, 0x11, 0x08, 0x11, 0x10, 0x00, 0x20, 0x7F, 0xFE, 0x40, 0x02, 0x80, 0x04,
0x1F, 0xE0, 0x00, 0x40, 0x01, 0x80, 0xFF, 0xFE, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05, 0x00,
0x02, 0x00
};/*"学",4*/
const uint8_t cn_yuan [] PROGMEM =
{ 0x00, 0x00, 0x00, 0x40, 0x78, 0x20, 0x4B, 0xFE, 0x52, 0x02, 0x54, 0x04, 0x61, 0xF8, 0x50, 0x00,
0x48, 0x00, 0x4B, 0xFE, 0x48, 0x90, 0x68, 0x90, 0x50, 0x90, 0x41, 0x12, 0x41, 0x12, 0x42, 0x0E,
0x44, 0x00
};/*"院",5*/
const int cn_allArray_LEN = 6;
const uint8_t* cn_allArray[6] = {
cn_xin, cn_jiang, cn_li, cn_gong, cn_xue, cn_yuan
};
#define G 11
#define Y 12
#define R 13
char ss[5];
char s[3];
String sss;
int RT=0;
int GT=0;
void setup()
{
Wire.begin(/*SDA*/15,/*SCL*/4);
// 初始化OLED并设置其IIC地址为 0x3C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// delay(5000);
Serial.begin(115200);
// put your setup code here, to run once:
//Serial1.begin(115200);
display.display();
// Clear the buffer
display.clearDisplay();
pinMode(G,OUTPUT);
pinMode(Y,OUTPUT);
pinMode(R,OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
SerialBT.register_callback(Bluetooth_Event); //设置事件回调函数 连接 断开 发送 接收
SerialBT.begin("ESP32_SLAVE"); //开启蓝牙 名称为:"ESP32_SLAVE" 从机
Serial.printf("Init Complete - Slave\r\n");
SerialBT.connect(MasterName);
}
void Bluetooth_Event(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) //蓝牙事件回调函数
{
if(event == ESP_SPP_OPEN_EVT || event == ESP_SPP_SRV_OPEN_EVT) //蓝牙连接成功标志
{ //蓝牙主机和从机模式对应的标志不同,前面的是主机模式的,后面是从机模式
Serial.write("connection successful!\r\n");
}
else if(event == ESP_SPP_CLOSE_EVT) //蓝牙断开连接标志
{
Serial.write("disconnect successful!\r\n");
}
else if(event == ESP_SPP_DATA_IND_EVT) //数据接收标志
{
int ok1=0;
int ok2=0;
int a=0,b=0;
while(SerialBT.available()&&a==0&&b==0)
{
a=SerialBT.read();
}
while(SerialBT.available()&&a!=0&&b==0){
b=SerialBT.read();}
Serial.println(a);
Serial.println(b);
if(a>b)
{
state=b;
tt=a;
ok1=1;
if(state==1)
{
RT=tt;
}
if(state==2)
{
GT=tt;
}
}
else{
tt=b;
state=a;
ok2=1;
if(state==1)
{
RT=tt;
}
if(state==2)
{
GT=tt;
}
}
if(ok1==1&&ok2==1)
Serial.write(" receive complete! \r\n");
}
else if(event == ESP_SPP_WRITE_EVT) //数据发送标志
{
Serial.write(" send complete! \r\n");
}
}
void loop() {
display.setTextSize(1); //设置字体大小
display.setTextColor(SSD1306_WHITE);//开像素点发光
// testdrawbitmap(cn_allArray[0],16,16);
for (int i = 0; i < 6; i++) { //新疆理工学院第一行
display.drawBitmap(i * 16, 0, cn_allArray[i], 16, 16, 1);
delay(1);
}
display.setTextColor(SSD1306_WHITE);//开像素点发光
// put your main code here, to run repeatedly:
digitalWrite(G,HIGH);
for(unsigned int i=GT;i>0;i--)
{
display.clearDisplay();
display.setTextSize(1); //设置字体大小
display.setTextColor(SSD1306_WHITE);//开像素点发光
// testdrawbitmap(cn_allArray[0],16,16);
for (int i = 0; i < 6; i++) { //新疆理工学院第一行
display.drawBitmap(i * 16, 0, cn_allArray[i], 16, 16, 1);
delay(1);
}
// delay(1000);
display.setCursor(0, 0);
display.setTextSize(2); //设置字体大小
display.println();
display.println();
display.print(i);
display.print('s');
display.display();
delay(1000);
}
digitalWrite(G,LOW);
digitalWrite(Y,HIGH);
for(unsigned int i=3;i>0;i--)
{
display.clearDisplay();
// delay(1000);
display.setTextSize(1); //设置字体大小
display.setTextColor(SSD1306_WHITE);//开像素点发光
// testdrawbitmap(cn_allArray[0],16,16);
for (int i = 0; i < 6; i++) { //新疆理工学院第一行
display.drawBitmap(i * 16, 0, cn_allArray[i], 16, 16, 1);
delay(1);
}
display.setCursor(0, 0);
display.setTextSize(2); //设置字体大小
display.println();
display.println();
display.print(i);
display.print('s');
display.display();
delay(1000);
}
Serial.println(tt);
digitalWrite(Y,LOW);
digitalWrite(R,HIGH);
for(unsigned int i=RT;i>0;i--)
{
display.clearDisplay();
// delay(1000);
display.setTextSize(1); //设置字体大小
display.setTextColor(SSD1306_WHITE);//开像素点发光
// testdrawbitmap(cn_allArray[0],16,16);
for (int i = 0; i < 6; i++) { //新疆理工学院第一行
display.drawBitmap(i * 16, 0, cn_allArray[i], 16, 16, 1);
delay(1);
}
// display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); //设置字体大小
display.println();
display.println();
display.print(i);
display.print('s');
display.display();
delay(1000);
}
digitalWrite(R,LOW);
digitalWrite(Y,HIGH);
for(unsigned int i=3;i>0;i--)
{
display.clearDisplay();
display.setTextSize(1); //设置字体大小
display.setTextColor(SSD1306_WHITE);//开像素点发光
// testdrawbitmap(cn_allArray[0],16,16);
for (int i = 0; i < 6; i++) { //新疆理工学院第一行
display.drawBitmap(i * 16, 0, cn_allArray[i], 16, 16, 1);
delay(1);
}
// display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); //设置字体大小
display.println();
display.println();
display.print(i);
display.print('s');
display.display();
delay(1000);
}
digitalWrite(Y,LOW);
display.display();
delay(20);
}
实验结果视频如下所示:
ESP32主站通过蓝牙设置ESP32从站红绿灯时间