Introduction: Arduino Guitar Jack Key Holder With Jack Recognition & OLED
Intro:
This instructable will detail the build of my Arduino based Guitar Jack plugin key holder
This is my first ever instructable so please bear with me as I may make changes / updates along the way
Step 1: Parts & Tools
Most of the parts I purchased from Amazon.co.uk or eBay, some I had kicking around already - Here is a list of what you'll need.
Amazon links are all Affiliate links, you may be able to find cheaper elsewhere - I use Amazon Prime a lot, so Amazon just happened to be my go-to.
I wanted to keep this build fairly low-cost and budget friendly. You could use a bigger TFT screen is you so wished, as well as a different Arduino. Do not use a NANO, as it will crash due to high memory usage. The code uses about 72% of the Pro Micro's RAM and is stable, but from testing, a NANO will crash and freeze.
(More details in the Code step.)
PARTS
1x Arduino Pro Micro - https://amzn.to/2UeDt2K
1x 0.96" OLED with Yellow & Blue Display - https://amzn.to/2PaLyo3
4x WS2812 'Pixels' - https://amzn.to/2XcTMir
1x DS3231 RTC - https://amzn.to/2VGq8BP
4x 1/4" Mono Jack (Or as many as you want) - Amazon (Gold) or Amazon (Silver) or eBay.co.uk
1x Mixed Resistor Pack - https://amzn.to/2v0IaCZ
4x 1/4" Guitar Jacks - https://amzn.to/2KwX9iA
1x Micro USB Cable Extension Cable - https://amzn.to/2v4x6Vs
4x M3 Screws
TOOLS & MATERIALS
- Soldering Iron (This is the one I bought - a TS100 - as it came with additional tips https://amzn.to/2VLoY80)
- Solder
- Hot Glue Gun (https://amzn.to/2UTd9PN)
- Wire (https://amzn.to/2VK2ILU)
- Wire cutters / strippers (https://amzn.to/2KzqUzp)
- 3D Printer or 3D Printing service
OPTIONAL - These items are optional, depending on how you choose to connect everything up
- Veroboard / Stripboard (https://amzn.to/2KzMFPE)
- Screw Terminal Connectors (2 Pole | 3 Pole | 4 Pole)
- PCB Headers (https://amzn.to/2X7RjWf)
Step 2: 3D Printing the Case
I printed mine on my Creality CR-10S, using Black PLA+ (https://amzn.to/2X2SDtE)
I printed at 0.2 layer height, with 25% infill.
Step 3: Putting It All Together + Schematic
How you choose to connect your Arduino is entirely up to you - I personally chose to make myself a "shield" so to speak. To make the shield, I've soldered female headers to veroboard to match the Pro Micro, I then added a rail of +5v and GND, at opposite ends. I've used jumper wire to connect the +5v to my now 5v 'rail', and did the same for the GND. I then added my 4x 100k resistors, one end connected to +5v for all of them, and then the other side connects to A0, A1, A2 & A3 respectively. I've then added screw terminals to analog pins A0, A1, A2 & A3 and also Pins 2 (SDA), 3 (SCL) & 4
Measure out your wiring and cut to appropriate lengths. I started with the WS2812 Pixel LEDs first - the FIRST WS2812 LED connects to +5v from the Arduino, GND from the Arduino, and DIN connects to Pin 4. After this, the remaining 3 are chained together, chaining all the 5v > 5v, GND > GND pins and DOUT from one Pixel, connects to DIN of the next. Once soldered, Press these gently into the square holes in the top, and hot glue in place and also to protect the rear from any accidental connections or shorts.
After the LEDs, I then screwed in the Guitar Jack Sockets. One pin of each connects to GND, and then the 2nd pin of each connects to A0, A1, A2 & A3 accordingly. So that's Socket 1, to A0, Socket 2 to A1, Socket 3 to A2, and Socket 4 to A3.
Next I soldered 4 wires to the OLED connections, and trimmed down any excess solder as much as possible. You want to attach your wires from the rear of the screen, so you're soldering to the front of the screen.
Pay attention to the pins! Some OLEDs have GND on the outside, then VCC, some have VCC on the outside, and then GND
Once soldered and you've trimmed or flatted down the solder connection as much as possible, gently press the screen into it's location. It's a bit of a tight fit by design, but be aware that different print tolerances may affect this and so you might have to do some minor post-processing to make it fit. Once in place, place some hot glue across each of the 4 corners to hold it in place.
Connect everything up to match the Schematic and pictures, and once happy, you can then hot glue the Pro Micro and RTC Clock in place too, and then connect the USB extension to the Pro Micro.
I used a micro USB extension so that a) the USB can be used to provide power, but more so, b) so that it was possible to reprogram the Pro Micro if needed without pulling everything apart
Once happy, screw the case together using the 4 screws
Step 4: The Plugs!
The way this works, is that, for all intents and purposes, part of the design works as an "ohmmeter". An ohmmeter is an instrument for measuring electrical resistance. Most Multimeters have this function whereby you pick the scale and then measure a resistor to find its value. The working principal is that you connect a KNOWN resistor to the +ve, which is then connected to an UNKNOWN resistor, which connects to -ve. The joint between the 2 resistors connects to the Arduino analog pin so that it can read the voltage and calculate the resistance.
It works like a voltage divider and calculates the resistance of the unknown resistor.
As a voltage divider network of resistors R1 and R2,
Vout = Vin * R2 / (R1 + R2 )- We are using 100k for our known (R1) resistor. This gives us the "voltage drop"
From this, we can now work out the resistance of the unknown (R2) resistor,
R2 = Vout * R1 / (Vin – Vout) - where R1 is our 100k (100,000 ohm) resistor
By using a a different resistor in each plug jack you wish to use, you can then adjust the code accordingly dependant on the jack in use.
I am using 4 jack plugs. I opted to use:
Known Resistor (x4) - 100k
Jack Plug 1 - 5.6k
Jack Plug 2 - 10k
Jack Plug 3 - 22k
Jack Plug 4 - 39k
You could of course expand this, and code in as many as you'd like.
Step 5: The Code
Firstly, you will need the Arduino IDE, available from here: https://www.arduino.cc/en/Main/Software
You will also need to make sure you have a few Arduino Libraries too:
Adafruit NeoPixel: https://github.com/adafruit/Adafruit_NeoPixel
u8g2: https://github.com/olikraus/u8g2
Adafruit RTCLib: https://github.com/adafruit/RTClib
Adafruit SleepyDog (Optional): https://github.com/adafruit/Adafruit_SleepyDog
A note about choosing the right "Arduino" board. Originally I started this project with an Arduino Nano, because they're super cheap at about £3-£4 in the UK, or as little as £1.50 if you purchase from AliExpress (but don't mind the 30-50 day wait). The problem with the Nano is that it's SRAM is 2 KB (2048 bytes). This sketch uses 1728 bytes of dynamic memory with Global Variables. That's 84% of the SRAM, leaving just 320 bytes free for local variables. This was insufficient and would cause the Nano to lock up and freeze.
The Pro Micro (Leonardo) has 2.5K SRAM (2560 bytes), which means there's 694 bytes free for local variables (The sketch uses 72% of the Pro Micro's SRAM). So far this has proved perfectly adequate and stable for my usage. If you intend to use many jack plugs, then you may wish to consider using something with more SRAM.
As far as Flash storage is concerned, this sketch uses 88% (25252 bytes) of 30k (The ATMega328p [Nano] and ATMega32u4 [Pro Micro] both have 32k, but 2k is reserved for the bootloader)
I've written hundreds of Arduino sketches over the years, but I'm a hobbyist - so bear in mind some parts of the code may be inefficient or there may be "better ways of doing this" scenarios. That being said, it's working perfectly for me and i'm happy with it. I used libraries that SHOULD work on most boards, whether it's AVR (most basic Arduino's) or SAMD21 (I have a handful of Cortex M0 devices)
I wanted to display a different graphic based on the jack used as well. If you want to make your own, this is a brilliant simple guide on how to create the C Array for images to be used with this display:
Make sure to use PROGMEM for your graphics. Eg:
static const unsigned char YOUR_IMAGE_NAME[] PROGMEM = { }
By design, the screen will "timeout" after 5 seconds and revert to displaying the time.
Most of the Settings can be found in Settings.h, specifically, the name of the associated jack plugs are coded here:
#define PLUG1 "KEYS" #define PLUG2 "P2" #define PLUG3 "P3" #define PLUG4 "P4" #define GENERIC "NA"
There is also some important parts of code inside Variables.h
float R1=96700.0; float R2=96300.0; float R3=96500.0; float R4=96300.0;
These are the KNOWN resistance values, in ohms, of each of the 4 resistors.
R1 connected to A0, R2 to A1, R3 to A2, and R4 to A3.
It is advisable to measure your 100k resistors using a multimeter and use the exact value of the resistor. Take the measurement of the resistor once everything is connected up. (But not powered on).
When choosing resistors for your jack plugs, make sure there's a good ohm gap between them, and when coding them, give yourself a nice range lower and higher than your chosen resistor. Here is what I used in my code:
float P1_MIN=4000.0, P1_MAX=7000.0; // 5.6K float P2_MIN=8000.0, P2_MAX=12000.0; // 10K float P3_MIN=20000.0, P3_MAX=24000.0; // 22K float P4_MIN=36000.0, P4_MAX=42000.0; // 39K
The reason for this is to account for the analog reading and the minor voltage fluctuations etc
So what happens is, if the detected resistance is between 4000 ohms and 7000 ohms, we're presuming you've used a 5.6k resistor and thus the code will see this as Jack Plug 1. If the measured resistance is between 8000 ohms and 12000 ohms, the assumption is that it's a 10k resistor and is Jack Plug 2 and so on.
If you need to do some debugging (Don't leave uncommented in 'production' since serial debugging uses up precious ram) simply uncomment the lines you require at the top of Settings.h
//#define SERIAL_DEBUG //#define WAIT_FOR_SERIAL
To uncomment, simple remove the // .... to comment the line back out, re-add the // to the front of the line.
SERIAL_DEBUG enables the serial debugging and the use of things such as (for example)
Serial.println(F("hello world"));
WAIT_FOR_SERIAL is an additional step, that means, until you open the Serial Monitor, the code won't continue. This helps ensure you don't miss any important serial messages. - NEVER LEAVE THIS ENABLED
If you do leave WAIT_FOR_SERIAL enabled, you won't be able to use the your key holder in any "real world" environment as it will be stuck waiting for the Arduino IDE Serial monitor before it can continue into the main loop of the sketch. Once you've completed your debugging, make sure you uncomment this line again, and re-upload your sketch for production/completion.
When using the SERIAL_DEBUG option, my code contains the following:
#ifdef SERIAL_DEBUG Serial.print(F("ACTIVE JACK = ")); Serial.println(ACTIVE_JACK); int len = sizeof(SOCKET_1234_HAS_PLUGTYPE_X)/sizeof(SOCKET_1234_HAS_PLUGTYPE_X[0]); for (int i=0;i<len;i++) { Serial.print(F("SOCKET_1234_HAS_PLUGTYPE_X[")); Serial.print(i); Serial.print(F("] = ")); Serial.println(SOCKET_1234_HAS_PLUGTYPE_X[i]); } Serial.println(); if (INSERTED[socket]) { Serial.print(F("Plug in socket ")); Serial.print(socket+1); Serial.print(F(" has a resitance of: ")); Serial.println(resistance); } #endif
The last Serial.print line will tell you what the resistance is, in ohms, of the last inserted jack. So you can also use this sketch as an ohmmeter of sorts to check the resistance of a jack plug.
Attachments
Step 6: Notes
I think I've covered everything, but please do comment and I will do my best to read and reply when I can :)
Apologies for the somewhat poor video - I don't have a tripod, recoding setup or a proper working space so to speak so this was filmed (badly) holding the phone in one hand and trying to demo it with the other.
Thanks for reading.
Step 7: Changelog
13th April 2019
- Published