Estoy tratando de hacer mi propia lámpara de despertador. Tengo una lámpara con una base de metal grande para ocultar todos los componentes. También tengo un kit de atenuación controlada por CC Velleman K8064 que armé y funciona. Tengo una Raspberry pi para controlarlo todo (también planeo usar la Pi como base de Android)
Me gustaría que la base de la lámpara funcione como un interruptor táctil para encender y apagar la lámpara. He intentado probar un interruptor táctil que encontré en www.talkingelectronics.com , sin embargo, cuando lo pruebo, la lámpara siempre está encendida.
¿Alguien puede señalarme la dirección de un diagrama de cableado de un interruptor táctil más simple que funcionará con una frambuesa pi?
Si tiene acceso de bajo nivel a los GPIO ásperos, entonces hay una manera fácil de hacerlo, todo lo que necesita es un resistor. Sí, leíste eso bien.
Simplemente conecte un pin a la base de la lámpara y ate la resistencia entre la base y , ese es el riel de 3.3V, recuerde que los pines no son tolerantes a 5 voltios.
Aquí está en pseudocódigo lo que necesita hacer del lado del software:
while(1) {
timer.reset()
gpiox.direction = GPIO.OUT
gpiox.write(GPIO.LOW)
while(gpiox.read != GPIO.LOW)
gpiox.direction = GPIO.IN
timer.start()
while(gpiox.read == GPIO.LOW)
timer.stop()
out = timer.read()
if (out > THRESHOLD)
pressed = true
else
pressed = false
}
¿Lo que está sucediendo? En primer lugar, reinicia un temporizador. Tiene que ser rápido, algo así como un temporizador de CPU que se incrementa en cada ciclo de reloj más o menos.
Configura su pin como salida, escribe un cero en él y luego espera a que realmente llegue a cero. Eso se puede hacer dentro de la escritura dependiendo del controlador/HAL que esté usando, pero para que esto funcione, no necesitará usar ninguno. Después de que el pin es realmente cero, lo configura como una entrada y comienza el temporizador. La capacitancia parásita de la base de la lámpara y la entrada del pin y, si está presente, su dedo comienza a cargarse a través de la resistencia. Cuando el voltaje a través de la capacitancia se lee como una lógica alta, detiene el temporizador: el truco es que si su dedo está presente, la capacitancia es mayor, por lo que lleva mucho más tiempo cargar la lógica, por lo que puede decir el presencia de los dedos leyendo el temporizador.
¿Qué problemas podría encontrar?
Bueno, tal vez no tengas un nivel tan bajo de acceso a los pines ásperos de GPIO... Pero eso es algo que debes averiguar. Tal vez no tengas un temporizador de tan bajo nivel. El mayor problema es que tal vez la capacitancia de la base de la lámpara sea muy grande, por lo que tocarla no supondrá una gran diferencia.
De todos modos, vale la pena probar este método porque cuesta unos centavos. Acerca de la resistencia, desea algo que cargue la capacitancia lo suficientemente lento como para que su temporizador mida realmente el tiempo que lleva, pero lo suficientemente rápido como para poder probar el "botón" tal vez 20 veces por segundo. La lámpara más el cuerpo más el pin pueden estar alrededor de 1nF, desea un de unos 20 ms por lo que
pero como funciona?
Todo lo que nos rodea tiene una capacitancia con respecto a otra cosa. Es común referirse a tierra como "algo más", por lo que todo tiene una capacitancia con respecto a tierra. Dicho esto, consideremos el siguiente circuito:
simular este circuito : esquema creado con CircuitLab
es la capacitancia de entrada del puerto digital más la capacitancia de la base de la lámpara hacia tierra, generalmente alrededor de unos 100pF, mientras que (como en 'humano') es la capacidad que tenemos hacia el suelo. Cuando toca la base de la lámpara, cierra el interruptor con la etiqueta 'toque', mientras que la frambuesa solo puede actuar sobre . empiezas con cerrado, entonces . Cuando se abre la frambuesa la capacitancia de entrada comienza a cargarse a través de con una constante de tiempo . La ley V(t) es bastante conocida:
En este punto, detendría el temporizador y verificaría cuánto tiempo tardó: si hay algo alrededor
no se está produciendo ningún contacto. La frambuesa cerraría
y esperar a que se descargue el capacitor, es decir, esperar a que el pin marque cero, para finalmente abrir el interruptor y comenzar de nuevo.
Pero y si cerramos
? Bien,
cambios:
ahora, y si
es lo suficientemente pequeño, y con suerte lo es,
incluso podría ser diez veces más grande que
. La frambuesa iniciará su temporizador, pero ahora llevará mucho más tiempo leer una entrada alta:
La penúltima relación es una especie de relación "esperamos que sea verdad". Cuando la frambuesa finalmente lea una entrada alta, detendrá el temporizador y dirá, bueno, eso lleva bastante tiempo, ¡cambiemos la luz para mi programador! Y eso es todo.
¿Y por qué funciona tu solución?
Eso es porque tu cuerpo está actuando como una antena. Básicamente, está alimentando la frecuencia de la red en el pin de entrada de la frambuesa, y eso puede hacer que la entrada se lea como una sola, pero esa sería una forma poco confiable de alternar su lámpara. Por lo que puedo leer, su sistema está funcionando de manera bastante aleatoria... Inténtelo de la manera adecuada.
Escribí una implementación en C (ver más abajo) basada en el pseudocódigo en la respuesta de Vladimir .
Funciona de maravilla en mi Pi Zero W, lo estoy usando para alternar la luz de fondo de una pantalla LCD tocando su bisel. Utilicé una resistencia de 1 MΩ, que tarda ~20 μs en cargarse cuando está inactiva y entre 45 y 110 μs cuando se toca. Incluso puede sentir el tacto a través del revestimiento no conductor del bisel, por lo que la RasPi debe protegerse de descargas estáticas.
Hasta ahora no he tenido ningún problema con toques repetidos que no se detecten.
// Filename: touch_toggle.c
/* Compile with gcc -lwiringPi touch_toggle.c -o touch_toggle
* Run with sudo ./touch_toggle
* Do not touch while starting the program so it can initialize properly
*/
/* SCHEMATIC
*
* ,----------------------,
* | Raspberry Pi |
* | |
* | TOUCH_PIN VCC |
* `-----+-------------+--'
* | |
* +---[1MΩ]-----+
* |
* Touch surface
*
*/
#include <wiringPi.h>
#include <stdio.h>
// Note: Pin numbers are in BCM notation (pin number format is set by wiringPiSetupGpio)
// See pinout.xyz
#define TOUCH_PIN 20
#define OUTPUT_PIN 21
// How long to pull the touch pin low
// Controls loop speed and affects CPU usage
#define DELAY 15
int main(void) {
wiringPiSetupGpio();
unsigned int timer;
unsigned int threshold = 0;
unsigned char state = 0; // Currently being touched?
unsigned char out_state = 0; // State of output pin
signed char hysteresis = 0; // Counter for consecutive readings
pullUpDnControl(TOUCH_PIN, PUD_OFF); // Not sure if this would ever be set, just to be safe
pinMode(OUTPUT_PIN, OUTPUT);
digitalWrite(OUTPUT_PIN, out_state);
// Measure capacitance to calibrate touch sensitivity
for (char i=0; i < 10; i++) {
// Pull touch pin low to discharge
pinMode(TOUCH_PIN, OUTPUT);
digitalWrite(TOUCH_PIN, LOW);
// Wait a bit
delay(DELAY);
// Start timer
timer = micros();
pinMode(TOUCH_PIN, INPUT);
// Wait for pin to become high
while (!digitalRead(TOUCH_PIN));
// Get time elapsed
threshold += micros() - timer;
}
// Set threshold to twice the average capacitance
threshold /= 5; // This number might need to be increased if the touch is not sensitive enough
printf("threshold=%d\n",threshold);
while (1) {
pinMode(TOUCH_PIN, OUTPUT);
digitalWrite(TOUCH_PIN, LOW);
delay(DELAY);
timer = micros();
pinMode(TOUCH_PIN, INPUT);
while (!digitalRead(TOUCH_PIN));
timer = micros() - timer;
if (timer > threshold) {
if (hysteresis < 0) hysteresis = 0;
hysteresis++;
} else {
if (hysteresis > 0) hysteresis = 0;
hysteresis--;
}
// 3 consecutive readings are required to toggle touch state
if (hysteresis > 2) {
if (state == 0) {
out_state = !out_state;
digitalWrite(OUTPUT_PIN, out_state);
state = 1;
// Print when touch starts and the measured value
// Can be commented out
printf("START %d", timer);
fflush(stdout); // Display instantly (by default only flushed on newline)
}
hysteresis = 0;
} else if (hysteresis < -2) {
if (state == 1) {
state = 0;
printf(" END\n");
}
hysteresis = 0;
}
}
return 0;
}
Código también en: https://pastebin.com/FrsYCtXu
Gracias a Vladimir por su respuesta que me permitió llegar a esta solución.
simular este circuito : esquema creado con CircuitLab
El código de Python es el siguiente
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
touchSwitch = 23
outputPin = 24
GPIO.setup(touchSwitch, GPIO.IN)
GPIO.setup(outputPin, GPIO.OUT)
GPIO.output(outputPin, False)
while True:
switchTouched = GPIO.input(touchSwitch)
if switchTouched:
print "touch detected"
time.sleep(0.3) # sleep again here so not to toggle the lamp to quickly
else:
print "not touched"
time.sleep(0.15) # 0.10 seems to give the best results but 0.15 uses less CPU
El problema con esta solución es que, al sujetar la placa táctil después de entre 5 y 12 detecciones de un toque, el toque no se detectará durante un tiempo y luego se volverá a detectar. Dado que solo lo estoy usando para una lámpara táctil, la solución es lo suficientemente buena para mis necesidades.
Esto parece funcionar sin demora (usando el circuito de TheLukeMcCarthy pero con GPIO 18 como entrada y GPIO 17 como pin de salida)
#include <wiringPi.h>
int main (void)
{
register unsigned char on = 0 ;
wiringPiSetup () ;
pinMode ( 1, INPUT) ;
pinMode ( 0, OUTPUT) ;
pinMode ( 4, OUTPUT) ;
digitalWrite ( 4, LOW) ;
digitalWrite ( 0, LOW) ;
while ( 1 )
{
if ( digitalRead (1) )
{
if ( on )
{
on=0;
digitalWrite ( 4, LOW) ;
}
else
{
on=1;
digitalWrite ( 4, HIGH) ;
}
delay ( 300 ) ;
}
delay ( 50 ) ;
}
return 0 ;
}
lukemccarthy
vladimir cravero
lukemccarthy
lukemccarthy
vladimir cravero
lukemccarthy
vladimir cravero
vladimir cravero