Oled Oval Eyes

// Emotion overlay if (currentEmotion == EMOTION_HAPPY) { // Happy: draw an upward curved arch using small overlapping circles int radius = 4; int step = 2; // spacing between circles for (int i = 0; i <= EYE_WIDTH; i += step) { float angle = map(i, 0, EYE_WIDTH, -PI, 0); // from left to right, create a half arch int x = EYE1_X + dx + i; int y = BASE_EYE_Y + dy + EYE_HEIGHT - 2 - sin(angle) * 6; // adjust -2 and *6 for arch position and height display.fillCircle(x, y, radius, SSD1306_BLACK); } for (int i = 0; i <= EYE_WIDTH; i += step) { float angle = map(i, 0, EYE_WIDTH, -PI, 0); int x = EYE2_X + dx + i; int y = BASE_EYE_Y + dy + EYE_HEIGHT - 2 - sin(angle) * 6; display.fillCircle(x, y, radius, SSD1306_BLACK); } } else if (currentEmotion == EMOTION_SAD) { // Sad: draw a downward curved arch using small overlapping circles int radius = 4; int step = 2; for (int i = 0; i <= EYE_WIDTH; i += step) { float angle = map(i, 0, EYE_WIDTH, 0, PI); // mirrored arch int x = EYE1_X + dx + i; int y = BASE_EYE_Y + dy + 2 + sin(angle) * 6; // +2 and *6 adjust for position/height display.fillCircle(x, y, radius, SSD1306_BLACK); } for (int i = 0; i <= EYE_WIDTH; i += step) { float angle = map(i, 0, EYE_WIDTH, 0, PI); int x = EYE2_X + dx + i; int y = BASE_EYE_Y + dy + 2 + sin(angle) * 6; display.fillCircle(x, y, radius, SSD1306_BLACK); } } this is the code that im tryna edit instead of it being triangles i want it to be rounded triangles but i dont know how to make that. the picture is a similar example of how im tryna make them look like but this is what i ended up with
No description
No description
44 Replies
DarwinWasWrong
DarwinWasWrong3mo ago
rest of code ? @༺ ☾ ༻
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
theres another one made with python that makes it change emotions based on what i say
DarwinWasWrong
DarwinWasWrong3mo ago
No description
DarwinWasWrong
DarwinWasWrong3mo ago
void drawEyes(int eyelidHeight, int dx, int dy) {
display.clearDisplay();
display.fillRoundRect(EYE1_X + dx, BASE_EYE_Y + dy, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_WHITE);
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 5, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx, BASE_EYE_Y + dy, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_WHITE);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 5, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
void drawEyes(int eyelidHeight, int dx, int dy) {
display.clearDisplay();
display.fillRoundRect(EYE1_X + dx, BASE_EYE_Y + dy, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_WHITE);
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 5, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx, BASE_EYE_Y + dy, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_WHITE);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 5, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
DarwinWasWrong
DarwinWasWrong3mo ago
No description
Toph
Toph3mo ago
you may want to fix your name @༺ ☾ ༻ (see #code-of-conduct #9) 🤓 effectively, you're just drawing the rounded rectangle shape in "white" then drawing it again (but moved down) in "black" to effectively erase the bottom part...
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
o ur right
Toph
Toph3mo ago
👉 ideally, you'd have a function that draws the "wink" at a particular position (so you can use the same code to draw the left & right eye)... so you can do:
void eyesHappy()
{
eyeJoy( EYE_LEFT_X, EYE_Y );
eyeJoy( EYE_RIGHT_X, EYE_Y );
display.display();
}

void eyesWink()
{
eyeOpen( EYE_LEFT_X, EYE_Y );
eyeJoy( EYE_RIGHT_X, EYE_Y );
display.display();
}

void eyesClosed()
{
eyeShut( EYE_LEFT_X, EYE_Y );
eyeShut( EYE_RIGHT_X, EYE_Y );
display.display();
}
void eyesHappy()
{
eyeJoy( EYE_LEFT_X, EYE_Y );
eyeJoy( EYE_RIGHT_X, EYE_Y );
display.display();
}

void eyesWink()
{
eyeOpen( EYE_LEFT_X, EYE_Y );
eyeJoy( EYE_RIGHT_X, EYE_Y );
display.display();
}

void eyesClosed()
{
eyeShut( EYE_LEFT_X, EYE_Y );
eyeShut( EYE_RIGHT_X, EYE_Y );
display.display();
}
... and so on to show different emotions ... 😉 (eyeJoy() draws the curved closed eye; eyeOpen() will be the full rounded rectangle; & eyeShut() could be just a line)
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
okay wait i'll try to add more emotions soon i might need your help again guys thank you for now i appreciate it // how are you questions else if (currentEmotion == EMOTION_HOWAREYOU) { // Show happy eyes display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.display(); delay(3000); // Keep happy eyes for 2 seconds // Show text: "I'm okay" display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor((SCREEN_WIDTH - 80) / 2, (SCREEN_HEIGHT - 16) / 2); display.println("I'm okay"); display.display(); delay(3000); // Clear screen and return to default display.clearDisplay(); display.display(); currentEmotion = EMOTION_DEFAULT; } hi again im trying to add an animation here but im not sure how, i tried using chatgpt but im not understanding the code that its giving me nor is it working. i want it to show the eyes first with a nod animation yet im not sure how to make it do that // how are you questions else if (currentEmotion == EMOTION_HOWAREYOU) { // Show happy eyes display.clearDisplay(); display.fillRoundRect(EYE1_X + dx, BASE_EYE_Y + dy + 4, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.fillRoundRect(EYE2_X + dx, BASE_EYE_Y + dy + 4, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.display(); delay(300); // Nod up display.clearDisplay(); display.fillRoundRect(EYE1_X + dx, BASE_EYE_Y + dy + 10, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.fillRoundRect(EYE2_X + dx, BASE_EYE_Y + dy + 10, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.display(); delay(300); // Nod down again display.clearDisplay(); display.fillRoundRect(EYE1_X + dx, BASE_EYE_Y + dy + 4, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.fillRoundRect(EYE2_X + dx, BASE_EYE_Y + dy + 4, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK); display.display(); delay(300); delay(3000); // Keep happy eyes for 2 seconds // Show text: "I'm okay" display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor((SCREEN_WIDTH - 80) / 2, (SCREEN_HEIGHT - 16) / 2); display.println("I'm okay"); display.display(); delay(3000); // Clear screen and return to default display.clearDisplay(); display.display(); currentEmotion = EMOTION_DEFAULT; } i tried doing something like this but the eyes just dont appear and i dont know why
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
here is the full code
AnonEngineering
AnonEngineering3mo ago
what color does SSD1306_BLACK draw?
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
Its basically black eyes ontop of my white eyes
AnonEngineering
AnonEngineering3mo ago
yes, I saw what you were doing after i wrote that, nice effect!
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
I’m aiming for a big project but i dont have enough experience and knowledge that bothers me the code is long too its leaving me confused myself at times 💀
DarwinWasWrong
DarwinWasWrong3mo ago
One thing to try is using functions to break up the long code. like
void sadeyes()
{
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);

display.display();
delay(5000); // Show sad eyes for 5 seconds

// Clear eyes
display.clearDisplay();
display.display();

// Display hope verse number in center
int index = random(HOPE_COUNT);
display.setTextSize(2); // Slightly bigger
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 60) / 2, (SCREEN_HEIGHT - 16) / 2);
display.println(hope_verses[index]); // Just the verse number

