Touchless Keypad: DIY Capacitive Proximity Sensors With Aluminium Foil & Capacitive Sensing Library
by Ernest Nga in Circuits > Arduino
3152 Views, 9 Favorites, 0 Comments
Touchless Keypad: DIY Capacitive Proximity Sensors With Aluminium Foil & Capacitive Sensing Library
Touch interfaces such as elevators buttons can potentially aid in the transmission of pathogens. Inspired by the COVID-19 pandemic, I decided to build a prototype of touchless keypad. By implementing Arduino Capsense Library, capacitive proximity sensors are made with aluminium foil and high value resistors. As this setup normally functions as a touch sensing device, several modifications are implemented to increase the sensor's sensitivity for proximity sensing, which will be highlighted in this article.
How Does It Work?
A finger, which has high dielectric properties, is able to increase the capacitance. If the capacitance of a RC circuit is higher, the time taken to charge or discharge is longer, which can be detected by Arduino. It is recommended that you read this article (https://playground.arduino.cc/Main/CapacitiveSensor/) which explains the mechanism and library methods in details.
Tools & Materials
(1) Arduino UNO
(2) Breadboard
(3) 10M Ohm Resistors × 11
(4) Male-to-male/Male-to-female connector x 11
(5) Male-to-male connectors × 13
(6) Aluminium foil
(7) OLED display
(8) Standing calendar
(9) Scissor and cellophane tape
(10) Stripping pliers (optional)
Attaching Aluminium Foil
Sketch the outline on the calendar. Use a small screw (or something sharp) to make a small hole. After stripping the insulator off the wire, attach the exposed wire to the aluminium foil.
Note: As Arduino UNO has a limited number of input pins, only 11 out of the 12 foil pieces can be used as capacitive sensors. You will be able to cover every digit from 0 to 9, and an extra input to clear/delete.
Wiring & Attaching OLED Display
Further details and explanation on how to use an OLED module can be found in https://randomnerdtutorials.com/guide-for-oled-display-with-arduino/
Code
#include <CapacitiveSensor.h> const byte howManySensors = 11; // total number of capacitive sensor input int sensorsVal[howManySensors]; // declare an array to store all input const byte threshold = 200; // Setting a threshold based on your observation // 10 megohm resistor between pins 13 & 12, pin 12 is the receiver pin, add wire, foil // multiple sensors can share the same sender pin 13 CapacitiveSensor cs_13_12 = CapacitiveSensor(13,12); CapacitiveSensor cs_13_11 = CapacitiveSensor(13,11); CapacitiveSensor cs_13_10 = CapacitiveSensor(13,10); CapacitiveSensor cs_13_9 = CapacitiveSensor(13,9); CapacitiveSensor cs_13_8 = CapacitiveSensor(13,8); CapacitiveSensor cs_13_7 = CapacitiveSensor(13,7); CapacitiveSensor cs_13_6 = CapacitiveSensor(13,6); CapacitiveSensor cs_13_5 = CapacitiveSensor(13,5); CapacitiveSensor cs_13_4 = CapacitiveSensor(13,4); CapacitiveSensor cs_13_3 = CapacitiveSensor(13,3); CapacitiveSensor cs_13_2 = CapacitiveSensor(13,2); /** Setting Up OLED Display **/ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); void setup(){ // set autocalibration cs_13_12.set_CS_AutocaL_Millis(5000); cs_13_11.set_CS_AutocaL_Millis(5000); cs_13_10.set_CS_AutocaL_Millis(5000); cs_13_9.set_CS_AutocaL_Millis(5000); cs_13_8.set_CS_AutocaL_Millis(5000); cs_13_7.set_CS_AutocaL_Millis(5000); cs_13_6.set_CS_AutocaL_Millis(5000); cs_13_5.set_CS_AutocaL_Millis(5000); cs_13_4.set_CS_AutocaL_Millis(5000); cs_13_3.set_CS_AutocaL_Millis(5000); cs_13_2.set_CS_AutocaL_Millis(5000); Serial.begin(9600); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); } delay(2000); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0, 10); // Display static text display.println(F("Initialising...")); display.display(); } void loop(){ // The intended number should correspond to the index number // Match the correct physical pin "cs_xx_xx.capacitiveSensor()" to the correct index // Index 0 --> number 0, Index 1 --> number 1, and so on // Index 10 --> an extra button sensorsVal[0] = cs_13_11.capacitiveSensor(130); sensorsVal[1] = cs_13_2.capacitiveSensor(130); sensorsVal[2] = cs_13_3.capacitiveSensor(130); sensorsVal[3] = cs_13_4.capacitiveSensor(130); sensorsVal[4] = cs_13_5.capacitiveSensor(130); sensorsVal[5] = cs_13_6.capacitiveSensor(130); sensorsVal[6] = cs_13_7.capacitiveSensor(130); sensorsVal[7] = cs_13_8.capacitiveSensor(130); sensorsVal[8] = cs_13_9.capacitiveSensor(130); sensorsVal[9] = cs_13_10.capacitiveSensor(130); sensorsVal[10] = cs_13_12.capacitiveSensor(130); // return error when it takes too long int maxVal = 0; // To find the max value of sensorsVal[] array byte maxValIndex = 0; // To find the index of the max value of sensorsVal[] array for(byte i = 0; i < howManySensors; i++){ /** // UNCOMMENT THIS TO DEBUG // use serial plotter to choose a threshold value Serial.print(sensorsVal[i]); Serial.print("\t"); **/ // To find the max value of the array if(sensorsVal[i] == -2){ maxVal = sensorsVal[i]; //locate timeout condition break; } else if(sensorsVal[i] > maxVal){ maxVal = sensorsVal[i]; maxValIndex = i; } } Serial.print("\n"); if(maxVal > threshold){ Serial.println(maxValIndex); oledDisplay(maxValIndex); delay(500); // to prevent multiple entries } else if(maxVal == -2){ // CapacitiveSensor returns -2 when there is timeout due to bad connection oledDisplay(255); delay(500); } delay(10); // arbitrary delay to limit data to serial port } void oledDisplay(byte val){ display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(25, 5); // Display static text display.println(F("The number is:")); if(val == 10){ // clear number display.display(); } else if (val == 255){ // sending error message display.setCursor(0, 20); display.println(F("Connection error")); display.display(); } else{ // display the number display.setTextSize(5); display.setCursor(53, 20); display.println(val); display.display(); } }<br>
You'll need to install the Capacitive Sensor Library by Paul Badger. You may also wish to download the relevant library for the OLED display.
Final Product
The following methods are used to improve the sensitivity & accuracy
(1) set_CS_AutocaL_Millis(5000)
Re-calibration is set at a 5-second interval
(2) capacitiveSensor(130)
By experimenting, the optimum sampling rate is found to be 130. You may wish to try different values.
(3) Ground plate
To improve grounding, a large piece of aluminium foil is mounted on the sides of calendar, which is connected to the ground pin of Arduino. Refer to the note on the second diagram.