#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
const int EYE_Y = 20;
const int EYE_W = 16;
const int GAP = 16;
const unsigned long BLINK_PERIOD_MS = 2000;
const unsigned long CLOSED_MS = 120;
const unsigned long MOVE_MS = 70;
const unsigned long REACTION_MS = 1000;
const unsigned long JUMP_MS = 120;
const byte BUTTON_PIN = 2;
const unsigned long DEBOUNCE_MS = 30;
unsigned long lastMove = 0;
unsigned long changedAt = 0;
unsigned long reactionAt = 0;
int gaze = 0;
int direction = 1;
bool rawButton = HIGH;
bool stableButton = HIGH;
bool reacting = false;
void face(bool closed, int offset, int jump, bool smile) {
display.clearDisplay();
int left = 64 - GAP / 2 - EYE_W + offset;
int right = 64 + GAP / 2 + offset;
int y = EYE_Y - jump;
int height = closed ? 2 : 16;
display.fillRoundRect(left, y, EYE_W, height, closed ? 0 : 4, SSD1306_WHITE);
display.fillRoundRect(right, y, EYE_W, height, closed ? 0 : 4, SSD1306_WHITE);
if (smile) {
display.drawLine(54, 43 - jump, 59, 48 - jump, SSD1306_WHITE);
display.drawLine(59, 48 - jump, 69, 48 - jump, SSD1306_WHITE);
display.drawLine(69, 48 - jump, 74, 43 - jump, SSD1306_WHITE);
}
display.display();
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED init failed"));
while (true) { delay(100); }
}
Serial.println(F("OLED ready"));
}
void loop() {
unsigned long now = millis();
bool reading = digitalRead(BUTTON_PIN);
if (reading != rawButton) {
rawButton = reading;
changedAt = now;
}
if (now - changedAt >= DEBOUNCE_MS && stableButton != rawButton) {
stableButton = rawButton;
if (stableButton == LOW) {
reacting = true;
reactionAt = now;
Serial.println(F("Reaction"));
}
}
if (reacting && now - reactionAt >= REACTION_MS) {
reacting = false;
}
int jump = reacting && ((now - reactionAt) / JUMP_MS) % 2 ? 6 : 0;
face(reacting || now % BLINK_PERIOD_MS < CLOSED_MS, 0, jump, reacting);
}
Loading
ssd1306
ssd1306
Uno: USB 5V (simulation)