mirror of
https://github.com/playfultechnology/esp32-eyes.git
synced 2025-12-06 17:15:42 -08:00
Updated readme and fixed typos
This commit is contained in:
@@ -84,7 +84,7 @@ void FaceBehavior::GoToEmotion(eEmotions emotion) {
|
||||
case eEmotions::Annoyed: _face.Expression.GoTo_Annoyed(); break;
|
||||
case eEmotions::Surprised: _face.Expression.GoTo_Surprised(); break;
|
||||
case eEmotions::Skeptic: _face.Expression.GoTo_Skeptic(); break;
|
||||
case eEmotions::Fustrated: _face.Expression.GoTo_Fustrated(); break;
|
||||
case eEmotions::Frustrated: _face.Expression.GoTo_Frustrated(); break;
|
||||
case eEmotions::Unimpressed: _face.Expression.GoTo_Unimpressed(); break;
|
||||
case eEmotions::Sleepy: _face.Expression.GoTo_Sleepy(); break;
|
||||
case eEmotions::Suspicious: _face.Expression.GoTo_Suspicious(); break;
|
||||
|
||||
@@ -30,7 +30,7 @@ enum eEmotions {
|
||||
Annoyed,
|
||||
Surprised,
|
||||
Skeptic,
|
||||
Fustrated,
|
||||
Frustrated,
|
||||
Unimpressed,
|
||||
Sleepy,
|
||||
Suspicious,
|
||||
|
||||
@@ -116,7 +116,7 @@ void FaceExpression::GoTo_Skeptic()
|
||||
_face.LeftEye.TransitionTo(Preset_Skeptic_Alt);
|
||||
}
|
||||
|
||||
void FaceExpression::GoTo_Fustrated()
|
||||
void FaceExpression::GoTo_Frustrated()
|
||||
{
|
||||
ClearVariations();
|
||||
_face.RightEye.TransitionTo(Preset_Fustrated);
|
||||
|
||||
@@ -40,7 +40,7 @@ class FaceExpression {
|
||||
void GoTo_Annoyed();
|
||||
void GoTo_Surprised();
|
||||
void GoTo_Skeptic();
|
||||
void GoTo_Fustrated();
|
||||
void GoTo_Frustrated();
|
||||
void GoTo_Unimpressed();
|
||||
void GoTo_Sleepy();
|
||||
void GoTo_Suspicious();
|
||||
|
||||
31
README.md
31
README.md
@@ -6,10 +6,39 @@ Inspired by the expressive eye animations of the Anki "Cozmo" robot, this Arduin
|
||||
<img src="https://github.com/playfultechnology/esp32-eyes/blob/main/doc/anki-cozmo-faces-3-1024x576.jpg" />
|
||||
|
||||
|
||||
Unlike some libraries which require a set of bitmap images for each frame of animation, this library draws each frame dynamically from a programmatic set of parameters.
|
||||
Unlike some libraries which display a set of pre-rendered bitmap images for each frame of animation, this library draws each frame dynamically from a programmatic set of parameters.
|
||||
|
||||
Heavily based on <a href="https://github.com/luisllamasbinaburo/ESP32_Faces/">this library</a>, although with significant adjustments:
|
||||
|
||||
- OLED (using <a href="https://github.com/olikraus/u8g2">u8g2</a>) rather than TFT (based on <a href="https://github.com/Bodmer/TFT_eSPI">eSPI_TFT</a>)
|
||||
- Horizontal rather than vertical alignment
|
||||
- Mirrored left/right eye animations
|
||||
- Automatic or manual blink and look direction
|
||||
|
||||
## Component Structure
|
||||
|
||||
- *Face* is the core object, consisting of left and right eye components, behaviour, expression, a look assistant, and a blink assistant. The outputs of these components are chained together to create the display on each frame:
|
||||
|
||||
- The Face *Behaviour* contains an array of weighted _Emotions_. There are currently 18 emotions, as defined in the enum in FaceEmotions.hpp.
|
||||
Each emotion can have an individual weight assigned to it, as follows:
|
||||
```
|
||||
face->Behavior.SetEmotion(eEmotions::Glee, 1.0);
|
||||
face->Behavior.SetEmotion(eEmotions::Anger, 0.5);
|
||||
```
|
||||
If ```face->RandomBehavior = true;``` (which is the default), then Face will use a roulette-wheel selection to randomly assign a new emotion based on their relative weights.
|
||||
The frequency with which the current emotion is re-evaluated (although this does not always result in a change) is determined by the value passed to ```face->Behaviour.Timer.SetIntervalMillis();```
|
||||
(If no weights have been assigned to any emotion, the face will default to "normal" emotion).
|
||||
Note that emotions are not blended together - the "weight" assigned to them determines the chances with which any emotion will be selected to be the next emotion (currentEmotion)
|
||||
|
||||
- *Expression* is a wrapper that handles transitions of each eye to the currently selected emotion.
|
||||
|
||||
- The Blink assistant handles blinking. If ```face->RandomBlink = true;``` (the default), the eyes will automatically blink, with a frequency determined by the value passed to ```face->Blink.Timer.SetIntervalMillis();```
|
||||
The eyes may be blinked manually by calling ```face->DoBlink();```
|
||||
|
||||
- The Look assistant handles the global position of the eyes around the screen. If ```face->RandomLook = true;``` (the default), the eyes will randomly move around the screen, with a frequency determined by the value passed to ```face->Look.Timer.SetIntervalMillis();```
|
||||
The eyes may be set to look at any position by calling ```face->Look.LookAt(x, y);``` (where x and y range from -1.0 - 1.0)
|
||||
|
||||
|
||||
- Each eye is responsible for managing their own drawing operations to the display (in EyeDrawer.cpp)
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
/***************************************************
|
||||
Copyright (c) 2020 Luis Llamas
|
||||
(www.luisllamas.es)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses
|
||||
****************************************************/
|
||||
* ESP32-Eyes, Copyright (c) 2023 Alastair Aitchison, Playful Technology
|
||||
* Based on previous work by Luis Llamas (www.luisllamas.es)
|
||||
*
|
||||
****************************************************/
|
||||
|
||||
// INCLUDES
|
||||
// Built-in Arduino I2C library
|
||||
@@ -17,36 +11,18 @@ You should have received a copy of the GNU Affero General Public License along w
|
||||
#include "Face.h"
|
||||
|
||||
// CONSTANTS
|
||||
const byte joystickPins[] = {26, 25};
|
||||
const byte blinkPin = 16;
|
||||
|
||||
// GLOBALS
|
||||
Face *face;
|
||||
String emotionName[] = {
|
||||
"Normal",
|
||||
"Angry",
|
||||
"Glee",
|
||||
"Happy",
|
||||
"Sad",
|
||||
"Worried",
|
||||
"Focused",
|
||||
"Annoyed",
|
||||
"Surprised",
|
||||
"Skeptic",
|
||||
"Frustrated",
|
||||
"Unimpressed",
|
||||
"Sleepy",
|
||||
"Suspicious",
|
||||
"Squint",
|
||||
"Furious",
|
||||
"Scared",
|
||||
"Awe"
|
||||
};
|
||||
|
||||
void setup(void) {
|
||||
// Create a serial connection
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__ __DATE__);
|
||||
|
||||
// Configure input pins
|
||||
pinMode(blinkPin, INPUT_PULLUP);
|
||||
|
||||
// Create a new face
|
||||
@@ -58,18 +34,16 @@ void setup(void) {
|
||||
face->Behavior.SetEmotion(eEmotions::Normal, 1.0);
|
||||
//face->Behavior.SetEmotion(eEmotions::Angry, 1.0);
|
||||
//face->Behavior.SetEmotion(eEmotions::Sad, 1.0);
|
||||
// Automatically select a random behaviour (based on the weight assigned to each emotion)
|
||||
// Automatically switch between possible allowed behaviours (selecting new behaviour randomly based on the weight assigned to each emotion)
|
||||
face->RandomBehavior = true;
|
||||
|
||||
// Automatically blink
|
||||
face->RandomBlink = true;
|
||||
// Set blink rate
|
||||
face->Blink.Timer.SetIntervalMillis(4000);
|
||||
//face->Blink.Timer.Stop();
|
||||
|
||||
// Automatically choose a new random direction to look
|
||||
face->RandomLook = true;
|
||||
|
||||
face->RandomLook = false;
|
||||
}
|
||||
|
||||
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
|
||||
@@ -87,7 +61,8 @@ float mapFloat(float x, float in_min, float in_max, float out_min, float out_max
|
||||
void loop(){
|
||||
static int lastMoveTime;
|
||||
|
||||
// To avoid making eyes too twitchy (and to allow time for previous animation to end), we only recalculate new position every 500ms
|
||||
// To avoid making eyes too twitchy (and to allow time for previous move animation to end),
|
||||
// only recalculate new position every 500ms
|
||||
if(millis() - lastMoveTime > 500) {
|
||||
int yRaw = analogRead(25);
|
||||
int xRaw = analogRead(26);
|
||||
@@ -96,11 +71,11 @@ void loop(){
|
||||
face->Look.LookAt(x, y);
|
||||
lastMoveTime = millis();
|
||||
}
|
||||
// Blink when joystick pressed in
|
||||
if(!digitalRead(blinkPin)){
|
||||
face->DoBlink();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Use this code to set a particular emotion from a button
|
||||
int32_t potValue = analogRead(15);
|
||||
@@ -108,31 +83,6 @@ void loop(){
|
||||
face->Behavior.SetEmotion(eEmotions::Angry, anger);
|
||||
*/
|
||||
|
||||
/*
|
||||
// Use this code to cycle automatically through all emotions
|
||||
static uint32_t counter = millis();
|
||||
static uint8_t emotionno = 0;
|
||||
static uint8_t changeEmotionFlag = 0;
|
||||
static uint8_t n = 0;
|
||||
|
||||
if(millis() - counter > 6000) {
|
||||
counter = millis();
|
||||
emotionno = n++;
|
||||
if(n >= EMOTIONS_COUNT) n = 0;
|
||||
changeEmotionFlag = 1;
|
||||
}
|
||||
|
||||
if(changeEmotionFlag) {
|
||||
// Clear any previously assigned weights
|
||||
face->Behavior.Clear();
|
||||
// Assign weight of 1.0 to the next emotion in the list
|
||||
face->Behavior.SetEmotion((eEmotions)emotionno, 1.0);
|
||||
// Print the new emotion to the serial monitor
|
||||
Serial.println(emotionName[emotionno]);
|
||||
// Reset the flag
|
||||
changeEmotionFlag = 0;
|
||||
}
|
||||
*/
|
||||
// Update the face!
|
||||
face->Update();
|
||||
//delay(10);
|
||||
}
|
||||
Reference in New Issue
Block a user