acidportal- 😈 Worlds smallest Evil Portal on a LilyGo T-QT |
git clone git://git.acid.vegas/acidportal.git |
Log | Files | Refs | Archive | README | LICENSE |
Anti-aliased_Clock.ino (5751B)
1 // Sketch to draw an analogue clock on the screen 2 // This uses anti-aliased drawing functions that are built into TFT_eSPI 3 4 // Anti-aliased lines can be drawn with sub-pixel resolution and permit lines to be 5 // drawn with less jaggedness. 6 7 // Based on a sketch by DavyLandman: 8 // https://github.com/Bodmer/TFT_eSPI/issues/905 9 10 11 #define WIFI_SSID "Your_SSID" 12 #define WIFI_PASSWORD "Your_Password" 13 14 #include <Arduino.h> 15 #include <TFT_eSPI.h> // Master copy here: https://github.com/Bodmer/TFT_eSPI 16 #include <SPI.h> 17 18 #include "NotoSansBold15.h" 19 20 TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h 21 TFT_eSprite face = TFT_eSprite(&tft); 22 23 #define CLOCK_X_POS 10 24 #define CLOCK_Y_POS 10 25 26 #define CLOCK_FG TFT_SKYBLUE 27 #define CLOCK_BG TFT_NAVY 28 #define SECCOND_FG TFT_RED 29 #define LABEL_FG TFT_GOLD 30 31 #define CLOCK_R 127.0f / 2.0f // Clock face radius (float type) 32 #define H_HAND_LENGTH CLOCK_R/2.0f 33 #define M_HAND_LENGTH CLOCK_R/1.4f 34 #define S_HAND_LENGTH CLOCK_R/1.3f 35 36 #define FACE_W CLOCK_R * 2 + 1 37 #define FACE_H CLOCK_R * 2 + 1 38 39 // Calculate 1 second increment angles. Hours and minute hand angles 40 // change every second so we see smooth sub-pixel movement 41 #define SECOND_ANGLE 360.0 / 60.0 42 #define MINUTE_ANGLE SECOND_ANGLE / 60.0 43 #define HOUR_ANGLE MINUTE_ANGLE / 12.0 44 45 // Sprite width and height 46 #define FACE_W CLOCK_R * 2 + 1 47 #define FACE_H CLOCK_R * 2 + 1 48 49 // Time h:m:s 50 uint8_t h = 0, m = 0, s = 0; 51 52 float time_secs = h * 3600 + m * 60 + s; 53 54 // Load header after time_secs global variable has been created so it is in scope 55 #include "NTP_Time.h" // Attached to this sketch, see that tab for library needs 56 57 // Time for next tick 58 uint32_t targetTime = 0; 59 60 // ========================================================================= 61 // Setup 62 // ========================================================================= 63 void setup() { 64 Serial.begin(115200); 65 Serial.println("Booting..."); 66 67 // Initialise the screen 68 tft.init(); 69 70 // Ideally set orientation for good viewing angle range because 71 // the anti-aliasing effectiveness varies with screen viewing angle 72 // Usually this is when screen ribbon connector is at the bottom 73 tft.setRotation(0); 74 tft.fillScreen(TFT_BLACK); 75 76 // Create the clock face sprite 77 //face.setColorDepth(8); // 8 bit will work, but reduces effectiveness of anti-aliasing 78 face.createSprite(FACE_W, FACE_H); 79 80 // Only 1 font used in the sprite, so can remain loaded 81 face.loadFont(NotoSansBold15); 82 83 // Draw the whole clock - NTP time not available yet 84 renderFace(time_secs); 85 86 targetTime = millis() + 100; 87 } 88 89 // ========================================================================= 90 // Loop 91 // ========================================================================= 92 void loop() { 93 // Update time periodically 94 if (targetTime < millis()) { 95 96 // Update next tick time in 100 milliseconds for smooth movement 97 targetTime = millis() + 100; 98 99 // Increment time by 100 milliseconds 100 time_secs += 0.100; 101 102 // Midnight roll-over 103 if (time_secs >= (60 * 60 * 24)) time_secs = 0; 104 105 // All graphics are drawn in sprite to stop flicker 106 renderFace(time_secs); 107 108 // Request time from NTP server and synchronise the local clock 109 // (clock may pause since this may take >100ms) 110 syncTime(); 111 } 112 } 113 114 // ========================================================================= 115 // Draw the clock face in the sprite 116 // ========================================================================= 117 static void renderFace(float t) { 118 float h_angle = t * HOUR_ANGLE; 119 float m_angle = t * MINUTE_ANGLE; 120 float s_angle = t * SECOND_ANGLE; 121 122 // The face is completely redrawn - this can be done quickly 123 face.fillSprite(TFT_BLACK); 124 125 // Draw the face circle 126 face.fillSmoothCircle( CLOCK_R, CLOCK_R, CLOCK_R, CLOCK_BG ); 127 128 // Set text datum to middle centre and the colour 129 face.setTextDatum(MC_DATUM); 130 131 // The background colour will be read during the character rendering 132 face.setTextColor(CLOCK_FG, CLOCK_BG); 133 134 // Text offset adjustment 135 constexpr uint32_t dialOffset = CLOCK_R - 10; 136 137 float xp = 0.0, yp = 0.0; // Use float pixel position for smooth AA motion 138 139 // Draw digits around clock perimeter 140 for (uint32_t h = 1; h <= 12; h++) { 141 getCoord(CLOCK_R, CLOCK_R, &xp, &yp, dialOffset, h * 360.0 / 12); 142 face.drawNumber(h, xp, 2 + yp); 143 } 144 145 // Add text (could be digital time...) 146 face.setTextColor(LABEL_FG, CLOCK_BG); 147 face.drawString("TFT_eSPI", CLOCK_R, CLOCK_R * 0.75); 148 149 // Draw minute hand 150 getCoord(CLOCK_R, CLOCK_R, &xp, &yp, M_HAND_LENGTH, m_angle); 151 face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 6.0f, CLOCK_FG); 152 face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 2.0f, CLOCK_BG); 153 154 // Draw hour hand 155 getCoord(CLOCK_R, CLOCK_R, &xp, &yp, H_HAND_LENGTH, h_angle); 156 face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 6.0f, CLOCK_FG); 157 face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 2.0f, CLOCK_BG); 158 159 // Draw the central pivot circle 160 face.fillSmoothCircle(CLOCK_R, CLOCK_R, 4, CLOCK_FG); 161 162 // Draw cecond hand 163 getCoord(CLOCK_R, CLOCK_R, &xp, &yp, S_HAND_LENGTH, s_angle); 164 face.drawWedgeLine(CLOCK_R, CLOCK_R, xp, yp, 2.5, 1.0, SECCOND_FG); 165 face.pushSprite(5, 5, TFT_TRANSPARENT); 166 } 167 168 // ========================================================================= 169 // Get coordinates of end of a line, pivot at x,y, length r, angle a 170 // ========================================================================= 171 // Coordinates are returned to caller via the xp and yp pointers 172 #define DEG2RAD 0.0174532925 173 void getCoord(int16_t x, int16_t y, float *xp, float *yp, int16_t r, float a) 174 { 175 float sx1 = cos( (a - 90) * DEG2RAD); 176 float sy1 = sin( (a - 90) * DEG2RAD); 177 *xp = sx1 * r + x; 178 *yp = sy1 * r + y; 179 }