/**
* Wokwi 模拟:ESP32 按键 + OLED + LED(模拟震动)
* 功能:按键控制LED闪烁,模拟发送/接收消息,OLED显示状态
* 连接:
* - OLED (I2C): SDA->GPIO21, SCL->GPIO22
* - 按键: 上(GPIO32), 下(GPIO33), 左(GPIO25), 右(GPIO26), 确认(GPIO34) 均接GND
* - LED: 阳极(GPIO13) 阴极(GND)
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
// 引脚定义
#define KEY_UP 32
#define KEY_DOWN 33
#define KEY_LEFT 25
#define KEY_RIGHT 26
#define KEY_OK 34
#define LED_PIN 13
// OLED 定义
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// 状态变量
String currentMessage = "Hello!"; // 当前显示的消息
bool newMessageFlag = false; // 新消息标志
unsigned long lastBlink = 0;
bool ledState = false;
void setup() {
Serial.begin(115200);
Serial.println("Starting...");
// 初始化按键 (启用内部上拉)
pinMode(KEY_UP, INPUT_PULLUP);
pinMode(KEY_DOWN, INPUT_PULLUP);
pinMode(KEY_LEFT, INPUT_PULLUP);
pinMode(KEY_RIGHT, INPUT_PULLUP);
pinMode(KEY_OK, INPUT_PULLUP);
// 初始化LED
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// 初始化I2C和OLED
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("OLED 初始化失败");
while (1);
}
// 连接模拟WiFi (Wokwi专用)
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println("\nWiFi 已连接 (模拟)");
// 显示初始界面
updateDisplay("Ready", false);
}
void loop() {
// 1. 按键扫描并触发LED模拟
if (digitalRead(KEY_OK) == LOW) {
delay(50); // 简单消抖
if (digitalRead(KEY_OK) == LOW) {
Serial.println("OK Pressed - 模拟发送消息");
// 触发LED闪烁 (模拟发送震动)
triggerBlink(100);
// 在屏幕上显示"已发送"
updateDisplay("已发送: " + currentMessage, false);
while (digitalRead(KEY_OK) == LOW); // 等待按键释放
}
}
// 2. 模拟接收新消息 (每5秒自动一次)
static unsigned long lastMsgTime = 0;
if (millis() - lastMsgTime > 5000) {
lastMsgTime = millis();
// 模拟收到一条新消息
currentMessage = "Msg " + String(millis() % 1000);
newMessageFlag = true;
Serial.println("模拟收到新消息: " + currentMessage);
// 触发LED闪烁 (模拟接收震动)
triggerBlink(300);
// 更新屏幕显示
updateDisplay("收到: " + currentMessage, true);
}
// 3. LED闪烁任务
if (ledState && millis() > lastBlink) {
digitalWrite(LED_PIN, LOW);
ledState = false;
}
delay(10);
}
// 触发LED闪烁函数
void triggerBlink(int durationMs) {
digitalWrite(LED_PIN, HIGH);
lastBlink = millis() + durationMs;
ledState = true;
}
// 更新OLED显示
void updateDisplay(String line1, bool isNew) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("=== 模拟器 ===");
display.drawFastHLine(0, 10, 128, SSD1306_WHITE);
display.setCursor(0, 20);
display.println(line1);
if (isNew) {
display.setCursor(0, 40);
display.println("[新消息]");
}
display.display();
}Loading
grove-oled-sh1107
grove-oled-sh1107