<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Raspberry Pi Projects</title><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/</link><description>Raspberry Pi Projects: You can find all the coolest new Raspberry Pi project or activities right here on element14. Research new Pi Project idea and more...</description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/solving-error-unknown-flash-device-an-openocd-upgrade-for-pi-pico-xiao-and-other-rp2040-boards?CommentId=c26fdc88-5c45-4bef-b1ec-17b64a094efe</link><pubDate>Sun, 25 Oct 2026 15:32:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:c26fdc88-5c45-4bef-b1ec-17b64a094efe</guid><dc:creator>shabaz</dc:creator><description>Finally! : ) Great, I&amp;#39;ll add a note at the top of the blog post to indicate that this is now historical.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/solving-error-unknown-flash-device-an-openocd-upgrade-for-pi-pico-xiao-and-other-rp2040-boards?CommentId=819f0e39-57ea-48b7-bd00-e28e28ddacc3</link><pubDate>Sun, 25 Oct 2026 15:28:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:819f0e39-57ea-48b7-bd00-e28e28ddacc3</guid><dc:creator>Jan Cumps</dc:creator><description>Update: solved. the Open OCD installed by the Raspberry Pi Pico Project extension for VS Code doesn&amp;#39;t need patching anymore.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=14a6c46f-88be-4736-8cf4-8da351e8c5f7</link><pubDate>Wed, 21 Oct 2026 02:08:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:14a6c46f-88be-4736-8cf4-8da351e8c5f7</guid><dc:creator>shabaz</dc:creator><description>Very efficient technique! I&amp;#39;ve just learned that adding the LEDs into the shift registers was extremely useful for unintended reasons; it&amp;#39;s a built-in analyzer : ) I can confirm the keyboard scan is happening, and can even put button states (to be displayed on the next tick) onto the LEDs, to see what&amp;#39;s happening even before attaching any real debugger.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=c1848e0c-151d-495b-ad9e-42f29b730913</link><pubDate>Wed, 21 Oct 2026 00:38:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:c1848e0c-151d-495b-ad9e-42f29b730913</guid><dc:creator>Jan Cumps</dc:creator><description>&amp;gt; It thinks it is possible to do button debounce If you need to keep debounce for each button, there is this scalable approach. create an array of uint16_t, with an entry for each button. When you notice a button is pressed in the scan loop, shift a 1 bit into LSB side of the entry, if not pressed, a 0. If , say, you plan to accept it &amp;quot;debounce passed&amp;quot; if it&amp;#39;s been high for 3 consecutive loops, you can do that by &amp;amp;&amp;amp; the entry with &amp;quot;0b00000111&amp;quot;. If that returns true, you have detected a debounced click. You can alter the number of scan loops it has to pass, by changing the amount of LSBs to check for. Same mechanism can be used for long presses. Say that you except a long press if a button has been consistently pressed for 12 scan loops. In that case, you can say it is long pressed if entry &amp;amp;&amp;amp; 0b0000111111111111 returns true</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=64742c43-905e-4990-b65c-a37e2c5bc9ae</link><pubDate>Wed, 21 Oct 2026 00:01:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:64742c43-905e-4990-b65c-a37e2c5bc9ae</guid><dc:creator>shabaz</dc:creator><description>Decided to set AI the task of figuring out the potential state machine for each button. It thinks it is possible to do button debounce, and also have an event when the button is held for a while, in a total of 5 states. The code (which expects to be run periodically, e.g. on a millisecond tick), provides a keypad_buttons_take_events function, which would indicate the key events like BTN_EVENT_PRESSED, BTN_EVENT_LONGPRESS and BTN_EVENT_RELEASED (and the event only occurs once, i.e. it is indeed an event, not a state value). I specifically asked for a debounce algorithm which immediately provides an event and deals with the debounce after the event, since that&amp;#39;s the way of having a fast response to user input. I asked for the debounce method to just inhibit further button events on that button in question, for a defined period (20 ticks or so at 1msec tick). I&amp;#39;ve not tried this out yet. /* * keypad_buttons.c * * Polling-based, per-button state machine. Call keypad_buttons_update() * exactly once every KEYPAD_TASK_TICK_PERIOD milliseconds, after filling * btn_arr[] with the latest active-high button bits. * * Button 0 is bit 0 of btn_arr[0], button 7 is bit 7 of btn_arr[0], * button 8 is bit 0 of btn_arr[1], etc. * * Timing constants are MILLISECONDS, not tick counts. * Example: 1000 ms at a 10 ms tick is 100 ticks (not 600 ticks). * * Debounce policy: the first opposite-level transition is accepted * immediately and emits an event; further opposite-level samples are * ignored until the lockout expires. There is NO stability validation. * A new transition can be accepted on the exact tick the lockout expires. * * Long press starts at the initially accepted press, not after debounce. * Long press fires once, on the first tick at/after the threshold, provided * the press has not already been released. A release at the exact threshold * takes precedence over a long press. * * Events are latched until retrieved with keypad_buttons_take_events(). * Repeated events of the same type before retrieval coalesce into one bit. */ #include #include #ifndef KEYPAD_BUTTON_COUNT #define KEYPAD_BUTTON_COUNT 16u #endif #ifndef KEYPAD_TASK_TICK_PERIOD #define KEYPAD_TASK_TICK_PERIOD 1u /* milliseconds: 1 through 10 */ #endif #ifndef BTN_DEBOUNCE_PERIOD #define BTN_DEBOUNCE_PERIOD 20u /* milliseconds */ #endif #ifndef BTN_LONGPRESS_PERIOD #define BTN_LONGPRESS_PERIOD 1000u /* milliseconds */ #endif #if (KEYPAD_BUTTON_COUNT 10u) #error &amp;quot;KEYPAD_TASK_TICK_PERIOD must be between 1 and 10 ms&amp;quot; #endif #if (BTN_DEBOUNCE_PERIOD 5000u) #error &amp;quot;BTN_LONGPRESS_PERIOD must be between 1 and 5000 ms&amp;quot; #endif #define KEYPAD_BUTTON_BYTES ((KEYPAD_BUTTON_COUNT + 7u) / 8u) #define BTN_DEBOUNCE_TICKS (BTN_DEBOUNCE_PERIOD / KEYPAD_TASK_TICK_PERIOD) /* Ceiling division: a non-multiple hold period rounds up to a scan tick. */ #define BTN_LONGPRESS_TICKS \ ((BTN_LONGPRESS_PERIOD + KEYPAD_TASK_TICK_PERIOD - 1u) / KEYPAD_TASK_TICK_PERIOD) typedef enum { BTN_UNPRESSED, /* Idle; next logic 1 produces PRESS immediately. */ BTN_PRESS_DEBOUNCE, /* PRESS emitted; ignore logic 0 for debounce time. */ BTN_PRESSED, /* Press accepted; wait for release or long press. */ BTN_HELD, /* Long-press event emitted; wait for release. */ BTN_RELEASE_DEBOUNCE /* RELEASE emitted; ignore logic 1 for debounce time. */ } ButtonState; typedef enum { BTN_EVENT_NONE = 0u, BTN_EVENT_PRESSED = 1u state = BTN_PRESS_DEBOUNCE; button-&amp;gt;debounce_ticks = 0u; button-&amp;gt;press_ticks = 0u; button-&amp;gt;pending_events |= BTN_EVENT_PRESSED; } static void button_accept_release(ButtonContext *button) { button-&amp;gt;state = BTN_RELEASE_DEBOUNCE; button-&amp;gt;debounce_ticks = 0u; button-&amp;gt;press_ticks = 0u; button-&amp;gt;pending_events |= BTN_EVENT_RELEASED; } void keypad_buttons_init(void) { for (size_t i = 0u; i &amp;gt; (i % 8u)) &amp;amp; 1u); /* Increment timers only for intervals that began on earlier ticks. */ if (button-&amp;gt;state == BTN_PRESS_DEBOUNCE || button-&amp;gt;state == BTN_RELEASE_DEBOUNCE) { if (button-&amp;gt;debounce_ticks debounce_ticks; } if (button-&amp;gt;state == BTN_PRESS_DEBOUNCE || button-&amp;gt;state == BTN_PRESSED) { if (button-&amp;gt;press_ticks press_ticks; } switch (button-&amp;gt;state) { case BTN_UNPRESSED: if (pressed) button_accept_press(button); break; case BTN_PRESS_DEBOUNCE: if (button-&amp;gt;debounce_ticks &amp;gt;= BTN_DEBOUNCE_TICKS) { /* Lockout expired: inspect this tick&amp;#39;s input immediately. */ if (!pressed) { button_accept_release(button); } else if (button-&amp;gt;press_ticks &amp;gt;= BTN_LONGPRESS_TICKS) { button-&amp;gt;state = BTN_HELD; button-&amp;gt;pending_events |= BTN_EVENT_LONGPRESS; } else { button-&amp;gt;state = BTN_PRESSED; } } break; case BTN_PRESSED: if (!pressed) { button_accept_release(button); } else if (button-&amp;gt;press_ticks &amp;gt;= BTN_LONGPRESS_TICKS) { button-&amp;gt;state = BTN_HELD; button-&amp;gt;pending_events |= BTN_EVENT_LONGPRESS; } break; case BTN_HELD: if (!pressed) button_accept_release(button); break; case BTN_RELEASE_DEBOUNCE: if (button-&amp;gt;debounce_ticks &amp;gt;= BTN_DEBOUNCE_TICKS) { /* Lockout expired: a high sample is a new press now. */ if (pressed) button_accept_press(button); else button-&amp;gt;state = BTN_UNPRESSED; } break; default: /* Recover safely if the state is corrupted. */ button-&amp;gt;state = BTN_UNPRESSED; button-&amp;gt;debounce_ticks = 0u; button-&amp;gt;press_ticks = 0u; break; } } } /* Returns BTN_UNPRESSED for an out-of-range index. */ ButtonState keypad_buttons_get_state(size_t button_index) { if (button_index &amp;gt;= KEYPAD_BUTTON_COUNT) return BTN_UNPRESSED; return buttons[button_index].state; } /* Returns and clears all pending events for one button. */ uint8_t keypad_buttons_take_events(size_t button_index) { uint8_t events; if (button_index &amp;gt;= KEYPAD_BUTTON_COUNT) return BTN_EVENT_NONE; events = buttons[button_index].pending_events; buttons[button_index].pending_events = BTN_EVENT_NONE; return events; } /* Logical accepted status, including either debounce lockout state. */ uint8_t keypad_buttons_is_pressed(size_t button_index) { if (button_index &amp;gt;= KEYPAD_BUTTON_COUNT) return 0u; const ButtonState state = buttons[button_index].state; return (uint8_t)(state == BTN_PRESS_DEBOUNCE || state == BTN_PRESSED || state == BTN_HELD); } /* Example integration (not compiled): * * uint8_t btn_arr[KEYPAD_BUTTON_BYTES]; * keypad_buttons_init(); * * // Every KEYPAD_TASK_TICK_PERIOD ms: * scan_hardware_into(btn_arr); * keypad_buttons_update(btn_arr); * * for (size_t i = 0; i &amp;lt; KEYPAD_BUTTON_COUNT; ++i) { * uint8_t events = keypad_buttons_take_events(i); * if (events &amp;amp; BTN_EVENT_PRESSED) { ... } * if (events &amp;amp; BTN_EVENT_LONGPRESS) { ... } * if (events &amp;amp; BTN_EVENT_RELEASED) { ... } * } */</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=12221da4-38e5-4f0c-a284-c30a2e4779fb</link><pubDate>Tue, 20 Oct 2026 23:51:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:12221da4-38e5-4f0c-a284-c30a2e4779fb</guid><dc:creator>shabaz</dc:creator><description>Hi DAB, Thanks!</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=1f762755-81ff-461c-b73e-aac197e3e9de</link><pubDate>Tue, 20 Oct 2026 20:28:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:1f762755-81ff-461c-b73e-aac197e3e9de</guid><dc:creator>DAB</dc:creator><description>Very cool.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=609e9aa7-7c82-464b-b81c-27e51ef2ae30</link><pubDate>Tue, 20 Oct 2026 13:00:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:609e9aa7-7c82-464b-b81c-27e51ef2ae30</guid><dc:creator>geralds</dc:creator><description>In normally usage you don&amp;#39;t need resetting the shift-registers. Just running in- running out the values... But your schematic is more flexible. Reset the input in the shift-register -&amp;gt; storage_clock to transfer the 0&amp;#39;s. -&amp;gt; activate the output, all get low. This is a bit faster to bring Low to all outputs. ---</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=e72a5dc8-82f4-4e38-8fd6-1735ab0e4dbf</link><pubDate>Tue, 20 Oct 2026 12:05:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:e72a5dc8-82f4-4e38-8fd6-1735ab0e4dbf</guid><dc:creator>shabaz</dc:creator><description>Very useful project! Also it shows only three wires from the microcontroller are needed (I used four, but the *SRCLR can simply be connected to the supply as shown in your circuit).</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=98668138-842b-4ed5-8cff-0e44ed933d5f</link><pubDate>Tue, 20 Oct 2026 11:40:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:98668138-842b-4ed5-8cff-0e44ed933d5f</guid><dc:creator>geralds</dc:creator><description>Yes, because the storage-register. I used it e.g. for an address register for programming of EPROMs.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=70731e84-518c-4f40-af66-40d4989c2ea3</link><pubDate>Tue, 20 Oct 2026 11:07:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:70731e84-518c-4f40-af66-40d4989c2ea3</guid><dc:creator>shabaz</dc:creator><description>Nice! Yes it would be great for driving loads of LEDs, with no flicker since they can be latched simultaneously, and are also very cost-effective. The &amp;#39;595 supports several mA per LED which gives a bright output from most indicator LEDs nowadays. I used 1k resistors but the LEDs (I&amp;#39;ve got red, blue and yellow LEDs on this board) are all still too bright.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=fc3e57cc-13ad-4964-9883-617bcd587302</link><pubDate>Tue, 20 Oct 2026 10:27:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:fc3e57cc-13ad-4964-9883-617bcd587302</guid><dc:creator>cstanton</dc:creator><description>The 74HC595 is such a useful chip. At Leeds Hackspace we used these extensively when working with LED cubes. It&amp;#39;s the chip that can latch out full bit patterns isn&amp;#39;t it?</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=addffb75-9b04-4c88-ba7e-ffbd76c335e0</link><pubDate>Tue, 20 Oct 2026 08:34:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:addffb75-9b04-4c88-ba7e-ffbd76c335e0</guid><dc:creator>veluv01</dc:creator><description>Interesting approach!</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=0792c494-4c9a-4036-924b-c34a9fcd75f4</link><pubDate>Tue, 20 Oct 2026 06:28:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:0792c494-4c9a-4036-924b-c34a9fcd75f4</guid><dc:creator>Jan Cumps</dc:creator><description>You can avoid the USB interrupt interruptions by running the scanning code on the 2nd Pico core. Or as a PIO state machine.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=7e6cc33a-b00d-475e-894b-8b84bcc0fd25</link><pubDate>Tue, 20 Oct 2026 02:23:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:7e6cc33a-b00d-475e-894b-8b84bcc0fd25</guid><dc:creator>shabaz</dc:creator><description>Poor probing, but a quick test to see how long the scan takes. This is the SR_CLK signal, and &amp;#39;scope is set to 2 usec per division. As can be seen, the first 16 pulses (which perform the button-scan occupy just under 9 usec. After that, the remaining 3 usec or so are occupied with the LED driver pulses (8 pulses with the LED data, and then 16 more pulses to continue to push the LED data to that last shift register). The above is repeatable, but, more realistically, when USB is enabled (which is normal with the Pico, since stdio input/output can be channelled through USB), then the USB code can interrupt any time, and then the SR_CLK trace looks like this (&amp;#39;scope is set to 5usec per division), and the time becomes variable, sometimes stretching to about 25-30 usec: Of course, both these values are very small, but you can see where the areas would be to make improvements (for instance, a lower value resistor would allow less nop() delay during the button scan, hence reducing from 9usec to perhaps 4 or 5 usec.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=f844299f-b66c-4404-8fef-64e1e071e8bd</link><pubDate>Mon, 19 Oct 2026 23:37:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:f844299f-b66c-4404-8fef-64e1e071e8bd</guid><dc:creator>shabaz</dc:creator><description>Hi Gerald, Interesting IC! And it has interrupt and switch debounce built-in. Several years ago I tried to reverse-engineer an old Z80 computer, I got to about 80% completion but have not had a chance to get back to it, they used an interesting IC, a peripheral expander with address bus. This is not the official circuit, just my attempt to give the signals plausible names. But it was interesting, it was clear they must be driving Port B (PB0-6) pins low one at a time (these select the row), and PA (columns) gets read. But they were also feeding all of PA into a very wide NAND gate, to somehow figure out if power save mode could be entered or exited, i.e. by seeing if any key was being pressed perhaps, and if a remote device was communicating via UART, since the *RXD line was part of the NAND gate inputs.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more?CommentId=14fa33c7-934e-40db-9e46-95c65f1d5183</link><pubDate>Mon, 19 Oct 2026 21:16:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:14fa33c7-934e-40db-9e46-95c65f1d5183</guid><dc:creator>geralds</dc:creator><description>Hi Shabaz shabaz ! Nice circuit. &amp;quot;The running 1&amp;quot;or (&amp;quot;0&amp;quot;)... I made such circuit with the keypad encoder MM74C922 (16keys), or xx923 (20keys). community.element14.com/.../MM74C922_2C00_923.pdf With this encoder you just need 1 IC. The outputs are 3-state, so you can connect it directly on a data bus. With a few logic gates you can expand the keypad matrix. This is a very old device. Maybe you have one in your box.</description></item><item><title>Blog Post: 74HC595: Build a Keyboard/Keypad/Joypad and more!</title><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/b/blog/posts/74hc595-build-a-keyboard-keypad-joypad-and-more</link><pubDate>Mon, 19 Oct 2026 19:48:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:b38144e4-e723-443b-8c88-b22e53ef33d6</guid><dc:creator>shabaz</dc:creator><description>Table of Contents Introduction 74HC595 Explained Circuit Code LED Bonus Building It Introduction A while back, I attached a 4x4 keypad matrix to a microcontroller, and it took up eight GPIO inputs. This time around, I noticed I had a load of buttons from an unused project, and decided to rethink things, and ended up building a little custom keypad for the Pi Pico (it can be done with any microcontroller). This could be useful for robotics, gaming, all sorts of things really. It was a quick weekend project, and I used the parts I had. The usual problem to solve, as hinted above, is that many buttons can consume a lot of GPIO! Various solutions exist, and (in my opinion) one of the best approaches is to use a GPIO expander chip, because it also eliminates the need for repeated keyboard scanning. Many GPIO expanders have an interrupt output, so all the microcontroller needs to do is enable a GPIO interrupt and in the event that there’s a button change, simply read in the inputs using I2C or SPI. In the absence of a GPIO expander, there are a few reduced-GPIO key scanning options, and one method is to use a parallel-input-to-serial-output shift register, and clock in all the inputs. I didn’t have such a shift register, but I had the complete opposite; a serial-input-to-parallel output shift register. I decided to use that, and learned along the way that it’s actually not a bad solution if scanning is acceptable (but there’s a way to use the same circuit and partially eliminate scanning too, if desired). The &amp;#39;595 is a useful problem-solver. 74HC595 Explained There are three parts to the ‘595. The blue part has three inputs, which are initially set low by the microcontroller. Set pin 10 high to keep the shift register out of reset. The other two inouts are a clock and data pair; set the SER data line, and pulse SRCLK high and low to push the bit into the shift register. On the right side, you could attach another shift register if desired. Once the shift register contains the desired logic levels, the middle portion of the ‘595 can be used, by pulsing RCLK high and low. It will store the data into output registers, and you’ll see that on pins QA to QH, provided pin 13 (output enable) is wired low. When joining up multiple ‘595s in a chain, usually pins 10, 11 and 12 are all wired together across all chain. Circuit The result of the circuit and code is to apply a voltage to each push-switch, one at a time, and let the microcontroller sense when the common wire, SW_DATA, goes high. That will only occur if a user presses a button at the time when a voltage is being applied to the switch, therefore rapid scanning is needed, which is not always a major issue with microcontrollers, but it depends on the project if this is convenient or not. To perform the scanning, three microcontroller output signals are needed for the shift register, but I used four to simplify the coding a little bit. A weakness in this circuit is that there is nothing to pull the SW_DATA signal sharply down, so a low-value resistor (such as 2.2k as I’ve used) is needed, otherwise the settling time is quite long. If you see erroneous simultaneous button-presses whenever a button is pressed, then the cause is most likely too high a resistor value there. Code I wrote a very short Pi Pico demo program, that scans the buttons every 100 msec (in practise you’d want to set it to a faster rate), and displays via USB UART two 8-bit hexadecimal values, indicating button(s) pressed. The way the code works, is that it sets the SER_DAT line high, and then pulses the shift register clock once, then sets SER_DAT low for the rest of the entire scan. That single high value will pulse its way through the shift register on 15 more clock pulses. After each clock pulse, the R_CLK signal is pulsed too; that registers the shift register value to the outputs, therefore driving just one switch line high. After a very short delay (couple of hundred nsec) the microcontroller reads the common switch line, and then the cycle repeats for the remainder switches. LED Bonus One of the key things about parallel-output registers, is that they can be used as outputs : ) I decided to append another 74HC595 (these ICs cost about $0.10) and use it for up to 8 LEDs. The code ( viewable/downloadable here ) doesn’t change much. After all the keys have been scanned, the desired LED settings are clocked in, and then padded with enough zero bits to push past the first shift registers. Because all the 595’s are chained and I’d joined all the RCLK signals together, it is not possible to solely do a key scan without affecting the LED outputs. However, in practical terms, it makes no difference, because the key scan happens within microseconds, thus leaving plenty of time until the next key scan, for the LED output registers to hold their desired levels. Building It I used PB86 switches that I had purchased a while back, they are really convenient because they fit 0.1” perfboard if a couple of tiny plastic locator pegs are snipped off. The odd button in the photo is there for a purpose (I will use it to map different key layouts, if the user holds down that button and presses another). This project is very easy to build because triple ‘595 boards are available: (Image source: Google Images) I didn’t have such a board, so took the longer route. The underside is very messy. Anyway, this was just supposed to be a quick experiment, and it seems to work fine. The code is in the simple_keypad project repository , and it uses the Pi Pico C/C++ SDK, but it&amp;#39;s so simple, that it would be easy to port to Arduino or other platforms. Thanks for reading!</description><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/shift%2bregister">shift register</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/keyboard">keyboard</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/rpiintermediate">rpiintermediate</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/keypad">keypad</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/rpibeginner">rpibeginner</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/raspberry_5F00_pi_5F00_projects">raspberry_pi_projects</category><category domain="https://community.element14.com/products/raspberry-pi/raspberrypi_projects/tags/74hc595">74hc595</category></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/w/documents/1504/building-a-low-power-compact-lcd-display?CommentId=1b586931-63ee-425d-95c0-c2a6f0caa233</link><pubDate>Fri, 21 Aug 2026 15:49:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:1b586931-63ee-425d-95c0-c2a6f0caa233</guid><dc:creator>colporteur</dc:creator><description>Professionally done, as always. I like the soup-to-nuts details. Make me feel I could build it myself. Except for the SMT work.</description></item><item><title /><link>https://community.element14.com/products/raspberry-pi/raspberrypi_projects/w/documents/1504/building-a-low-power-compact-lcd-display?CommentId=51a1a7a4-2001-425b-83bd-2c86da73f166</link><pubDate>Thu, 20 Aug 2026 14:06:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:51a1a7a4-2001-425b-83bd-2c86da73f166</guid><dc:creator>Mahipal1985</dc:creator><description>Thank you</description></item></channel></rss>