DIY Arduino RGB Keyboard Mod
by Instructosaurus in Circuits > Arduino
696 Views, 0 Favorites, 0 Comments
DIY Arduino RGB Keyboard Mod
I had recently bought myself my first fancy mechanical RGB keyboard and so I had an obsolete cheap membrane keyboard laying around. It only had static RGB that switched on and off with the scroll lock button. This had previously inconvinienced me greately since I couldn't turn the lights off and keep the buttons functional. Furthermore, it was even worse on Linux since scroll lock is mostly used to freeze console output. Since I now had a new keyboard to daily drive I decided to take the old one apart and figure out if I could fix the scroll lock nuisance. As is often the case I couldn't help myself but to complicate things , so I made the keyboard have a few different LED patterns, adjustable speed and brightness and some sound effects. Oh, and most importantly, a proper, dedicated on/off button. The video above is a short demo of how the keyboard works now.
Some basic electronics and programming knowledge is needed and I tried to put enough references at the end of this article for anyone to be able to understand why and how I've done everything.
Supplies
All the used passive electronics components are collected in the above table. Besides those, you'll need:
1x Arduino (I used a Nano but most microcontrollers will work just fine)
1x suitable USB cable for the Arduino that you don't mind eventually cutting
2x THT button
1x piezo buzzer
solderable protoboard
Optional:
* two pins and two female-male wires (alternatively, you could just use two normal wires)
*a 3D printed housing. I uploaded my design as an .stl if you want to just print it out and also as an .f3d if you'd like to change the design.
Note that many of the components are replaceable, at the very least with those with a similar value.
As always I did my best to try and reuse parts from old electronics to do my small contribution to reducing e-waste on our lovely planet.
Dreaming Up a Plan
After disasembling the keyboard I noticed that the RGB strip is plugged into separed power leads on the small keyboard PCB (visible in the above picture). Besides this, everything was like a regular membrane keyboard. I had decided that I was going to run the power for the Arduino directly from the power lines from the USB cable, hijacking the exposed leads on the PCB. Then I inspected the LED strip to see if I could wire each of the three colors separately and make them individually addressible. After some poking around with an ohmmeter I figured out that the LEDs were connected in series and not in parallel. And since different LED colors are, in general, driven with different currents (and at different voltages), it seemed a bit too risky trying to wire each color separately so I decided to control the LED strip as a whole.
Now I had to think about the level of adjustability of the LEDs I'd want. After quite some thought and tinkering with drafts of programs I imagine I was capable of writing I ended on the following plan: an on/off button, a "mode change" button for the lights, a speed potentiometer and a brightness potentiometer. It was around this point that it seemed fun to have the only-timey Windows shutdown sound play out when the LEDs are turned off. So I decided to add a piezo buzzer as well.
Putting Together the Circuit
I put together a simple circuit in accordance with what I'd decided to do, as visible in the above pictures. Some things to note: the buttons have bypass capacitors to mechanically account for debouncing problems, since these buttons are meant to be intterupts (the next segment explains why this is needed). Buttons, transistors and potentiometers all have current limiting resistors to protect the microcontroller. R8 is a pulldown resistor for the MOSFET to make sure it's in the off state when the Arduino pin is low. The buzzer has a resistor in series to adjust the power on the buzzer, thus adjusting the loudness. All in all, this is a pretty basic circuit, the real fun part begins at the coding section!
Writing the Arduino Code
I had a few ups and downs while figuring out the way the code should work for this project and I did a few revisions of the entire code along the way. Here I attached what I ultimately ended up with and I'll explain how it works and why I decided to have it work in such a way.
The main principle is as follows: each type of lightning is a seperate case inside the void NthStep(byte mode, byte brightness, byte stp) function. This function is the heart of the program so we should have a good look at it. It has 3 seperate cases based on the input 'mode', each coresponding to a different kind of lightning effect. The 'brightness' parameter adjusts the PWM duty cycle. Finally, the 'stp' parameter keeps track of the progress in cases where the lightning follows some sequence (for instance a rising and falling in brightness pattern). The dir parameter is related to the stp parameter, it changes from 0 to 1 and back every time stp reaches 256, again for the purposes of keeping track if the brightness should be increasing or decreasing.
Inside the void loop() function the NthStep function is called repeatedly. Every repetition the brightness and speed analog pins are measured, in case the potentiometers were turned. Since the NthStep function is called at least every 256 ms (due to the delay(light_spd) in line 155) it's fast enough most of the time to make the transition seem smooth to the human eye.
The other part of the void loop() function accounts for the possiblity that the two interrupt buttons were pressed. The interrupt functions are void mode_interrupt() and void pwr_interrupt() and they only change a boolean value or increase an integer, which is then read in the void loop(). The integer is then recalculated modulo 3 to always equal one of the 3 possible cases inside the NthStep function. This is following the paradigm that interrupt functions should be as minimal as possible. A nice Arduino interrupt tutorial is in the list of references bellow, explaining how to use them so I won't get into any of it here. I chose a FALLING interrupt with a PULLUP Arduino pin.
Finally, the stp number is increased and recalculated modulo 256 to ensure it's always the size of a byte, for the above described purposes.
The only thing left is the sound effects.There is quite some code writen but it really is quite simple. Firstly, the pitches.h file should be included at the beginning as well as placed inside the same folder as the Arudino code. Secondly, the melody notes and the melody note durations should be writen as two separate arrays. I found the notes online and I determined the note durations via trial and error by ear. Finally, each melody has its own function which iterates through all the notes in the given array and plays them for the required time. I refere you to the references at the bottom with a nice tutorial after which I modeled the sound effects in this project.
Finishing Up
After I was happy with the workings of my circuit and program on the breadboard I transfered the circuit to a solderable protoboard. At first I thought that I might be able to hide the circuit inside the keyboard, however it became obvious rather quickly that it wouldn't fit. So I designed an enclosure for the circuit board with space for the usb cable and a holder for the mail keyboard cable. I should note that I could have used the exposed usb power pins on the keyboard PCB to power the Arduino via the Vin pin, however I couldn't do that since the Vin pin (and a few others) on this specific Arduino are fried due to some...educational accidents I had done with this board in the past. I did however use the 5V pin to power the piezo buzzer and the LED strip. I know I could supply 5 volts to the 5V pin to power the Arduino however the voltage from the USB cable is higher and I didn't feel like risking anything.
Conclusion and References
I had fun and learnt a few useful things while making this project and I would very much recommend anyone to try something similar. This keyboard cannot in any way compete with a good name-brand RGB keyboard but it can make for a fun learning experience and a way better secondary keyboard for other computery projects.
It would be awesome to once make a real-time programable RGB keyboard through a computer UI (something like what Razer has) however it would take a lot more knowledge and work.
You can download all the related material on my github:
https://github.com/MaticMorgan/simple_RGB_keyboard
If you have any comments and questions, feel free to leave a commend or send me a message!
List of references:
Basic electronics: Light Emitting Diode. Aquired in november 2022 from https://lastminuteengineers.com/light-emitting-diode-led/
Arduino interrupt tutorial. Aquired in november 2022 from https://www.teachmemicro.com/arduino-interrupt-tutorial/
Super Mario Theme Song. Aquired in november 2022 from https://create.arduino.cc/projecthub/jrance/super-mario-theme-song-w-piezo-buzzer-and-arduino-1cc2e4