/* Magic 3D Clock - see http://www.technoblogy.com/show?2KGV David Johnson-Davies - www.technoblogy.com - 27th June 2019 ATtiny85 @ 8 MHz (internal oscillator; BOD disabled) CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ // Set the RTC time const int TimeNow = 0x1245; // Set time; ie 12:45 // Adafruit 1.8" 128x160 display parameters int const ysize = 128, xsize = 160, yoff = 0, xoff = 0, invert = 0, rotate = 0; // ATtiny85 pins int const dc = 0; int const mosi = 1; int const sck = 2; int const cs = 3; int const ce = 4; // RTC // Character set for digits and colon - stored in program memory const uint16_t CharMap[11][14] PROGMEM = { {0x0F8, 0x3FE, 0x306, 0x603, 0x603, 0x603, 0x603, 0x603, 0x603, 0x603, 0x603, 0x306, 0x3FE, 0x0F8}, {0x030, 0x070, 0x1F0, 0x1F0, 0x030, 0x030, 0x030, 0x030, 0x030, 0x030, 0x030, 0x030, 0x1FE, 0x1FE}, {0x1FC, 0x3FE, 0x707, 0x603, 0x607, 0x00E, 0x01C, 0x038, 0x070, 0x0E0, 0x1C0, 0x380, 0x7FF, 0x7FF}, {0x1FC, 0x3FE, 0x707, 0x603, 0x003, 0x007, 0x0FE, 0x0FC, 0x006, 0x003, 0x603, 0x707, 0x3FE, 0x1FC}, {0x01C, 0x03C, 0x07C, 0x0EC, 0x1CC, 0x38C, 0x70C, 0x60C, 0x7FF, 0x7FF, 0x00C, 0x00C, 0x00C, 0x00C}, {0x7FF, 0x7FF, 0x600, 0x600, 0x600, 0x7FC, 0x3FE, 0x007, 0x003, 0x003, 0x603, 0x707, 0x3FE, 0x1FC}, {0x03C, 0x07C, 0x0E0, 0x1C0, 0x380, 0x300, 0x7FC, 0x7FE, 0x707, 0x603, 0x603, 0x707, 0x3FE, 0x1FC}, {0x7FF, 0x7FF, 0x006, 0x006, 0x00C, 0x00C, 0x018, 0x018, 0x030, 0x030, 0x060, 0x060, 0x0C0, 0x0C0}, {0x0F8, 0x1FC, 0x38E, 0x306, 0x306, 0x38E, 0x1FC, 0x3FE, 0x707, 0x603, 0x603, 0x707, 0x3FE, 0x1FC}, {0x1FC, 0x3FE, 0x707, 0x603, 0x603, 0x707, 0x3FF, 0x1FF, 0x006, 0x00E, 0x01C, 0x038, 0x1F0, 0x1E0}, {0x000, 0x000, 0x000, 0x000, 0x0E0, 0x0E0, 0x0E0, 0x000, 0x000, 0x000, 0x0E0, 0x0E0, 0x0E0, 0x000} }; // TFT colour display ********************************************** typedef unsigned int colour_t; int const CASET = 0x2A; // Define column address int const RASET = 0x2B; // Define row address int const RAMWR = 0x2C; // Write to display RAM // Current plot position and colours int x0, y0; colour_t fore = 0xFFFF; // White colour_t back = 0; // Black int scale = 1; // Text scale // Send a byte to the display void Data (uint8_t d) { for (uint8_t bit = 0x80; bit; bit >>= 1) { PINB = 1<>8, yoff, 0, yoff + ysize - 1); Command4(RASET, xoff>>8, xoff, 0, xoff + xsize - 1); Command(0x3A); Data(0x03); // 12-bit colour Command(RAMWR); for (int i=0; i>3; } // Move current plot position to x,y void MoveTo (int x, int y) { x0 = x; y0 = y; } // Plot point at x,y void PlotPoint (int x, int y) { PINB = 1<>8); Data(fore & 0xff); PINB = 1<>(11-x) & 1; } // Make four digit clock display boolean FourDigits (int x, int y, unsigned int time) { int xs = x - 44; int ys = y - 4; if ((ys < 0) || (55 < ys && ys < 64) || (ys > 119) || (xs < 0) || ((47 < xs) && (xs < 56)) || (xs > 103)) return 0; if (xs > 55) xs = xs - 8; if (ys > 63) ys = ys - 8; int xc = xs / 48; int yc = ys / 56; int d = (2 * (1 - yc)) + xc; char c = time>>(12-4*d) & 0x0F; return Pixel((xs % 48) / 4, (ys % 56) / 4, c); } // Test routine to display greymap void GreyMap (unsigned int time) { for (int x=0; x<160; x++) { for (int y=0; y<128; y++) { fore = FourDigits(x, y, time) ? 0xFFFF : 0; PlotPoint(x, y); } } } // Test routine to display texturemap void TextureMap () { for (int x=0; x<160; x++) { for (int y=0; y<128; y++) { fore = Texture(x, y); PlotPoint(x, y); } } } colour_t Row[160]; // Magic 3D Clock void Magic (unsigned int time) { // Build row for (int y=0; y<128; y++) { for (int x=0; x<32; x++) Row[x] = Texture(x, y); for (int slice=0; slice<4; slice++) { for (int k=0; k<32; k++) { int x = (k + ((slice + 1) * 32)); Row[x] = Row[x - 32 + 2 * FourDigits(x, y, time)]; } } for (int x=0; x<160; x++) { fore = Row[x]; PlotPoint(x, y); } } } // DS1302 Real Time Clock ********************************************** void InitRTC () { DDRB = DDRB | 1<>8); // Hour PINB = 1<>12 & 0x0f); PlotChar(Time>>8 & 0x0f); PlotChar(10); PlotChar(Time>>4 & 0x0f); PlotChar(Time & 0x0f); PlotChar(10); uint8_t Secs = GetSecs(); PlotChar(Secs>>4 & 0x0f); PlotChar(Secs & 0x0f); } // Setup ********************************************** void setup() { // Set up RTC InitRTC(); SetTime(TimeNow); // Set up display InitDisplay(); DisplayOn(); ClearDisplay(); } void loop () { unsigned int Time = GetTime(); Magic(Time); delay(1000); while (GetSecs() != 0) delay(1000); // Wait for next minute }