// ============================================================================ // VQC10 driver // ---------------------------------------------------------------------------- // Drives 8x VQC10 tubes/modules, each a 5x7 dot-matrix (LED or VFD-style) // character display (see Datasheets/VQC10_Funkamateur.pdf and // "VQC10 timing.jpeg" for the original hardware reference - VQC10 is an // Eastern-European 5x7 dot-matrix indicator tube, not a classic 7-segment // Nixie/VFD tube). Because each character cell is a dot matrix rather than // a fixed set of segments, this driver renders full ASCII text (via the // bitmap _font[] table below) instead of just digits. // // Wiring / protocol: the 8 character cells are driven through a chain of // 74HC595 serial-in/parallel-out shift registers (latchPin=RCK/STCP, // clockPin=SCK/SHCP, dataPin=DIN/SER - classic 3-wire SPI-like shift-out, // no MISO). Unlike most other drivers in this project (which multiplex // digit-by-digit), the VQC10 hardware is scanned ROW-by-ROW: for every one // of the NUMROWS=7 dot-rows, the column data for all NUMDIGITS=8 characters // is shifted out and latched digit-by-digit, then a single row-select line // is pulsed on for a PWM-timed on-period before moving to the next row. // Refresh timing is fully cooperative/blocking (see writeDisplay2() below) // rather than driven from the hardware timer ISR - see the note above // writeDisplay() for why. // // Used by clocks.h configuration(s): CLOCK_71 ("2x VQC10 clock by UNFI"). // ============================================================================ #ifdef VQC10 char tubeDriver[] = "VQC10"; #define NUMDIGITS 8 int maxDigits = NUMDIGITS; //Please, set the pin numbers in clock.h! //#define latchPin 5 //D2 RCK //#define clockPin 4 //D1 SCK //#define dataPin 2 //D4 DIN //#define ledOffpin 0 //D5 //#define D5pin 14 #define NUMCOLS 5 // font glyph width in dots (columns per character cell) #define NUMROWS 7 // font glyph height in dots (rows per character cell) - also the number of physical row-select lines scanned in writeDisplay2() boolean _upsidedown = false; // flips the dot-matrix rendering 180 degrees (for tubes mounted upside down); never set to true anywhere in this codebase - effectively dead/unused, kept for parity with wordclock.ino which shares this same font/transpose code byte row[NUMROWS]; // scratch buffer filled by show()/transposePattern(): one row-bitmap per dot-row for the character currently being rendered // Maps the shared digit[]/newDigit[] buffer codes (see core file: 0-9=digit, 10=BLANK, // 11=minus, 12=decimal point, 13+=driver-specific extra glyphs) to an index into the // ASCII-ordered _font[] table below, i.e. this converts the generic "digit code" alphabet // used by the core firmware into actual character codes this driver can render. char asciiConvert[] = "0123456789 -.APC~%oIF"; char DPchar = 0xFF; //decimal point - index of the dedicated 1-dot "decimal point" glyph appended at the very end of _font[] (see 0xFF entry below) char cDigit[NUMDIGITS+1] = "76543210"; // NOTE: declared/initialized but never referenced anywhere else in this file or the project - dead code (candidate for removal) byte dat[NUMDIGITS][NUMROWS]; // final row-bitmaps actually shifted out to hardware (post-animation-blend result) byte oldDat[NUMDIGITS][NUMROWS]; // row-bitmaps for the outgoing (old) character, built fresh each writeDisplaySingle() call byte newDat[NUMDIGITS][NUMROWS]; // row-bitmaps for the incoming (new) character, built fresh each writeDisplaySingle() call // standard ascii 5x7 font incl. the IBM-PC extension: // already defined in DotMatrx5x7.h // Format: NUMCOLS(5) bytes per glyph, indexed as glyph_code*NUMCOLS in show() above; each // byte is one column of the cell, with dot rows packed in its low NUMROWS(7) bits (bit0=row0 // top .. bit6=row6 bottom in normal orientation). Glyph 0xFF at the very end of the table is // repurposed as a dedicated "decimal point" glyph (see DPchar above) rather than a real // character, so it only lights a single dot instead of a printable symbol. //#define aUML "\x84" // ä = 0x84 //#define oUML "\x94" // ö = 0x94 //#define uUML "\x81" // ü = 0x81 //#define sZET "\xE1" // ß = 0xE1 //#define AUML "\x8E" // Ä = 0x8E //#define OUML "\x99" // Ö = 0x99 //#define UUML "\x9A" // Ü = 0x9A byte _font[] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 empty 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, // 0x01 sad 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, // 0x02 happy 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, // 0x03 heart 0x18, 0x3C, 0x7E, 0x3C, 0x18, // 0x04 diamond 0x1C, 0x57, 0x7D, 0x57, 0x1C, // 0x05 clover 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, // 0x06 spade 0x00, 0x18, 0x3C, 0x18, 0x00, // 0x07 small full circle 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, // 0x08 inverted small circle 0x06, 0x09, 0x06, 0x00, 0x00, // 0x09 small empty circle //old: 0x00, 0x18, 0x24, 0x18, 0x00, // 0x09 small empty circle 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, // 0x0A block (linefeed) 0x30, 0x48, 0x3A, 0x06, 0x0E, // 0x0B male 0x26, 0x29, 0x79, 0x29, 0x26, // 0x0C female 0x40, 0x7F, 0x05, 0x05, 0x07, // 0x0D note (carriage return) 0x40, 0x7F, 0x05, 0x25, 0x3F, // 0x0E two notes 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, // 0x0F sun 0x7F, 0x3E, 0x1C, 0x1C, 0x08, // 0x10 right triangle 0x08, 0x1C, 0x1C, 0x3E, 0x7F, // 0x11 left triangle 0x14, 0x22, 0x7F, 0x22, 0x14, // 0x12 up/down arrow 0x5F, 0x5F, 0x00, 0x5F, 0x5F, // 0x13 double exclamation mark 0x06, 0x09, 0x7F, 0x01, 0x7F, // 0x14 paragraph end sign (pilcrow) // 0x00, 0x66, 0x89, 0x95, 0x6A, // 0x15 paragraph sign original 0x00, 0x26, 0x49, 0x55, 0x28, // 0x15 paragraph sign 0x60, 0x60, 0x60, 0x60, 0x60, // 0x16 double underline 0x54, 0x62, 0x7F, 0x62, 0x54, // 0x17 up/down arrow with underline 0x08, 0x04, 0x7E, 0x04, 0x08, // 0x18 up arrow 0x10, 0x20, 0x7E, 0x20, 0x10, // 0x19 down arrow 0x08, 0x08, 0x2A, 0x1C, 0x08, // 0x1A right arrow 0x08, 0x1C, 0x2A, 0x08, 0x08, // 0x1B left arrow 0x14, 0x3E, 0x55, 0x41, 0x22, // 0x1C euro 0x63, 0x75, 0x69, 0x75, 0x63, // 0x1D timer 0x30, 0x38, 0x3E, 0x38, 0x30, // 0x1E up triangle 0x06, 0x0E, 0x3E, 0x0E, 0x06, // 0x1F down triangle 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 space 0x00, 0x00, 0x5F, 0x00, 0x00, // 0x21 ! 0x00, 0x07, 0x00, 0x07, 0x00, // 0x22 " 0x14, 0x7F, 0x14, 0x7F, 0x14, // 0x23 # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // 0x24 $ 0x23, 0x13, 0x08, 0x64, 0x62, // 0x25 % 0x36, 0x49, 0x56, 0x20, 0x50, // 0x26 & 0x00, 0x08, 0x07, 0x03, 0x00, // 0x27 ´ 0x00, 0x1C, 0x22, 0x41, 0x00, // 0x28 ( 0x00, 0x41, 0x22, 0x1C, 0x00, // 0x29 ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // 0x2A * 0x08, 0x08, 0x3E, 0x08, 0x08, // 0x2B + 0x00, 0x80, 0x70, 0x30, 0x00, // 0x2C , 0x08, 0x08, 0x08, 0x08, 0x08, // 0x2D - 0x00, 0x00, 0x60, 0x60, 0x00, // 0x2E . 0x20, 0x10, 0x08, 0x04, 0x02, // 0x2F / 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0x30 0 0x00, 0x42, 0x7F, 0x40, 0x00, // 0x31 1 0x72, 0x49, 0x49, 0x49, 0x46, // 0x32 2 0x21, 0x41, 0x49, 0x4D, 0x33, // 0x33 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 0x34 4 0x27, 0x45, 0x45, 0x45, 0x39, // 0x35 5 0x3C, 0x4A, 0x49, 0x49, 0x31, // 0x36 6 0x41, 0x21, 0x11, 0x09, 0x07, // 0x37 7 0x36, 0x49, 0x49, 0x49, 0x36, // 0x38 8 0x46, 0x49, 0x49, 0x29, 0x1E, // 0x39 9 0x00, 0x00, 0x14, 0x00, 0x00, // 0x3A : 0x00, 0x40, 0x34, 0x00, 0x00, // 0x3B ; 0x00, 0x08, 0x14, 0x22, 0x41, // 0x3C < 0x14, 0x14, 0x14, 0x14, 0x14, // 0x3D = 0x00, 0x41, 0x22, 0x14, 0x08, // 0x3E > 0x02, 0x01, 0x59, 0x09, 0x06, // 0x3F ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // 0x40 @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // 0x41 A 0x7F, 0x49, 0x49, 0x49, 0x36, // 0x42 B 0x3E, 0x41, 0x41, 0x41, 0x22, // 0x43 C 0x7F, 0x41, 0x41, 0x41, 0x3E, // 0x44 D 0x7F, 0x49, 0x49, 0x49, 0x41, // 0x45 E 0x7F, 0x09, 0x09, 0x09, 0x01, // 0x46 F 0x3E, 0x41, 0x41, 0x51, 0x73, // 0x47 G 0x7F, 0x08, 0x08, 0x08, 0x7F, // 0x48 H 0x00, 0x41, 0x7F, 0x41, 0x00, // 0x49 I 0x20, 0x40, 0x41, 0x3F, 0x01, // 0x4A J 0x7F, 0x08, 0x14, 0x22, 0x41, // 0x4B K 0x7F, 0x40, 0x40, 0x40, 0x40, // 0x4C L 0x7F, 0x02, 0x1C, 0x02, 0x7F, // 0x4D M 0x7F, 0x04, 0x08, 0x10, 0x7F, // 0x4E N 0x3E, 0x41, 0x41, 0x41, 0x3E, // 0x4F O 0x7F, 0x09, 0x09, 0x09, 0x06, // 0x50 P 0x3E, 0x41, 0x51, 0x21, 0x5E, // 0x51 Q 0x7F, 0x09, 0x19, 0x29, 0x46, // 0x52 R 0x26, 0x49, 0x49, 0x49, 0x32, // 0x53 S 0x03, 0x01, 0x7F, 0x01, 0x03, // 0x54 T 0x3F, 0x40, 0x40, 0x40, 0x3F, // 0x55 U 0x1F, 0x20, 0x40, 0x20, 0x1F, // 0x56 V 0x3F, 0x40, 0x38, 0x40, 0x3F, // 0x57 W 0x63, 0x14, 0x08, 0x14, 0x63, // 0x58 X 0x03, 0x04, 0x78, 0x04, 0x03, // 0x59 Y 0x61, 0x59, 0x49, 0x4D, 0x43, // 0x5A Z 0x00, 0x7F, 0x41, 0x41, 0x41, // 0x5B [ 0x02, 0x04, 0x08, 0x10, 0x20, // 0x5C '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // 0x5D ] 0x04, 0x02, 0x01, 0x02, 0x04, // 0x5E ^ 0x40, 0x40, 0x40, 0x40, 0x40, // 0x5F _ 0x00, 0x03, 0x07, 0x08, 0x00, // 0x60 ` 0x20, 0x54, 0x54, 0x78, 0x40, // 0x61 a 0x7F, 0x28, 0x44, 0x44, 0x38, // 0x62 b 0x38, 0x44, 0x44, 0x44, 0x00, // 0x63 c 0x38, 0x44, 0x44, 0x28, 0x7F, // 0x64 d 0x38, 0x54, 0x54, 0x54, 0x18, // 0x65 e 0x00, 0x08, 0x7E, 0x09, 0x02, // 0x66 f // 0x18, 0xA4, 0xA4, 0x9C, 0x78, // 0x67 g (old) 0x0C, 0x52, 0x52, 0x4E, 0x3C, // 0x67 g 0x7F, 0x08, 0x04, 0x04, 0x78, // 0x68 h 0x00, 0x44, 0x7D, 0x40, 0x00, // 0x69 i 0x20, 0x40, 0x40, 0x3D, 0x00, // 0x6A j 0x7F, 0x10, 0x28, 0x44, 0x00, // 0x6B k 0x00, 0x41, 0x7F, 0x40, 0x00, // 0x6C l 0x7C, 0x04, 0x78, 0x04, 0x78, // 0x6D m 0x7C, 0x08, 0x04, 0x04, 0x78, // 0x6E n 0x38, 0x44, 0x44, 0x44, 0x38, // 0x6F o 0xFC, 0x18, 0x24, 0x24, 0x18, // 0x70 p // 0x18, 0x24, 0x24, 0x18, 0xFC, // 0x71 q (old) 0x0C, 0x12, 0x12, 0x0C, 0x7E, // 0x71 q 0x7C, 0x08, 0x04, 0x04, 0x08, // 0x72 r 0x48, 0x54, 0x54, 0x54, 0x24, // 0x73 s 0x04, 0x04, 0x3F, 0x44, 0x24, // 0x74 t 0x3C, 0x40, 0x40, 0x20, 0x7C, // 0x75 u 0x1C, 0x20, 0x40, 0x20, 0x1C, // 0x76 v 0x3C, 0x40, 0x30, 0x40, 0x3C, // 0x77 w 0x44, 0x28, 0x10, 0x28, 0x44, // 0x78 x 0x0C, 0x10, 0x10, 0x50, 0x3C, // 0x79 y 0x44, 0x64, 0x54, 0x4C, 0x44, // 0x7A z 0x00, 0x08, 0x36, 0x41, 0x00, // 0x7B { 0x00, 0x00, 0x7F, 0x00, 0x00, // 0x7C | 0x00, 0x41, 0x36, 0x08, 0x00, // 0x7D } 0x02, 0x01, 0x02, 0x04, 0x02, // 0x7E ~ 0x3C, 0x26, 0x23, 0x26, 0x3C, // 0x7F house 0x1E, 0xA1, 0xA1, 0x61, 0x12, // 0x81 0x3A, 0x40, 0x40, 0x20, 0x7A, // 0x81 ü 0x38, 0x54, 0x54, 0x55, 0x59, // 0x82 0x21, 0x55, 0x55, 0x79, 0x41, // 0x83 0x21, 0x54, 0x54, 0x78, 0x41, // 0x84 ä 0x21, 0x55, 0x54, 0x78, 0x40, // 0x85 0x20, 0x54, 0x55, 0x79, 0x40, // 0x86 0x0C, 0x1E, 0x52, 0x72, 0x12, // 0x87 0x39, 0x55, 0x55, 0x55, 0x59, // 0x88 0x39, 0x54, 0x54, 0x54, 0x59, // 0x89 0x39, 0x55, 0x54, 0x54, 0x58, // 0x8A 0x00, 0x00, 0x45, 0x7C, 0x41, // 0x8B 0x00, 0x02, 0x45, 0x7D, 0x42, // 0x8C 0x00, 0x01, 0x45, 0x7C, 0x40, // 0x8D 0xF0, 0x29, 0x24, 0x29, 0xF0, // 0x8E Ä 0xF0, 0x28, 0x25, 0x28, 0xF0, // 0x8F 0x7C, 0x54, 0x55, 0x45, 0x00, // 0x90 0x20, 0x54, 0x54, 0x7C, 0x54, // 0x91 0x7C, 0x0A, 0x09, 0x7F, 0x49, // 0x92 0x32, 0x49, 0x49, 0x49, 0x32, // 0x93 0x32, 0x48, 0x48, 0x48, 0x32, // 0x94 ö 0x32, 0x4A, 0x48, 0x48, 0x30, // 0x95 0x3A, 0x41, 0x41, 0x21, 0x7A, // 0x96 0x3A, 0x42, 0x40, 0x20, 0x78, // 0x97 0x00, 0x9D, 0xA0, 0xA0, 0x7D, // 0x98 //0x39, 0x44, 0x44, 0x44, 0x39, // 0x99 Ö (old) 0x3D, 0x42, 0x42, 0x42, 0x3D, // 0x99 Ö 0x3D, 0x40, 0x40, 0x40, 0x3D, // 0x9A Ü 0x3C, 0x24, 0xFF, 0x24, 0x24, // 0x9B cent 0x48, 0x7E, 0x49, 0x43, 0x66, // 0x9C pound 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, // 0x9D 0xFF, 0x09, 0x29, 0xF6, 0x20, // 0x9E 0xC0, 0x88, 0x7E, 0x09, 0x03, // 0x9F 0x20, 0x54, 0x54, 0x79, 0x41, // 0xA0 0x00, 0x00, 0x44, 0x7D, 0x41, // 0xA1 0x30, 0x48, 0x48, 0x4A, 0x32, // 0xA2 0x38, 0x40, 0x40, 0x22, 0x7A, // 0xA3 0x00, 0x7A, 0x0A, 0x0A, 0x72, // 0xA4 0x7D, 0x0D, 0x19, 0x31, 0x7D, // 0xA5 0x26, 0x29, 0x29, 0x2F, 0x28, // 0xA6 0x26, 0x29, 0x29, 0x29, 0x26, // 0xA7 0x30, 0x48, 0x4D, 0x40, 0x20, // 0xA8 0x38, 0x08, 0x08, 0x08, 0x08, // 0xA9 0x08, 0x08, 0x08, 0x08, 0x38, // 0xAA 0x2F, 0x10, 0xC8, 0xAC, 0xBA, // 0xAB 0x2F, 0x10, 0x28, 0x34, 0xFA, // 0xAC 0x00, 0x00, 0x7B, 0x00, 0x00, // 0xAD exclamation mark upside down 0x08, 0x14, 0x2A, 0x14, 0x22, // 0xAE less less 0x22, 0x14, 0x2A, 0x14, 0x08, // 0xAF greater greater 0xAA, 0x00, 0x55, 0x00, 0xAA, // 0xB0 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 0xB1 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 0xB2 0x00, 0x00, 0x00, 0xFF, 0x00, // 0xB3 0x10, 0x10, 0x10, 0xFF, 0x00, // 0xB4 0x14, 0x14, 0x14, 0xFF, 0x00, // 0xB5 0x10, 0x10, 0xFF, 0x00, 0xFF, // 0xB6 0x10, 0x10, 0xF0, 0x10, 0xF0, // 0xB7 0x14, 0x14, 0x14, 0xFC, 0x00, // 0xB8 0x14, 0x14, 0xF7, 0x00, 0xFF, // 0xB9 0x00, 0x00, 0xFF, 0x00, 0xFF, // 0xBA 0x14, 0x14, 0xF4, 0x04, 0xFC, // 0xBB 0x14, 0x14, 0x17, 0x10, 0x1F, // 0xBC 0x10, 0x10, 0x1F, 0x10, 0x1F, // 0xBD 0x14, 0x14, 0x14, 0x1F, 0x00, // 0xBE 0x10, 0x10, 0x10, 0xF0, 0x00, // 0xBF 0x00, 0x00, 0x00, 0x1F, 0x10, // 0xC0 0x10, 0x10, 0x10, 0x1F, 0x10, // 0xC1 0x10, 0x10, 0x10, 0xF0, 0x10, // 0xC2 0x00, 0x00, 0x00, 0xFF, 0x10, // 0xC3 0x10, 0x10, 0x10, 0x10, 0x10, // 0xC4 0x10, 0x10, 0x10, 0xFF, 0x10, // 0xC5 0x00, 0x00, 0x00, 0xFF, 0x14, // 0xC6 0x00, 0x00, 0xFF, 0x00, 0xFF, // 0xC7 0x00, 0x00, 0x1F, 0x10, 0x17, // 0xC8 0x00, 0x00, 0xFC, 0x04, 0xF4, // 0xC9 0x14, 0x14, 0x17, 0x10, 0x17, // 0xCA 0x14, 0x14, 0xF4, 0x04, 0xF4, // 0xCB 0x00, 0x00, 0xFF, 0x00, 0xF7, // 0xCC 0x14, 0x14, 0x14, 0x14, 0x14, // 0xCD 0x14, 0x14, 0xF7, 0x00, 0xF7, // 0xCE 0x14, 0x14, 0x14, 0x17, 0x14, // 0xCF 0x10, 0x10, 0x1F, 0x10, 0x1F, // 0xD0 0x14, 0x14, 0x14, 0xF4, 0x14, // 0xD1 0x10, 0x10, 0xF0, 0x10, 0xF0, // 0xD2 0x00, 0x00, 0x1F, 0x10, 0x1F, // 0xD3 0x00, 0x00, 0x00, 0x1F, 0x14, // 0xD4 0x00, 0x00, 0x00, 0xFC, 0x14, // 0xD5 0x00, 0x00, 0xF0, 0x10, 0xF0, // 0xD6 0x10, 0x10, 0xFF, 0x10, 0xFF, // 0xD7 0x14, 0x14, 0x14, 0xFF, 0x14, // 0xD8 0x10, 0x10, 0x10, 0x1F, 0x00, // 0xD9 0x00, 0x00, 0x00, 0xF0, 0x10, // 0xDA 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xDB 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, // 0xDC 0xFF, 0xFF, 0xFF, 0x00, 0x00, // 0xDD 0x00, 0x00, 0x00, 0xFF, 0xFF, // 0xDE 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // 0xDF 0x38, 0x44, 0x44, 0x38, 0x44, // 0xE0 alpha 0x7C, 0x2A, 0x2A, 0x3E, 0x14, // 0xE1 beta / ß 0x7E, 0x02, 0x02, 0x06, 0x06, // 0xE2 Gamma 0x02, 0x7E, 0x02, 0x7E, 0x02, // 0xE3 Pi 0x63, 0x55, 0x49, 0x41, 0x63, // 0xE4 Sigma 0x38, 0x44, 0x44, 0x3C, 0x04, // 0xE5 sigma 0x40, 0x7E, 0x20, 0x1E, 0x20, // 0xE6 mu 0x06, 0x02, 0x7E, 0x02, 0x02, // 0xE7 tau 0x99, 0xA5, 0xE7, 0xA5, 0x99, // 0xE8 Phi 0x1C, 0x2A, 0x49, 0x2A, 0x1C, // 0xE9 theta 0x4C, 0x72, 0x01, 0x72, 0x4C, // 0xEA Omega 0x30, 0x4A, 0x4D, 0x4D, 0x30, // 0xEB delta 0x30, 0x48, 0x78, 0x48, 0x30, // 0xEC phi? 0xBC, 0x62, 0x5A, 0x46, 0x3D, // 0xED empty set 0x3E, 0x49, 0x49, 0x49, 0x00, // 0xEE epsilon 0x7E, 0x01, 0x01, 0x01, 0x7E, // 0xEF 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, // 0xF0 equivalence 0x44, 0x44, 0x5F, 0x44, 0x44, // 0xF1 plus minus 0x40, 0x51, 0x4A, 0x44, 0x40, // 0xF2 greater or equal 0x40, 0x44, 0x4A, 0x51, 0x40, // 0xF3 less or equal 0x00, 0x00, 0xFF, 0x01, 0x03, // 0xF4 0xE0, 0x80, 0xFF, 0x00, 0x00, // 0xF5 0x08, 0x08, 0x6B, 0x6B, 0x08, // 0xF6 divided by 0x36, 0x12, 0x36, 0x24, 0x36, // 0xF7 approx 0x06, 0x0F, 0x09, 0x0F, 0x06, // 0xF8 degree 0x00, 0x00, 0x18, 0x18, 0x00, // 0xF9 big dot 0x00, 0x00, 0x10, 0x10, 0x00, // 0xFA small dot 0x30, 0x40, 0xFF, 0x01, 0x01, // 0xFB square root 0x00, 0x1F, 0x01, 0x01, 0x1E, // 0xFC 0x00, 0x19, 0x1D, 0x17, 0x12, // 0xFD power of two 0x00, 0x3C, 0x3C, 0x3C, 0x3C, // 0xFE blob //0x00, 0x00, 0x00, 0x60, 0x60, // 0xFF: Decimal point: 4 points 0x00, 0x00, 0x00, 0x00, 0x40, // 0xFF: Decimal point, only 1 point }; void setup_pins() { DPRINTLN("VQC10 Clock - setup 74HC595 pins"); pinMode(latchPin, OUTPUT); regPin(latchPin,"latchPin"); pinMode(dataPin,OUTPUT); regPin(dataPin,"dataPin"); pinMode(clockPin,OUTPUT); regPin(clockPin,"clockPin"); pinMode(D5pin,INPUT); regPin(D5pin,"D5pin"); // NOTE: configured and registered but never read anywhere in this driver or the core file - purpose (spare sensor/button input?) is undocumented, see open questions digitsOnly = false; // this driver can render full ASCII text (dot-matrix font), not just 0-9, so let the core firmware know asciiConvert[16] = 9; // runtime override: digit-buffer code 16 (originally mapped to '~' above) is remapped to raw font index 9 ("small empty circle" glyph, see _font table) for a driver-specific extra symbol // Deliberately does NOT call startTimer() here (unlike most other drivers): the hardware // timer ISR (writeDisplay(), see below) is intentionally a no-op for VQC10, and indeed // startTimer() is never invoked anywhere for this driver in the whole project. All actual // refresh work happens cooperatively via writeDisplay2(), called repeatedly from loop()/ // Fdelay() in the core file - see the comment above writeDisplay() for why. } void inline shiftOutForward(byte myDataOut) { // This shifts 8 bits out MSB first, on the rising edge of the clock, clock idles low // Used for the "digit select" (Z) and "row select" shift-register bytes, whose bit // order must match how those select lines are physically wired to the 74HC595 outputs. for (int i=7; i>=0; i--) { digitalWrite(clockPin, 0); digitalWrite(dataPin, myDataOut & (1<MAXBRIGHTNESS) brightness = MAXBRIGHTNESS; //only for safety if (autoBrightness && displayON) { PWMtimeBrightness = max(PWM_min,PWM_max*lx/MAXIMUM_LUX); // ambient-light-driven dimming: scale row on-time by measured lux vs. MAXIMUM_LUX } else PWMtimeBrightness = max(PWM_min,PWM_max*brightness/MAXBRIGHTNESS); // manual brightness: scale row on-time by configured day/night brightness level iRow = 0; // FIXED (was "loopMax = maxDigits;", i.e. NUMDIGITS=8): this loop indexes dot-matrix ROWS, which // only range 0..NUMROWS-1 (NUMROWS=7, i.e. dat[i] is sized [NUMROWS]=[7]), not digit columns. The // old bound made the loop run iRow = 0..7 (8 iterations) instead of 0..6 (7 iterations), so on the // last iteration (iRow==7) "dat[i][iRow]" below read one element past the end of each digit's // 7-byte row array - for i> 1; else cmask = cmask << 1; rows[r] = rows[r] << (7-NUMCOLS); } } // Debug helper: prints one byte as 8 ASCII '0'/'1' characters (MSB first). void bPrint(byte in) { for (int i=7;i>=0;i--) { boolean b = in & (1<7) a=7; for (int k=0;k