$ 1 32 2.26757369614512E-05 0 5 50 Auto 2048 2048 true 242 832 704 832 768 4096 %2F%2F%202025%20Richard%20E%20Barber%0A%0A%23include%20%3CArduino.h%3E%0A%0A%2F%2F%20----%20Wiring%20%28columns%20and%20rows%29%20----%0A%2F%2F%20Columns%3A%20driven%20OUTPUT%2C%20idle%20HIGH%2C%20one%20pulled%20LOW%20per%20scan%20step%0A%23define%20C0%202%0A%23define%20C1%203%0A%23define%20C2%204%0A%23define%20C3%205%0A%2F%2F%20Rows%3A%20read%20as%20INPUT_PULLUP%20%28idle%20HIGH%2C%20go%20LOW%20when%20pressed%20with%20active%20column%29%0A%23define%20R0%206%0A%23define%20R1%207%0A%23define%20R2%208%0A%23define%20R3%209%0A%0A%2F%2F%20If%20your%20keypad%20part%20outputs%20HIGH%20on%20press%20instead%20of%20shorting%2C%20set%20to%201%0A%23define%20PRESSED_READS_HIGH%200%0A%0A%2F%2F%20----%20BCD%20bus%20%28UNO%20analog%20pins%20used%20as%20digital%29%20----%0A%2F%2F%20A0..A3%20%3D%20digital%2014..17%0A%2F%2F%20We%27ll%20drive%20these%20with%20digitalWrite%2814..17%2C%200%2F1%29.%0A%2F%2F%20%28No%20external%20latch%20required%3B%20we%20latch%20in%20software.%29%0Abyte%20g_latchedCode%20%3D%200%3B%20%20%20%2F%2F%20last%20latched%204-bit%20code%0Abyte%20g_anyPressed%20%20%3D%200%3B%20%20%20%2F%2F%201%20while%20any%20key%20is%20currently%20held%0A%0A%2F%2F%20----%20Helpers%20that%20avoid%20arrays%20%28iCircuit%20likes%20this%20better%29%20----%0Astatic%20byte%20colPin%28byte%20idx%29%20%7B%0A%20%20if%20%28idx%20%3D%3D%200%29%20return%20C0%3B%0A%20%20if%20%28idx%20%3D%3D%201%29%20return%20C1%3B%0A%20%20if%20%28idx%20%3D%3D%202%29%20return%20C2%3B%0A%20%20return%20C3%3B%20%2F%2F%20idx%20%3D%3D%203%0A%7D%0Astatic%20byte%20rowPin%28byte%20idx%29%20%7B%0A%20%20if%20%28idx%20%3D%3D%200%29%20return%20R0%3B%0A%20%20if%20%28idx%20%3D%3D%201%29%20return%20R1%3B%0A%20%20if%20%28idx%20%3D%3D%202%29%20return%20R2%3B%0A%20%20return%20R3%3B%20%2F%2F%20idx%20%3D%3D%203%0A%7D%0A%0A%2F%2F%20Key%20lookup%20without%202D%20array%20initializers%0Astatic%20char%20keyAt%28byte%20r%2C%20byte%20c%29%20%7B%0A%20%20%2F%2F%20Row-major%3A%20%20%7B%201%202%203%20A%20%3B%204%205%206%20B%20%3B%207%208%209%20C%20%3B%20%2A%200%20%23%20D%20%7D%0A%20%20if%20%28r%20%3D%3D%200%29%20%7B%0A%20%20%20%20if%20%28c%20%3D%3D%200%29%20return%20%271%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%201%29%20return%20%272%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%202%29%20return%20%273%27%3B%0A%20%20%20%20return%20%27A%27%3B%0A%20%20%7D%20else%20if%20%28r%20%3D%3D%201%29%20%7B%0A%20%20%20%20if%20%28c%20%3D%3D%200%29%20return%20%274%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%201%29%20return%20%275%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%202%29%20return%20%276%27%3B%0A%20%20%20%20return%20%27B%27%3B%0A%20%20%7D%20else%20if%20%28r%20%3D%3D%202%29%20%7B%0A%20%20%20%20if%20%28c%20%3D%3D%200%29%20return%20%277%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%201%29%20return%20%278%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%202%29%20return%20%279%27%3B%0A%20%20%20%20return%20%27C%27%3B%0A%20%20%7D%20else%20%7B%20%2F%2F%20r%20%3D%3D%203%0A%20%20%20%20if%20%28c%20%3D%3D%200%29%20return%20%27%2A%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%201%29%20return%20%270%27%3B%0A%20%20%20%20if%20%28c%20%3D%3D%202%29%20return%20%27%23%27%3B%0A%20%20%20%20return%20%27D%27%3B%0A%20%20%7D%0A%7D%0A%0A%2F%2F%20Map%20a%20key%20char%20to%20a%204-bit%20code%20%280x0..0xF%29%0Abyte%20codeForKey%28char%20k%29%20%7B%0A%20%20if%20%28k%20%3D%3D%20%270%27%29%20return%200x0%3B%0A%20%20if%20%28k%20%3D%3D%20%271%27%29%20return%200x1%3B%0A%20%20if%20%28k%20%3D%3D%20%272%27%29%20return%200x2%3B%0A%20%20if%20%28k%20%3D%3D%20%273%27%29%20return%200x3%3B%0A%20%20if%20%28k%20%3D%3D%20%274%27%29%20return%200x4%3B%0A%20%20if%20%28k%20%3D%3D%20%275%27%29%20return%200x5%3B%0A%20%20if%20%28k%20%3D%3D%20%276%27%29%20return%200x6%3B%0A%20%20if%20%28k%20%3D%3D%20%277%27%29%20return%200x7%3B%0A%20%20if%20%28k%20%3D%3D%20%278%27%29%20return%200x8%3B%0A%20%20if%20%28k%20%3D%3D%20%279%27%29%20return%200x9%3B%0A%20%20if%20%28k%20%3D%3D%20%27A%27%29%20return%200xA%3B%0A%20%20if%20%28k%20%3D%3D%20%27B%27%29%20return%200xB%3B%0A%20%20if%20%28k%20%3D%3D%20%27C%27%29%20return%200xC%3B%0A%20%20if%20%28k%20%3D%3D%20%27D%27%29%20return%200xD%3B%0A%20%20if%20%28k%20%3D%3D%20%27%2A%27%29%20return%200xE%3B%0A%20%20if%20%28k%20%3D%3D%20%27%23%27%29%20return%200xF%3B%0A%20%20return%200x0%3B%0A%7D%0A%0A%2F%2F%20Drive%20the%204-bit%20nibble%20on%20A0..A3%20%28pins%2014..17%29%2C%20very%20parser-friendly%0Avoid%20outputBCD%28byte%20code%29%20%7B%0A%20%20int%20b%3B%0A%0A%20%20b%20%3D%200%3B%0A%20%20if%20%28code%20%26%200x01%29%20b%20%3D%201%3B%0A%20%20digitalWrite%2814%2C%20b%29%3B%20%20%20%2F%2F%20A0%20%28LSB%29%0A%0A%20%20b%20%3D%200%3B%0A%20%20if%20%28code%20%26%200x02%29%20b%20%3D%201%3B%0A%20%20digitalWrite%2815%2C%20b%29%3B%20%20%20%2F%2F%20A1%0A%0A%20%20b%20%3D%200%3B%0A%20%20if%20%28code%20%26%200x04%29%20b%20%3D%201%3B%0A%20%20digitalWrite%2816%2C%20b%29%3B%20%20%20%2F%2F%20A2%0A%0A%20%20b%20%3D%200%3B%0A%20%20if%20%28code%20%26%200x08%29%20b%20%3D%201%3B%0A%20%20digitalWrite%2817%2C%20b%29%3B%20%20%20%2F%2F%20A3%20%28MSB%29%0A%7D%0A%0Avoid%20setup%28%29%20%7B%0A%20%20%2F%2F%20Console%0A%20%20Serial.begin%289600%29%3B%0A%20%20Serial.println%28%224x4%20kpd%20scanner%20to%20BCD.%22%29%3B%0A%0A%20%20%2F%2F%20Columns%20as%20outputs%2C%20idle%20HIGH%0A%20%20pinMode%28C0%2C%20OUTPUT%29%3B%20digitalWrite%28C0%2C%20HIGH%29%3B%0A%20%20pinMode%28C1%2C%20OUTPUT%29%3B%20digitalWrite%28C1%2C%20HIGH%29%3B%0A%20%20pinMode%28C2%2C%20OUTPUT%29%3B%20digitalWrite%28C2%2C%20HIGH%29%3B%0A%20%20pinMode%28C3%2C%20OUTPUT%29%3B%20digitalWrite%28C3%2C%20HIGH%29%3B%0A%0A%20%20%2F%2F%20Rows%20as%20inputs%20with%20pullups%0A%20%20pinMode%28R0%2C%20INPUT_PULLUP%29%3B%0A%20%20pinMode%28R1%2C%20INPUT_PULLUP%29%3B%0A%20%20pinMode%28R2%2C%20INPUT_PULLUP%29%3B%0A%20%20pinMode%28R3%2C%20INPUT_PULLUP%29%3B%0A%0A%20%20%2F%2F%20BCD%20bus%20pins%20%28A0..A3%20as%2014..17%29%0A%20%20pinMode%2814%2C%20OUTPUT%29%3B%0A%20%20pinMode%2815%2C%20OUTPUT%29%3B%0A%20%20pinMode%2816%2C%20OUTPUT%29%3B%0A%20%20pinMode%2817%2C%20OUTPUT%29%3B%0A%0A%20%20%2F%2F%20Start%20bus%20at%200000%20%28latched%29%0A%20%20g_latchedCode%20%3D%200x0%3B%0A%20%20outputBCD%28g_latchedCode%29%3B%0A%7D%0A%0Avoid%20driveAllColsHigh%28%29%20%7B%0A%20%20digitalWrite%28C0%2C%20HIGH%29%3B%0A%20%20digitalWrite%28C1%2C%20HIGH%29%3B%0A%20%20digitalWrite%28C2%2C%20HIGH%29%3B%0A%20%20digitalWrite%28C3%2C%20HIGH%29%3B%0A%7D%0A%0Avoid%20loop%28%29%20%7B%0A%20%20%2F%2F%20Scan%20each%20column%20LOW%20one%20at%20a%20time%0A%20%20for%20%28byte%20c%20%3D%200%3B%20c%20%3C%204%3B%20c%2B%2B%29%20%7B%0A%20%20%20%20driveAllColsHigh%28%29%3B%0A%20%20%20%20digitalWrite%28colPin%28c%29%2C%20LOW%29%3B%0A%0A%20%20%20%20%2F%2F%20small%20settle%20%28avoid%20microsecond%20API%20for%20iCircuit%29%0A%20%20%20%20delay%281%29%3B%0A%0A%20%20%20%20%2F%2F%20Read%20each%20row%0A%20%20%20%20for%20%28byte%20r%20%3D%200%3B%20r%20%3C%204%3B%20r%2B%2B%29%20%7B%0A%20%20%20%20%20%20int%20v%20%3D%20digitalRead%28rowPin%28r%29%29%3B%0A%20%20%20%20%20%20byte%20pressed%20%3D%20%28PRESSED_READS_HIGH%20%3F%20%28v%20%3D%3D%20HIGH%29%20%3A%20%28v%20%3D%3D%20LOW%29%29%3B%0A%20%20%20%20%20%20if%20%28pressed%29%20%7B%0A%20%20%20%20%20%20%20%20char%20k%20%3D%20keyAt%28r%2C%20c%29%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Only%20latch%20on%20the%20rising%20edge%20%28first%20frame%20of%20a%20new%20press%29%0A%20%20%20%20%20%20%20%20if%20%28%21g_anyPressed%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20byte%20code%20%3D%20codeForKey%28k%29%3B%0A%20%20%20%20%20%20%20%20%20%20g_latchedCode%20%3D%20code%3B%0A%20%20%20%20%20%20%20%20%20%20outputBCD%28g_latchedCode%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20Serial.print%28%22Key%20press%3A%20%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20Serial.print%28k%29%3B%0A%20%20%20%20%20%20%20%20%20%20Serial.print%28%22%20-%3E%20BCD%200x%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20Serial.println%28%28int%29code%2C%20HEX%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20g_anyPressed%20%3D%201%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20crude%20debounce%20so%20the%20console%20doesn%27t%20spam%0A%20%20%20%20%20%20%20%20delay%2850%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20pacing%20between%20columns%0A%20%20%20%20delay%281%29%3B%0A%20%20%7D%0A%0A%20%20%2F%2F%20Detect%20release%3A%20if%20no%20key%20is%20currently%20detected%2C%20clear%20the%20%22pressed%22%20flag%0A%20%20%2F%2F%20%28bus%20remains%20latched%20with%20last%20value%29%0A%20%20byte%20anyNow%20%3D%200%3B%0A%20%20for%20%28byte%20c%20%3D%200%3B%20c%20%3C%204%3B%20c%2B%2B%29%20%7B%0A%20%20%20%20%2F%2F%20quick%20re-scan%20%28very%20short%29%20to%20check%20if%20any%20key%20is%20down%0A%20%20%20%20driveAllColsHigh%28%29%3B%0A%20%20%20%20digitalWrite%28colPin%28c%29%2C%20LOW%29%3B%0A%20%20%20%20delay%281%29%3B%0A%20%20%20%20for%20%28byte%20r%20%3D%200%3B%20r%20%3C%204%3B%20r%2B%2B%29%20%7B%0A%20%20%20%20%20%20int%20v%20%3D%20digitalRead%28rowPin%28r%29%29%3B%0A%20%20%20%20%20%20byte%20pressed%20%3D%20%28PRESSED_READS_HIGH%20%3F%20%28v%20%3D%3D%20HIGH%29%20%3A%20%28v%20%3D%3D%20LOW%29%29%3B%0A%20%20%20%20%20%20if%20%28pressed%29%20%7B%0A%20%20%20%20%20%20%20%20anyNow%20%3D%201%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20if%20%28anyNow%29%20break%3B%0A%20%20%7D%0A%20%20if%20%28%21anyNow%29%20%7B%0A%20%20%20%20g_anyPressed%20%3D%200%3B%20%20%2F%2F%20ready%20to%20latch%20next%20new%20press%0A%20%20%7D%0A%7D > Arduino Uno R 736 832 736 800 0 0 1 7.2 0 0 0.5 | 1280 672 1280 736 0 g 768 864 768 896 0 g 1056 672 1056 704 0 202 512 928 512 992 1024 w 608 928 640 928 0 0 0 0 0 w 640 928 640 1120 0 0 0 0 0 w 640 1120 832 1120 0 0 0 0 0 w 608 960 672 960 0 0 0 0 0 w 672 960 672 1088 0 0 0 0 0 w 672 1088 832 1088 0 0 0 0 0 w 608 992 704 992 0 0 0 0 0 w 704 992 704 1056 0 0 0 0 0 w 704 1056 832 1056 0 0 0 0 0 w 608 1024 832 1024 0 0 0 0 0 w 736 832 736 928 0 0 0 0 0 w 736 928 832 928 0 0 0 0 0 w 768 864 800 864 0 0 0 0 0 w 800 864 800 896 0 0 0 0 0 w 800 896 832 896 0 0 0 0 0 157 320 928 320 992 1024 w 1056 672 1056 640 0 0 0 0 0 w 1056 640 1024 640 0 0 0 0 0 w 1024 640 1024 704 0 0 0 0 0 x 256 512 288 512 17 100 Arduino%204x4%20Keypad%20Scanner w 1696 1376 224 1376 0 0 0 0 0 w 1280 896 1024 896 0 0 0 0 0 w 1280 832 1248 832 0 0 0 0 0 w 1248 832 1248 928 0 0 0 0 0 w 1248 928 1024 928 0 0 0 0 0 w 1280 768 1216 768 0 0 0 0 0 w 1216 768 1216 960 0 0 0 0 0 w 1216 960 1024 960 0 0 0 0 0 w 1344 960 1344 1120 0 0 0 0 0 w 1344 1120 1024 1120 0 0 0 0 0 w 1280 704 1184 704 0 0 0 0 0 w 1184 704 1184 992 0 0 0 0 0 w 1184 992 1024 992 0 0 0 0 0 w 1408 960 1408 1088 0 0 0 0 0 w 1408 1088 1024 1088 0 0 0 0 0 w 1472 960 1472 1056 0 0 0 0 0 w 1472 1056 1024 1056 0 0 0 0 0 w 1536 960 1536 1024 0 0 0 0 0 w 1536 1024 1024 1024 0 0 0 0 0 w 480 928 512 928 0 0 0 0 0 w 480 960 512 960 0 0 0 0 0 w 480 992 512 992 0 0 0 0 0 w 480 1024 512 1024 0 0 0 0 0 w 416 1056 512 1056 0 0 0 0 0 w 384 1056 384 1088 0 0 0 0 0 w 384 1088 512 1088 0 0 0 0 0 w 352 1056 352 1120 0 0 0 0 0 w 352 1120 512 1120 0 0 0 0 0