#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// --- Configuration ---
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* apiKey = "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"; // Get at console.groq.com
// --- Animation Functions ---
void drawEyes(bool open, int xOff, int yOff, int eyeHeight = 25) {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
if (open) {
display.fillRoundRect(35 + xOff, 20 + yOff, 20, eyeHeight, 8, SSD1306_WHITE);
display.fillRoundRect(75 + xOff, 20 + yOff, 20, eyeHeight, 8, SSD1306_WHITE);
} else {
display.fillRect(35 + xOff, 32 + yOff, 20, 4, SSD1306_WHITE);
display.fillRect(75 + xOff, 32 + yOff, 20, 4, SSD1306_WHITE);
}
display.display();
}
void talkingAnimation(String text) {
Serial.print("AI Robot: ");
for (int i = 0; i < text.length(); i++) {
Serial.print(text[i]);
// Eyes bounce and height changes to simulate "speech"
int bounce = (i % 2 == 0) ? 2 : -2;
int h = (i % 3 == 0) ? 18 : 26;
drawEyes(true, 0, bounce, h);
delay(30);
}
Serial.println("\n------------------------------------");
drawEyes(true, 0, 0);
}
// --- AI Logic ---
void askFreeAI(String prompt) {
// 1. Print the question to Serial
Serial.println("\n------------------------------------");
Serial.print("You: ");
Serial.println(prompt);
Serial.println("Status: Thinking...");
drawEyes(false, 0, 0); // Close eyes while thinking
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
if (http.begin(client, "https://api.groq.com/openai/v1/chat/completions")) {
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " + String(apiKey));
DynamicJsonDocument doc(2048);
doc["model"] = "llama-3.1-8b-instant";
JsonArray messages = doc.createNestedArray("messages");
JsonObject systemMsg = messages.createNestedObject();
systemMsg["role"] = "system";
systemMsg["content"] = "You are EMO, a cool, helpful robot. Give short, witty answers.";
JsonObject userMsg = messages.createNestedObject();
userMsg["role"] = "user";
userMsg["content"] = prompt;
String jsonPayload;
serializeJson(doc, jsonPayload);
int httpResponseCode = http.POST(jsonPayload);
if (httpResponseCode == 200) {
String response = http.getString();
DynamicJsonDocument filter(4096);
deserializeJson(filter, response);
String answer = filter["choices"][0]["message"]["content"];
talkingAnimation(answer);
} else {
Serial.print("Error! Code: ");
Serial.println(httpResponseCode);
Serial.println("Details: " + http.getString());
drawEyes(false, 0, 5);
}
http.end();
}
}
// --- Core Logic ---
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
display.clearDisplay();
drawEyes(true, 0, 0);
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
drawEyes(true, 0, 0);
Serial.println("\nREADY! Type your question in the box below:");
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input.length() > 1) {
askFreeAI(input);
}
}
// Automatic blinking
if (millis() % 5000 < 150) {
drawEyes(false, 0, 0);
delay(150);
drawEyes(true, 0, 0);
}
}