-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Animated_Eyes_1 is an example for a single display Animated_Eyes_2 is an example for two displays
- Loading branch information
Showing
35 changed files
with
260,676 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// An adaption of the "UncannyEyes" sketch (see eye_functions tab) | ||
// for the TFT_eSPI library. As written the sketch is for driving | ||
// one (240x320 minimum) TFT display, showing 2 eyes. See example | ||
// Animated_Eyes_2 for a dual 128x128 TFT display configued sketch. | ||
|
||
// The number of displays and chip selects used are defined in the | ||
// config.h tab. The display count can be set to 1. If using one | ||
// TFT and the chip select for that display is already defined in | ||
// the TFT_eSPI library then change the chip select pins to -1 in the | ||
// "config.h" tab. | ||
|
||
// The wiring for 2 TFT displays to an ESP32 is described in the | ||
// "wiring" tab of this sketch. | ||
|
||
// Configuration settings for the eye, eye style, display count, | ||
// chip selects and x offsets can be defined in the sketch "config.h" tab. | ||
|
||
// Performance (frames per second = fps) can be improved by using | ||
// DMA (for SPI displays only) on ESP32 and STM32 processors. Use | ||
// as high a SPI clock rate as is supported by the display. 27MHz | ||
// minimum, some diplays can be operated at higher clock rates in | ||
// the range 40-80MHz. | ||
|
||
// Single defaultEye performance for different processors | ||
// No DMA With DMA | ||
// ESP8266 (160MHz CPU) 40MHz SPI 36 fps | ||
// ESP32 27MHz SPI 53 fps 85 fps | ||
// ESP32 40MHz SPI 67 fps 102 fps | ||
// ESP32 80MHz SPI 82 fps 116 fps // Note: Few displays work reliably at 80MHz | ||
// STM32F401 55MHz SPI 44 fps 90 fps | ||
// STM32F446 55MHz SPI 83 fps 155 fps | ||
// STM32F767 55MHz SPI 136 fps 197 fps | ||
|
||
// DMA can be used with STM32 and ESP32 processors when the interface | ||
// is SPI, uncomment the next line: | ||
#define USE_DMA | ||
|
||
// Load TFT driver library | ||
#include <SPI.h> | ||
#include <TFT_eSPI.h> | ||
TFT_eSPI tft; // A single instance is used for 1 or 2 displays | ||
|
||
// A pixel buffer is used during eye rendering | ||
#define BUFFER_SIZE 1024 // 128 to 1024 seems optimum | ||
|
||
#ifdef USE_DMA | ||
#define BUFFERS 2 // 2 toggle buffers with DMA | ||
#else | ||
#define BUFFERS 1 // 1 buffer for no DMA | ||
#endif | ||
|
||
uint16_t pbuffer[BUFFERS][BUFFER_SIZE]; // Pixel rendering buffer | ||
bool dmaBuf = 0; // DMA buffer selection | ||
|
||
// This struct is populated in config.h | ||
typedef struct { // Struct is defined before including config.h -- | ||
int8_t select; // pin numbers for each eye's screen select line | ||
int8_t wink; // and wink button (or -1 if none) specified there, | ||
uint8_t rotation; // also display rotation and the x offset | ||
int16_t xposition; // position of eye on the screen | ||
} eyeInfo_t; | ||
|
||
#include "config.h" // ****** CONFIGURATION IS DONE IN HERE ****** | ||
|
||
extern void user_setup(void); // Functions in the user*.cpp files | ||
extern void user_loop(void); | ||
|
||
#define SCREEN_X_START 0 | ||
#define SCREEN_X_END SCREEN_WIDTH // Badly named, actually the "eye" width! | ||
#define SCREEN_Y_START 0 | ||
#define SCREEN_Y_END SCREEN_HEIGHT // Actually "eye" height | ||
|
||
// A simple state machine is used to control eye blinks/winks: | ||
#define NOBLINK 0 // Not currently engaged in a blink | ||
#define ENBLINK 1 // Eyelid is currently closing | ||
#define DEBLINK 2 // Eyelid is currently opening | ||
typedef struct { | ||
uint8_t state; // NOBLINK/ENBLINK/DEBLINK | ||
uint32_t duration; // Duration of blink state (micros) | ||
uint32_t startTime; // Time (micros) of last state change | ||
} eyeBlink; | ||
|
||
struct { // One-per-eye structure | ||
int16_t tft_cs; // Chip select pin for each display | ||
eyeBlink blink; // Current blink/wink state | ||
int16_t xposition; // x position of eye image | ||
} eye[NUM_EYES]; | ||
|
||
uint32_t startTime; // For FPS indicator | ||
|
||
// INITIALIZATION -- runs once at startup ---------------------------------- | ||
void setup(void) { | ||
Serial.begin(115200); | ||
//while (!Serial); | ||
Serial.println("Starting"); | ||
|
||
#if defined(DISPLAY_BACKLIGHT) && (DISPLAY_BACKLIGHT >= 0) | ||
// Enable backlight pin, initially off | ||
Serial.println("Backlight turned off"); | ||
pinMode(DISPLAY_BACKLIGHT, OUTPUT); | ||
digitalWrite(DISPLAY_BACKLIGHT, LOW); | ||
#endif | ||
|
||
// User call for additional features | ||
user_setup(); | ||
|
||
// Initialiase the eye(s), this will set all chip selects low for the tft.init() | ||
initEyes(); | ||
|
||
// Initialise TFT | ||
Serial.println("Initialising displays"); | ||
tft.init(); | ||
|
||
#ifdef USE_DMA | ||
tft.initDMA(); | ||
#endif | ||
|
||
// Raise chip select(s) so that displays can be individually configured | ||
digitalWrite(eye[0].tft_cs, HIGH); | ||
if (NUM_EYES > 1) digitalWrite(eye[1].tft_cs, HIGH); | ||
|
||
for (uint8_t e = 0; e < NUM_EYES; e++) { | ||
digitalWrite(eye[e].tft_cs, LOW); | ||
tft.setRotation(eyeInfo[e].rotation); | ||
tft.fillScreen(TFT_BLACK); | ||
digitalWrite(eye[e].tft_cs, HIGH); | ||
} | ||
|
||
#if defined(DISPLAY_BACKLIGHT) && (DISPLAY_BACKLIGHT >= 0) | ||
Serial.println("Backlight now on!"); | ||
analogWrite(DISPLAY_BACKLIGHT, BACKLIGHT_MAX); | ||
#endif | ||
|
||
startTime = millis(); // For frame-rate calculation | ||
} | ||
|
||
// MAIN LOOP -- runs continuously after setup() ---------------------------- | ||
void loop() { | ||
updateEye(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Pin selections here are based on the original Adafruit Learning System | ||
// guide for the Teensy 3.x project. Some of these pin numbers don't even | ||
// exist on the smaller SAMD M0 & M4 boards, so you may need to make other | ||
// selections: | ||
|
||
// GRAPHICS SETTINGS (appearance of eye) ----------------------------------- | ||
|
||
// If using a SINGLE EYE, you might want this next line enabled, which | ||
// uses a simpler "football-shaped" eye that's left/right symmetrical. | ||
// Default shape includes the caruncle, creating distinct left/right eyes. | ||
|
||
//#define SYMMETRICAL_EYELID | ||
|
||
// Enable ONE of these #includes -- HUGE graphics tables for various eyes: | ||
#include "data/defaultEye.h" // Standard human-ish hazel eye -OR- | ||
//#include "data/dragonEye.h" // Slit pupil fiery dragon/demon eye -OR- | ||
//#include "data/noScleraEye.h" // Large iris, no sclera -OR- | ||
//#include "data/goatEye.h" // Horizontal pupil goat/Krampus eye -OR- | ||
//#include "data/newtEye.h" // Eye of newt -OR- | ||
//#include "data/terminatorEye.h" // Git to da choppah! | ||
//#include "data/catEye.h" // Cartoonish cat (flat "2D" colors) | ||
//#include "data/owlEye.h" // Minerva the owl (DISABLE TRACKING) | ||
//#include "data/naugaEye.h" // Nauga googly eye (DISABLE TRACKING) | ||
//#include "data/doeEye.h" // Cartoon deer eye (DISABLE TRACKING) | ||
|
||
// DISPLAY HARDWARE SETTINGS (screen type & connections) ------------------- | ||
#define TFT_COUNT 1 // Number of screens (1 or 2) | ||
#define TFT1_CS -1 // TFT 1 chip select pin (set to -1 to use TFT_eSPI setup) | ||
#define TFT2_CS -1 // TFT 2 chip select pin (set to -1 to use TFT_eSPI setup) | ||
#define TFT_1_ROT 1 // TFT 1 rotation | ||
#define TFT_2_ROT 1 // TFT 2 rotation | ||
#define EYE_1_XPOSITION 0 // x shift for eye 1 image on display | ||
#define EYE_2_XPOSITION 320 - 128 // x shift for eye 2 image on display | ||
|
||
#define DISPLAY_BACKLIGHT -1 // Pin for backlight control (-1 for none) | ||
#define BACKLIGHT_MAX 255 | ||
|
||
// EYE LIST ---------------------------------------------------------------- | ||
#define NUM_EYES 2 // Number of eyes to display (1 or 2) | ||
|
||
#define BLINK_PIN -1 // Pin for manual blink button (BOTH eyes) | ||
#define LH_WINK_PIN -1 // Left wink pin (set to -1 for no pin) | ||
#define RH_WINK_PIN -1 // Right wink pin (set to -1 for no pin) | ||
|
||
// This table contains ONE LINE PER EYE. The table MUST be present with | ||
// this name and contain ONE OR MORE lines. Each line contains THREE items: | ||
// a pin number for the corresponding TFT/OLED display's SELECT line, a pin | ||
// pin number for that eye's "wink" button (or -1 if not used), a screen | ||
// rotation value (0-3) and x position offset for that eye. | ||
|
||
#if (NUM_EYES == 2) | ||
eyeInfo_t eyeInfo[] = { | ||
{ TFT1_CS, LH_WINK_PIN, TFT_1_ROT, EYE_1_XPOSITION }, // LEFT EYE chip select and wink pins, rotation and offset | ||
{ TFT2_CS, RH_WINK_PIN, TFT_2_ROT, EYE_2_XPOSITION }, // RIGHT EYE chip select and wink pins, rotation and offset | ||
}; | ||
#else | ||
eyeInfo_t eyeInfo[] = { | ||
{ TFT1_CS, LH_WINK_PIN, TFT_1_ROT, EYE_1_XPOSITION }, // EYE chip select and wink pins, rotation and offset | ||
}; | ||
#endif | ||
|
||
// INPUT SETTINGS (for controlling eye motion) ----------------------------- | ||
|
||
// JOYSTICK_X_PIN and JOYSTICK_Y_PIN specify analog input pins for manually | ||
// controlling the eye with an analog joystick. If set to -1 or if not | ||
// defined, the eye will move on its own. | ||
// IRIS_PIN speficies an analog input pin for a photocell to make pupils | ||
// react to light (or potentiometer for manual control). If set to -1 or | ||
// if not defined, the pupils will change on their own. | ||
// BLINK_PIN specifies an input pin for a button (to ground) that will | ||
// make any/all eyes blink. If set to -1 or if not defined, the eyes will | ||
// only blink if AUTOBLINK is defined, or if the eyeInfo[] table above | ||
// includes wink button settings for each eye. | ||
|
||
//#define JOYSTICK_X_PIN A0 // Analog pin for eye horiz pos (else auto) | ||
//#define JOYSTICK_Y_PIN A1 // Analog pin for eye vert position (") | ||
//#define JOYSTICK_X_FLIP // If defined, reverse stick X axis | ||
//#define JOYSTICK_Y_FLIP // If defined, reverse stick Y axis | ||
#define TRACKING // If defined, eyelid tracks pupil | ||
#define AUTOBLINK // If defined, eyes also blink autonomously | ||
|
||
// #define LIGHT_PIN -1 // Light sensor pin | ||
#define LIGHT_CURVE 0.33 // Light sensor adjustment curve | ||
#define LIGHT_MIN 0 // Minimum useful reading from light sensor | ||
#define LIGHT_MAX 1023 // Maximum useful reading from sensor | ||
|
||
#define IRIS_SMOOTH // If enabled, filter input from IRIS_PIN | ||
#if !defined(IRIS_MIN) // Each eye might have its own MIN/MAX | ||
#define IRIS_MIN 90 // Iris size (0-1023) in brightest light | ||
#endif | ||
#if !defined(IRIS_MAX) | ||
#define IRIS_MAX 130 // Iris size (0-1023) in darkest light | ||
#endif |
Oops, something went wrong.