這個專案一開始很吸引人的部份是使用了FluxGarage RoboEyes (https://github.com/FluxGarage/RoboEyes)有支援使用1.3吋的Oled,所以我就換了它
#include <WiFi.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <Wire.h>
#include <Adafruit_SH110X.h> //#include <Adafruit_SSD1306.h>
#include <FluxGarage_RoboEyes.h>
/* ================= OLED ================= */
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_SDA 8
#define OLED_SCL 9
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RoboEyes<Adafruit_SH1106G> roboEyes(display); // create RoboEyes instance
#include <WiFiManager.h>
#include <ESPmDNS.h>
// === WiFiManager 設定 ===
WiFiManager wm;
if (!wm.autoConnect("MoCoffee_AP")) {
Serial.println("Failed to connect and hit timeout");
delay(3000);
ESP.restart();
}
Serial.println("WiFi connected!");
Serial.print("IP Address: "); Serial.println(WiFi.localIP());
// === mDNS 設定 ===
if (MDNS.begin("MoCoffee")) {
Serial.println("mDNS responder started. Connect to http://MoCoffee.local");
}
// 初始化 LEDC (ESP32 Core 3.x.x 新版寫法)
ledcAttach(LF, PWM_FREQ, PWM_RES);
ledcAttach(LB, PWM_FREQ, PWM_RES);
ledcAttach(RF, PWM_FREQ, PWM_RES);
ledcAttach(RB, PWM_FREQ, PWM_RES);
#include <Wire.h>
/* ================= 馬達腳位設定 ================= */
#define LF 1
#define LB 0
#define RF 3
#define RB 2
/* ================= LEDC PWM 設定 ================= */
#define PWM_FREQ 5000
#define PWM_RES 8 // 8-bit 解析度 (0-255)
int manualSpeed = 255; // 手動控制預設速度
/* ================= 馬達控制邏輯(ESP32 Core 3.x.x新版寫法) ================= */
void driveMotor(int lf, int lb, int rf, int rb) {
ledcWrite(LF, lf);
ledcWrite(LB, lb);
ledcWrite(RF, rf);
ledcWrite(RB, rb);
}
#include <DFRobotDFPlayerMini.h>
/* ================= DFPlayer 音樂模組設定 ================= */
#define DF_RX_PIN 20 // ESP32-C3 接收 (接 DFPlayer TX)
#define DF_TX_PIN 21 // ESP32-C3 發送 (接 DFPlayer RX)
HardwareSerial dfSerial(1); // 使用 UART1
DFRobotDFPlayerMini myDFPlayer;
int currentVolume = 15; // 預設音量 (0-30)
// === DFPlayer 初始化 ===
dfSerial.begin(9600, SERIAL_8N1, DF_RX_PIN, DF_TX_PIN);
Serial.println("Initializing DFPlayer...");
// 加上判斷,就算沒接上 DFPlayer 也不會讓程式卡死
if (!myDFPlayer.begin(dfSerial, true, false)) {
Serial.println("DFPlayer Error: Check connection or SD card");
} else {
Serial.println("DFPlayer Ready!");
myDFPlayer.volume(currentVolume); // 設定音量
myDFPlayer.playFolder(1, 1);// 播放開機啟動音效(01/001.mp3)
}
// === 音樂控制路由 ===
server.on("/m_play", [](){ myDFPlayer.start(); server.send(200); });
server.on("/m_pause", [](){ myDFPlayer.pause(); server.send(200); });
server.on("/m_next", [](){ myDFPlayer.next(); server.send(200); });
server.on("/m_prev", [](){ myDFPlayer.previous(); server.send(200); });
/* ================= TTP223 設定 ================= */
#define TOUCH_PIN 7 // TTP223 SIG 接在 GPIO 7
pinMode(TOUCH_PIN, INPUT); // TTP223 預設輸出高電平為觸發 (A、B 跳線未焊時)
// --- TTP223 觸控邏輯 ---
bool currentTouch = digitalRead(TOUCH_PIN);
if (currentTouch == HIGH) {
myDFPlayer.playMp3Folder(1);
roboEyes.setMood(HAPPY);
}