Una de las formas de evitar el uso de botones aparatosos en tus proyectos Arduino es utilizar placas o módulos con pines táctiles, como algunos módulos de ESP32.
Eso sí, la mayoría de placas no cuentan con esta característica, pero leyendo esta entrada en el foro de esp32.com di con algo interesante:
https://www.esp32.com/viewtopic.php?t=23066
Con una rápida calibración, se puede usar cualquier pin analógico como sensor táctil. Aunque hay varias librerías al respecto, realmente solo necesitas un par de funciones, así que vamos al grano!
Componentes
Para este proyecto voy a usar los siguientes compontentes:
- 1x Placa SparkFun Pro Micro con ATmega32u4
De hecho es un clon chino de Aliexpress muy barato.
https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro - 1x Cable USB micro de datos.
- 1x Diodo LED
- 1x Resistencia 1K o 220 Ohm
- 3x Cables puente
- 1x Placa de prototipos (protoboard)
Cableado
Si usamos la Pro Micro, esta es la asignación de pines:
Pro Micro | Componente |
---|---|
Puerto Micro USB | Cable USB |
Pin 21 (A3) | Cable puente desconectado |
Pin 20 | LED+ |
GND | Resistencia |
Solo debemos tener en cuenta que el cable puente que usaremos como sensor táctil deberá ir conectado a un pin analógico.
Sketch de Arduino
En mi github puedes encontrar un sketch de Arduino listo para usar:
https://github.com/TheRoam/TRW_AnalogTouch/blob/main/ProMicro_Blink_AnalogTouch.ino
Verás que indica "ProMicro", pero realmente es compatible con cualquier microcontrolador. Solo tienes que elegir tu placa en el menú de Herramientas.
La Pro Micro lleva un controlador ATMega32u4, que es compatible con la placa Arduino Leonardo.
Con esta configuración, compilamos el script y lo subimos a la placa.
Resultado
Abrimos el Monitor Serie, que debería aparecer en blanco ya que el texto de depuración está configurado al mínimo por defecto.
Ahora tocamos el extremo libre del cable puente y veremos cómo se ilumina el led, y cómo se detecta el "toque" en el Monitor Serie.
También verás que el script acumula los "toques" para poder utilizarlos en otros programas.
Al código
Brevemente explico lo que hace el programa:
- Durante el
setup()
, iniciamos la comunicación por serie, activamos el pin para el led, y rellenamos la matriz de lecturas analógicas con unas lecturas iniciales consetTouch
(Por defecto se leen 20 valores).
void setup() {
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
//enable LED pin
pinMode(LP,OUTPUT);
setTouch(TP);
}
- A continuación, pasamos a la función de ejecución continua
loop()
donde refrescaremos las lecturas al inicio de cada bucle.
setTouch(TP);
//------loop continues------//
void setTouch(int tp){
//fill up the array
for(int a=0;a<VALUES;a++){
mean[a]=analogRead(tp);
delay(10);
}
}
- Comprobamos si la depuración es mínima o extendida y ejecutamos el programa principal correspondiente (es el mismo, pero con mayor salida al Monitor Serie).
//run check
if(out==1){
extended(TP);
}else if(out==0){
minimal(TP);
}
- El programa principal:
- Recorre la matriz de lecturas,
- Obtiene la media de los valores,
- Obtiene una nueva lectura,
- Calcula la diferencia de tensión entre la última lectura y la media,
- Si el valor es mayor que la caida de tensión de referencia, se identifica "toque", se imprime por Monitor Serie, se suma al contador y se ilumina el led.
- Se restaura la media a 0, se apaga el led y se devuelve la variable de "toques".
int minimal(int tp){
//start reading values
for(int i=0;i<VALUES;i++){
//get average of array
for(int j=0;j<VALUES;j++){
avg+=mean[j];
}
avg=avg/VALUES;
//read current value
fin=analogRead(tp);
//compare average with current value
if((avg-fin)>REFV){
Serial.println("---------- T O U C H ----------");
//increase counter
touch++;
//print touch count
Serial.print("T: ");
Serial.println(touch);
//light led
ledON(LP);
//wait 1 second after touch detected
delay(1000);
}
//restart counter
avg=0;
//restart led
ledOFF(LP);
delay(VALINTERVAL);
}
return touch;
}
- Con esto se reinicia el bucle, volviendo al punto 2.
Otras configuraciones
El script cuenta con diversas variables de configuración que encontraremos en los '#define's
OUT
: define la cantidad de texto de depuración. Valor 0: mínimo; Valor 1: extendido.VALUES
: tamaño de la matriz de valores analógicos.TOUCHPIN
: definir el número del pin analógico a usar.LEDPIN
: definir el número de pin usado por el led.VALINTERVAL
: intervalo de evaluación en milisegundos.REFV
: valor de caida de voltaje (en milivoltios) que identifica un "toque".
// OUTPUT verbosity
// 1: extended --> Prints ADC array, mean value, touch count and touch message with touch count
// 0: minimal --> Prints touch message with touch count
#define OUT 0
// comparison variables
#define VALUES 20 //values for mean array
#define TOUCHPIN 3 //touch pin
#define LEDPIN 20 //led pin
#define VALINTERVAL 100 //evaluation interval
#define REFV 80 //reference voltage drop in mV
Calibración
Cambiando la configuración se puede calibrar el script para distintas placas. Con lo que he probado, esta es una buena secuencia:
- Define una REFV alta, por ejemplo 1000
- Carga el script con depuración extendida (OUT 1)
- Abre el Monitor Serie y observa los valores medios (Average: 230)
- Ahora, toca el cable puente y observa de nuevo los valores medios (Average: 170)
- Haz la resta entre las medias en 3. y en 4. (230-170=60).
- Define el REFV con este valor y calibra a partir de aquí.
- Para más sensibilidad, defínelo más bajo (50).
- Si es excesivo puede detectarse sin contacto. Auméntalo (80).
- Debido a la carga del CPU, REFV puede variar si hay depuración OUT 1 respecto a OUT 0. Busca un valor que funcione para OUT 0.
¿Te ha sido útil o tienes dudas? Deja tu comentario en 🐦 Twitter!