display.display();
delay(5000); // Show verse number for 5 seconds

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
}
void sadeyes()
{
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);

display.display();
delay(5000); // Show sad eyes for 5 seconds

// Clear eyes
display.clearDisplay();
display.display();

// Display hope verse number in center
int index = random(HOPE_COUNT);
display.setTextSize(2); // Slightly bigger
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 60) / 2, (SCREEN_HEIGHT - 16) / 2);
display.println(hope_verses[index]); // Just the verse number

display.display();
delay(5000); // Show verse number for 5 seconds

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
}
same with other emotions
void happyeyes()
{ // Show happy eyes
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.display();
delay(3000); // Keep happy eyes for 2 seconds

// Show text: "I'm okay"
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 80) / 2, (SCREEN_HEIGHT - 16) / 2);
display.println("I'm okay");
display.display();
delay(3000);

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
}
void happyeyes()
{ // Show happy eyes
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.display();
delay(3000); // Keep happy eyes for 2 seconds

// Show text: "I'm okay"
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 80) / 2, (SCREEN_HEIGHT - 16) / 2);
display.println("I'm okay");
display.display();
delay(3000);

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
}
then use
else if (currentEmotion == EMOTION_SAD) {
sadeyes();
};
else if (currentEmotion == EMOTION_HOWAREYOU) {
happyeyes();
};
else if (currentEmotion == EMOTION_SAD) {
sadeyes();
};
else if (currentEmotion == EMOTION_HOWAREYOU) {
happyeyes();
};
rather than have all the eye code there in the decisions area @wisso
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
so for each emotion i’ll make a void ? for example for sad eyes void sadeyes(){} and so on
AnonEngineering
AnonEngineering3mo ago
yes a function void myFunction() {} void here means "this is a function that doesn't return anything"
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
can u explain to me what the concept of return does i never really got it
AnonEngineering
AnonEngineering3mo ago
a very simple example:
c++
int add2Function(int inputValue) {
return inputValue + 2;
}
c++
int add2Function(int inputValue) {
return inputValue + 2;
}
this function is declared as int because it returns to the place it was called from the inputValue + 2 as an integer you'd call it like
c++
int myReturnValue = add2Function(9);
c++
int myReturnValue = add2Function(9);
and after the above line executes myReturnValue would equal 11
DarwinWasWrong
DarwinWasWrong3mo ago
Btw. You can use a switch case for selection since your emotions variables are ints. @AnonEngineering I am on phone, so maybe you explain switch case if you feel like it. Otherwise I can do tomorrow.
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
Yall can take your time its ok
DarwinWasWrong
DarwinWasWrong3mo ago
@wisso now one thing - you do not need to use else if on things that are exclusive like commands eg
if (apple == red )
{ do this}

