// ESP32-C3 Emotion Bot (OLED 128x64, Button, Buzzer)
// Libraries required:
// Adafruit GFX, Adafruit SSD1306
// Install from Library Manager if needed.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
/////////////////////// USER PIN CONFIG ///////////////////////
// Change these if your devkit requires other pins
const int SDA_PIN = 8; // typical on many C3 boards (change if needed)
const int SCL_PIN = 9; // typical on many C3 boards (change if needed)
const int BUTTON_PIN = 5; // button -> other side to GND
const int BUZZER_PIN = 4; // passive buzzer + -> pin, - -> GND
////////////////////////////////////////////////////////////////
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
volatile unsigned long last_isr = 0;
volatile bool button_pressed = false;
unsigned long last_debounce = 0;
int currentEmotion = 0; // 0..8 (9 emotions)
const int EMOTIONS = 9;
// ----------------- PLACEHOLDERS FOR BITMAPS -----------------
// Replace these with your generated PROGMEM arrays (128x64 -> 1024 bytes each)
// Example names: emotion0_bitmap, emotion1_bitmap, ... emotion8_bitmap
extern const uint8_t emotion0_bitmap[] PROGMEM;
extern const uint8_t emotion1_bitmap[] PROGMEM;
extern const uint8_t emotion2_bitmap[] PROGMEM;
extern const uint8_t emotion3_bitmap[] PROGMEM;
extern const uint8_t emotion4_bitmap[] PROGMEM;
extern const uint8_t emotion5_bitmap[] PROGMEM;
extern const uint8_t emotion6_bitmap[] PROGMEM;
extern const uint8_t emotion7_bitmap[] PROGMEM;
extern const uint8_t emotion8_bitmap[] PROGMEM;
// If you don't have bitmaps yet, we will draw simple text placeholders.
// ---------------------------------------------------------------
void IRAM_ATTR buttonISR(){
unsigned long t = millis();
if (t - last_isr > 200) { // basic hardware debounce (200 ms)
button_pressed = true;
last_isr = t;
}
}
void playToneForEmotion(int e) {
// passive buzzer short melodies per emotion
switch (e) {
case 0: // NORMAL
tone(BUZZER_PIN, 900, 80);
break;
case 1: // HAPPY
tone(BUZZER_PIN, 1200, 120);
delay(130);
tone(BUZZER_PIN, 1500, 100);
break;
case 2: // SURPRISED
tone(BUZZER_PIN, 2000, 120);
break;
case 3: // ANGRY
tone(BUZZER_PIN, 300, 200);
break;
case 4: // SAD
tone(BUZZER_PIN, 400, 180);
break;
case 5: // EXCITED
tone(BUZZER_PIN, 1500, 100);
delay(80);
tone(BUZZER_PIN, 1800, 100);
break;
case 6: // CONFUSED
tone(BUZZER_PIN, 700, 120);
break;
case 7: // BLINK (soft)
tone(BUZZER_PIN, 1000, 60);
break;
case 8: // ANGRY (strong)
tone(BUZZER_PIN, 300, 300);
break;
}
}
void drawEmotionBitmap(int e) {
display.clearDisplay();
// If you created bitmaps and included them, uncomment this switch block and comment placeholders
switch (e) {
case 0: display.drawBitmap(0,0, emotion0_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 1: display.drawBitmap(0,0, emotion1_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 2: display.drawBitmap(0,0, emotion2_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 3: display.drawBitmap(0,0, emotion3_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 4: display.drawBitmap(0,0, emotion4_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 5: display.drawBitmap(0,0, emotion5_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 6: display.drawBitmap(0,0, emotion6_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 7: display.drawBitmap(0,0, emotion7_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
case 8: display.drawBitmap(0,0, emotion8_bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); break;
default:
// placeholder simple drawing if bitmaps are absent
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(6, 20);
if (e == 0) display.println("NORMAL :)");
else if (e==1) display.println("HAPPY :D");
else if (e==2) display.println("SURPRISED!");
else if (e==3) display.println("ANGRY >:(");
else if (e==4) display.println("SAD :(");
else if (e==5) display.println("EXCITED!!");
else if (e==6) display.println("CONFUSED?");
else if (e==7) display.println("BLINK");
else display.println("ANGRY2");
}
display.display();
}
void setup() {
Serial.begin(115200);
// Initialize I2C explicitly on chosen pins (important for ESP32-C3)
Wire.begin(SDA_PIN, SCL_PIN);
pinMode(BUTTON_PIN, INPUT_PULLUP); // button -> GND
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
// attach interrupt on falling edge (button pressed to GND)
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonISR, FALLING);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 failed");
for (;;);
}
display.clearDisplay();
drawEmotionBitmap(currentEmotion);
}
void loop() {
if (button_pressed) {
// simple software debounce: wait for switch release
delay(50);
if (digitalRead(BUTTON_PIN) == LOW) {
// wait until button released
while (digitalRead(BUTTON_PIN) == LOW) delay(10);
// cycle emotion
currentEmotion++;
if (currentEmotion >= EMOTIONS) currentEmotion = 0;
drawEmotionBitmap(currentEmotion);
playToneForEmotion(currentEmotion);
}
button_pressed = false;
}
// If you want an idle blink animation for specific emotion, you can add it here.
// Example: if currentEmotion==0 show alternating frames.
}
Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1