/* Dot Matrix Clock V2 David Johnson-Davies - www.technoblogy.com - 5th October 2020 ATtiny2313 @ 8 MHz (external crystal; BOD disabled) CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ // Dot-matrix character definitions char CharMap[11][3] = { { 0x7F, 0x41, 0x7F }, // 0 { 0x00, 0x20, 0x7F }, // 1 { 0x4F, 0x49, 0x79 }, // 2 { 0x49, 0x49, 0x7F }, // 3 { 0x78, 0x08, 0x7F }, // 4 { 0x79, 0x49, 0x4F }, // 5 { 0x7F, 0x49, 0x4F }, // 6 { 0x40, 0x40, 0x7F }, // 7 { 0x7F, 0x49, 0x7F }, // 8 { 0x79, 0x49, 0x7F }, // 9 { 0x00, 0x00, 0x00 }, // space }; /* // Alternative rounded digits char CharMap[11][3] = { { 0x3E, 0x41, 0x3E }, // 0 { 0x00, 0x20, 0x7F }, // 1 { 0x27, 0x49, 0x31 }, // 2 { 0x2A, 0x49, 0x36 }, // 3 { 0x18, 0x28, 0x7F }, // 4 { 0x7A, 0x49, 0x4E }, // 5 { 0x3E, 0x49, 0x26 }, // 6 { 0x47, 0x48, 0x70 }, // 7 { 0x36, 0x49, 0x36 }, // 8 { 0x30, 0x48, 0x3F }, // 9 { 0x00, 0x00, 0x00 }, // space }; */ const int Space = 10; const int Dash = 11; const int Colon = 0x12; char Buffer[] = { 1, 2, 5, 9, 0 }; int Size[] = { 2, 10, 6, 10, 60 }; char Columns[12] = { 15, 9, 1, 4, 13, 16, 5, 11, 6, 8, 10, 7 }; int Column; int ColonState; volatile int Counter; void DisplayNextColumn() { char segs; Column = (Column+1) % 12; int DigitColumn = Column % 3; int Digit = Column / 3; char Char = Buffer[Digit]; // Blank leftmost digit if (Digit == 0 && Char == 0) Char = Space; // Treat column 0 as colon if (Column == 0) segs = ColonState; else segs = CharMap[Char][DigitColumn]; DDRB = DDRB & 0x80; // B6-B0 all inputs PORTB = PORTB | segs; // 1 = high DDRB = DDRB | segs; // 1 = output } void SetTime() { int Speed = 2000; if ((PIND & 1)==0) Speed = 4; // Check set time button if (Counter == 0) { // Runs at 1Hz Counter = Speed; ColonState = ColonState ^ Colon; // Flash colon int Carry = 1; for (int p=4; p>=0; p--) { char temp = Buffer[p] + Carry; Buffer[p] = temp % Size[p]; Carry = temp / Size[p]; if (Buffer[0]==1 && Buffer[1]==3) { Buffer[0] = 0; Buffer[1] = 1; } } } Counter--; } // Timer interrupts - multiplex display ISR (TIMER1_COMPA_vect) { pinMode(Columns[Column], INPUT); // Turn column off DisplayNextColumn(); SetTime(); } ISR (TIMER1_COMPB_vect) { pinMode(Columns[Column], OUTPUT); // Turn column on digitalWrite(Columns[Column], LOW); } void setup() { pinMode(0, INPUT_PULLUP); // Set up Timer1 to multiplex the display TCCR1A = 0<