if (apple == blue)
{ do that}
if (apple == red )
{ do this}

if (apple == blue)
{ do that}
it doesnt require
if (apple == red )
{ do this}

else if (apple == blue)
{ do that}
if (apple == red )
{ do this}

else if (apple == blue)
{ do that}
AnonEngineering
AnonEngineering3mo ago
just got off work, now about switch case and else if...
DarwinWasWrong
DarwinWasWrong3mo ago
NOw he turns up...
AnonEngineering
AnonEngineering3mo ago
I've developed this horrible addiction to food and shelter 😉
DarwinWasWrong
DarwinWasWrong3mo ago
sleep rough, it will free you sleep ANYWAY
switch (currentEmotion) {

// Emotion overlay
case EMOTION_HAPPY:
// Happy: curved "smiling" eyes from bottom
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
break;


case EMOTION_SAD:
// Show sad eyes first
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);

display.display();
delay(5000); // Show sad eyes for 5 seconds

// Clear eyes
display.clearDisplay();
display.display();

// Display hope verse number in center
//int index = random(HOPE_COUNT);
display.setTextSize(2); // Slightly bigger
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 60) / 2, (SCREEN_HEIGHT - 16) / 2);
//display.println(hope_verses[index]); // Just the verse number

display.display();
delay(5000); // Show verse number for 5 seconds

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
break;

switch (currentEmotion) {

// Emotion overlay
case EMOTION_HAPPY:
// Happy: curved "smiling" eyes from bottom
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
break;


case EMOTION_SAD:
// Show sad eyes first
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy - 12, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);

