acidportal- 😈 Worlds smallest Evil Portal on a LilyGo T-QT |
git clone git://git.acid.vegas/acidportal.git |
Log | Files | Refs | Archive | README | LICENSE |
Animated_Eyes_2.ino (5379B)
1 // An adaption of the "UncannyEyes" sketch (see eye_functions tab) 2 // for the TFT_eSPI library. As written the sketch is for driving 3 // two TFT displays. 4 5 // The size of the displayed eye is determined by the screen size and 6 // resolution. The eye image is 128 pixels wide. In humans the palpebral 7 // fissure (open eye) width is about 30mm so a low resolution, large 8 // pixel size display works best to show a scale eye image. Note that 9 // display manufacturers usually quote the diagonal measurement, so a 10 // 128 x 128 1.7" display or 128 x 160 2" display is about right. 11 12 // The number of displays and chip selects used are defined in the 13 // config.h tab. The display count can be set to 1. If using one 14 // TFT and the chip select for that display is already defined in 15 // the TFT_eSPI library then change the chip select pins to -1 in the 16 // "config.h" tab. 17 18 // The wiring for 2 TFT displays to an ESP32 is described in the 19 // "wiring" tab of this sketch. 20 21 // Configuration settings for the eye, eye style, display count, 22 // chip selects and x offsets can be defined in the sketch "config.h" tab. 23 24 // Performance (frames per second = fps) can be improved by using 25 // DMA (for SPI displays only) on ESP32 and STM32 processors. Use 26 // as high a SPI clock rate as is supported by the display. 27MHz 27 // minimum, some displays can be operated at higher clock rates in 28 // the range 40-80MHz. 29 30 // Single defaultEye performance for different processors 31 // No DMA With DMA 32 // ESP8266 (160MHz CPU) 40MHz SPI 36 fps 33 // ESP32 27MHz SPI 53 fps 85 fps 34 // ESP32 40MHz SPI 67 fps 102 fps 35 // ESP32 80MHz SPI 82 fps 116 fps // Note: Few displays work reliably at 80MHz 36 // STM32F401 55MHz SPI 44 fps 90 fps 37 // STM32F446 55MHz SPI 83 fps 155 fps 38 // STM32F767 55MHz SPI 136 fps 197 fps 39 40 // DMA can be used with RP2040, STM32 and ESP32 processors when the interface 41 // is SPI, uncomment the next line: 42 //#define USE_DMA 43 44 // Load TFT driver library 45 #include <SPI.h> 46 #include <TFT_eSPI.h> 47 TFT_eSPI tft; // A single instance is used for 1 or 2 displays 48 49 // A pixel buffer is used during eye rendering 50 #define BUFFER_SIZE 1024 // 128 to 1024 seems optimum 51 52 #ifdef USE_DMA 53 #define BUFFERS 2 // 2 toggle buffers with DMA 54 #else 55 #define BUFFERS 1 // 1 buffer for no DMA 56 #endif 57 58 uint16_t pbuffer[BUFFERS][BUFFER_SIZE]; // Pixel rendering buffer 59 bool dmaBuf = 0; // DMA buffer selection 60 61 // This struct is populated in config.h 62 typedef struct { // Struct is defined before including config.h -- 63 int8_t select; // pin numbers for each eye's screen select line 64 int8_t wink; // and wink button (or -1 if none) specified there, 65 uint8_t rotation; // also display rotation and the x offset 66 int16_t xposition; // position of eye on the screen 67 } eyeInfo_t; 68 69 #include "config.h" // ****** CONFIGURATION IS DONE IN HERE ****** 70 71 extern void user_setup(void); // Functions in the user*.cpp files 72 extern void user_loop(void); 73 74 #define SCREEN_X_START 0 75 #define SCREEN_X_END SCREEN_WIDTH // Badly named, actually the "eye" width! 76 #define SCREEN_Y_START 0 77 #define SCREEN_Y_END SCREEN_HEIGHT // Actually "eye" height 78 79 // A simple state machine is used to control eye blinks/winks: 80 #define NOBLINK 0 // Not currently engaged in a blink 81 #define ENBLINK 1 // Eyelid is currently closing 82 #define DEBLINK 2 // Eyelid is currently opening 83 typedef struct { 84 uint8_t state; // NOBLINK/ENBLINK/DEBLINK 85 uint32_t duration; // Duration of blink state (micros) 86 uint32_t startTime; // Time (micros) of last state change 87 } eyeBlink; 88 89 struct { // One-per-eye structure 90 int16_t tft_cs; // Chip select pin for each display 91 eyeBlink blink; // Current blink/wink state 92 int16_t xposition; // x position of eye image 93 } eye[NUM_EYES]; 94 95 uint32_t startTime; // For FPS indicator 96 97 // INITIALIZATION -- runs once at startup ---------------------------------- 98 void setup(void) { 99 Serial.begin(115200); 100 //while (!Serial); 101 Serial.println("Starting"); 102 103 #if defined(DISPLAY_BACKLIGHT) && (DISPLAY_BACKLIGHT >= 0) 104 // Enable backlight pin, initially off 105 Serial.println("Backlight turned off"); 106 pinMode(DISPLAY_BACKLIGHT, OUTPUT); 107 digitalWrite(DISPLAY_BACKLIGHT, LOW); 108 #endif 109 110 // User call for additional features 111 user_setup(); 112 113 // Initialise the eye(s), this will set all chip selects low for the tft.init() 114 initEyes(); 115 116 // Initialise TFT 117 Serial.println("Initialising displays"); 118 tft.init(); 119 120 #ifdef USE_DMA 121 tft.initDMA(); 122 #endif 123 124 // Raise chip select(s) so that displays can be individually configured 125 digitalWrite(eye[0].tft_cs, HIGH); 126 if (NUM_EYES > 1) digitalWrite(eye[1].tft_cs, HIGH); 127 128 for (uint8_t e = 0; e < NUM_EYES; e++) { 129 digitalWrite(eye[e].tft_cs, LOW); 130 tft.setRotation(eyeInfo[e].rotation); 131 tft.fillScreen(TFT_BLACK); 132 digitalWrite(eye[e].tft_cs, HIGH); 133 } 134 135 #if defined(DISPLAY_BACKLIGHT) && (DISPLAY_BACKLIGHT >= 0) 136 Serial.println("Backlight now on!"); 137 analogWrite(DISPLAY_BACKLIGHT, BACKLIGHT_MAX); 138 #endif 139 140 startTime = millis(); // For frame-rate calculation 141 } 142 143 // MAIN LOOP -- runs continuously after setup() ---------------------------- 144 void loop() { 145 updateEye(); 146 }