Cómo crear un interruptor táctil para usar con una Raspberry Pi

4

Estoy tratando de hacer mi propia lámpara de despertador. Tengo una lámpara con una gran base metálica para ocultar todos los componentes. También tengo un Velleman K8064 DC Controlled Dimmer Kit que tengo juntos y esta trabajando. Tengo un Raspberry pi para controlarlo todo (también planeo usar el Pi como un Android Dock)

Me gustaría que la base de la lámpara funcione como un interruptor táctil para encender y apagar la lámpara. Sin embargo, cuando lo probé, he probado el interruptor táctil que encontré en www.talkingelectronics.com . la lámpara está siempre encendida.

¿Alguien puede indicarme la dirección de un diagrama de cableado de un interruptor táctil más simple que funcionará con una frambuesa pi?

    
pregunta TheLukeMcCarthy

3 respuestas

6

Si tiene acceso de bajo nivel a los GPIO de Raspy, entonces hay una manera fácil de hacerlo, todo lo que necesita es un reisistor. Sí, has leído bien.

Simplemente conecte un pin a la base de la lámpara y ate la resistencia entre la base y \ $ V_ {cc} \ $, 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
}

¿Qué está pasando? En primer lugar, restablecer un temporizador. Debe ser rápido, algo así como un temporizador de CPU que se incrementa en cada ciclo de reloj o algo así.

Usted establece su pin como salida, le escribe un cero y luego espera a que realmente vaya a cero. Esto se puede hacer dentro de la escritura dependiendo del controlador / HAL que esté utilizando, pero para que esto funcione, no necesitará utilizar ninguno. Después de que el pin esté realmente a cero, configúrelo como entrada e inicie 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 se lee el voltaje a través de la capacitancia como una lógica alta, se detiene el temporizador: el truco es que si su dedo está presente, la capacitancia es más grande, por lo que la carga de la lógica requiere más tiempo. Presencia del dedo leyendo el temporizador.

¿Qué problemas podrías encontrar?
Bueno, tal vez no tengas un acceso de tan bajo nivel a los pines GPIO raspados ... Pero eso es algo que debes averiguar. Tal vez usted no tiene un temporizador de nivel tan bajo. El mayor problema es que tal vez la capacitancia de la base de la lámpara sea muy grande, por lo que tocarla no hará una gran diferencia.

De todos modos, vale la pena probar este método porque cuesta unos centavos. Acerca de la resistencia, usted desea algo que cargue la capacitancia lo suficientemente lenta para que su temporizador mida el tiempo que tarda, pero lo suficientemente rápido para poder muestrear el "botón" tal vez 20 veces por segundo. La lámpara más el cuerpo y el pin pueden estar alrededor de 1nF, usted quiere un \ $ \ tau = RC \ $ de aproximadamente 20 ms, por lo que $$ R = \ frac {\ tau} {C} = \ frac {20 \ cdot10 ^ {- 3} s} {1 \ cdot10 ^ {- 9} F} = 20M \ Omega $$ Bueno, eso es demasiado. Necesitará un temporizador rápido e irá por algo alrededor de \ $ 1M \ Omega \ $

¿Pero cómo funciona?
Todo lo que nos rodea tiene una capacidad con respecto a otra cosa. Es común referirse a la tierra como "algo más", por lo que todo tiene una capacidad con respecto a la tierra. Dicho esto, consideremos el siguiente circuito:

simular este circuito : esquema creado usando CircuitLab

\ $ C_ {in} \ $ es la capacitancia de entrada del puerto digital más la capacitancia de la base de la lámpara hacia la tierra, generalmente alrededor de 100pF, mientras que \ $ C_H \ $ (como en "humano") es la capacidad que tenemos hacia suelo. Cuando tocas la base de la lámpara, cierras el interruptor etiquetado como "tocar", mientras que la frambuesa solo puede actuar en \ $ SW_ {in} \ $. Comienzas con \ $ SW_ {in} \ $ closed, entonces \ $ V_ {C_ {in}} = 0 \ $. Cuando la frambuesa abre \ $ SW_ {in} \ $, la capacitancia de entrada comienza a cobrar a \ $ V_ {cc} \ $ a través de \ $ R_p \ $ con un costante de tiempo \ $ \ tau = R_p \ cdot C_ {in} \ PS La ley V (t) es bastante conocida: $$ V_ {C_ {in}} (t) = V_ {cc} (1-e ^ {- \ frac {t} {\ tau}}) $$ La frambuesa detectará una entrada alta cuando el voltaje alcance algo alrededor de \ $ \ frac {2} {3} V_ {cc} \ $, por lo que tomará:

$$ t_ {ALTO} = \ tau \ ln \ Big (\ frac {V_ {cc}} {V_ {cc} - \ frac {2} {3} V_ {cc}} \ Big) = \ tau \ ln (3) $$

En este punto, detendría el temporizador y comprobaría cuánto tiempo tardó: si es algo alrededor de \ $ 1.1 \ tau \ $ no se produce ningún toque. La frambuesa cerraría \ $ SW_ {in} \ $ y esperaría a que se descargue el condensador, es decir, esperando que el pin lea cero, para finalmente abrir el interruptor y comenzar de nuevo.
Pero, ¿qué pasa si cerramos \ $ SW_h \ $? Bueno, \ $ \ tau \ $ cambia: \ $ \ tau '= R_p \ cdot (C_ {in} + C_H) \ $ ahora, y si \ $ C_ {in} \ $ es lo suficientemente pequeño, y espero que lo sea, \ $ tau '\ $ incluso podría ser diez veces más grande que \ $ \ tau \ $. La frambuesa iniciará su temporizador, pero ahora tardará bastante más en leer una entrada alta:

$$ t '_ {HIGH} = ... = \ tau' \ ln (3) \ approx 10 \ cdot \ tau \ ln (3) = 10 \ tau $$

La relación segunda a última es una especie de relación "esperamos que sea verdad". Cuando la frambuesa finalmente lea una entrada alta, detendrá el cronómetro y dirá que eso toma bastante tiempo, ¡encendamos 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, pero esa sería una forma poco confiable de encender la lámpara. Por lo que puedo leer, su sistema está funcionando de manera bastante aleatoria ... Pruébelo de la manera adecuada.

    
respondido por el Vladimir Cravero
1

Gracias a Vladimir por su respuesta que me permitió encontrar esta solución.

simular este circuito : esquema creado usando 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 sostener la placa táctil luego de entre 5 y 12 detecciones de un toque, el toque no se detectará por un tiempo y luego se volverá a detectar. Dado que solo lo uso para una lámpara táctil, la solución es lo suficientemente buena para mis necesidades.

    
respondido por el TheLukeMcCarthy
1

Esto parece funcionar sin retraso (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 ;
}
    
respondido por el Mmc Dispenser

Lea otras preguntas en las etiquetas