display.display();
delay(5000); // Show sad eyes for 5 seconds

// Clear eyes
display.clearDisplay();
display.display();

// Display hope verse number in center
//int index = random(HOPE_COUNT);
display.setTextSize(2); // Slightly bigger
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 60) / 2, (SCREEN_HEIGHT - 16) / 2);
//display.println(hope_verses[index]); // Just the verse number

display.display();
delay(5000); // Show verse number for 5 seconds

// Clear screen and return to default
display.clearDisplay();
display.display();
currentEmotion = EMOTION_DEFAULT;
break;

since the emotions are enumerated (numbers) you can use switch case.
AnonEngineering
AnonEngineering3mo ago
in such a case (no pun intended) do you usually skip a default clause?
DarwinWasWrong
DarwinWasWrong3mo ago
I dont think it gets to there without an rmotion being set
AnonEngineering
AnonEngineering3mo ago
ahh, so no possibility of a value without a case
DarwinWasWrong
DarwinWasWrong3mo ago
not sure - the input string could use some work.
AnonEngineering
AnonEngineering3mo ago
this reminds me of the roboeyes library https://github.com/FluxGarage/RoboEyes
DarwinWasWrong
DarwinWasWrong3mo ago
I think the op been directed there but prefers own eyes code development Dont quote me on that I would chuck all the emotions into functions to clean up the switch case. eg
void happyeyes()
{
// Happy: curved "smiling" eyes from bottom
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
}
void happyeyes()
{
// Happy: curved "smiling" eyes from bottom
display.fillRoundRect(EYE1_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
display.fillRoundRect(EYE2_X + dx , BASE_EYE_Y + dy + 8, EYE_WIDTH, EYE_HEIGHT, 12, SSD1306_BLACK);
}
and of course - fix all the local variables that are not globally defined sigh replace all the local dx, dy with currentX and currentY...
DarwinWasWrong
DarwinWasWrong3mo ago
esp32 oled eyes Copy - Wokwi ESP32, STM32, Arduino Simulator
Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!
AnonEngineering
AnonEngineering3mo ago
that's a new one, wokwi compiles that for > 100 seconds, and won't let me cancel... Wokwi went down, back now
DarwinWasWrong
DarwinWasWrong3mo ago
oops - sorry about that.. 😆
DarwinWasWrong
DarwinWasWrong3mo ago
been working on other graphic methods
No description
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
what the frick I think im kind of getting somewhere but im still unsure I gave every emotion its own function or its own void idk about the switches tho are they better to use?
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
@DarwinWasWrong I tried to do it as you said with switches and cases
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
i used ai tho how the hell
༺ ☾ ༻
༺ ☾ ༻OP3mo ago
do you know how i can draw eyes like these
No description
DarwinWasWrong
DarwinWasWrong3mo ago
by using the one of the various robot eyes libraries that were sent in the begining
DarwinWasWrong
DarwinWasWrong3mo ago
FluxGarage
YouTube
#2 - Getting Started With the Free Robo Eyes Arduino Library
Download the Robo Eyes Library Here: https://github.com/FluxGarage/RoboEyes Check the First Demonstration Video: https://youtu.be/ibSaDEkfUOI 00:00 INTRO AND OVERVIEW 00:23 Prepare basic hardware 01:15 Install library and upload test sketch 03:34 Custom eye shapes 04:26 Face expressions and behaviour 05:39 OUTRO 05:55 WHAT COMES NEXT?
༺ ☾ ༻
༺ ☾ ༻OP2mo ago
ooo are yall familiar with esp32? I have an issue that i cant figure out at all Im using an esp32-s3 tiny devboard, i switched the arduino with it and i changed the code to befit the esp and it worked the first time next day it just stopped working its showing me that its connected and its active but its not responding to my codes at all its just not responding in any way I cant figure out why

Did you find this page helpful?