¿Cómo podría programar un interruptor (basado en un relé de estado sólido o un triac) que se dispara con potencia de cruce por cero?
Para aquellos que no están familiarizados con el tema: encienda la alimentación de 230 V cuando la onda sinusoidal de la línea de alimentación cruza el cero; el resultado es minimizar las perturbaciones electromagnéticas resultantes de un pico rápido en la corriente.
Específicamente, preferiría moverme tanto al software como sea posible. El circuito de detección que consiste en un pequeño transformador, un diodo y un par de resistencias para mantener controlados los niveles y las corrientes proporciona "1" cuando la potencia de entrada de CA está en la mitad positiva, "0" en negativo, conectado a un pin GPIO de entrada. La salida consta de unos pocos relés de estado sólido y elementos esenciales para mantenerlos en funcionamiento (pull-ups, etc.), conectados a los pines GPIO de salida.
El problema es el tiempo: con 50 Hz de CA obtenemos 100 cruces por cero en un segundo, un medio ciclo es de 10 ms. Para estar a una distancia razonable del cruce por cero para mantener dicho EMI bajo, no debemos activar la salida más del 10% después (o antes) del evento de cruce por cero, eso significa tolerancia + -1ms. Eso no significa un tiempo de reacción de 1 ms: podemos esperar razonablemente que el próximo cruce por cero ocurra exactamente 10 ms después del primero, o el cuarto - 40 ms. Se trata de granularidad: si permitimos 20 ms para la reacción, debe ser entre 19 y 21 ms, no 18 o 22.
¿Cómo puedo implementar dicho temporizador? GPIO de salida de disparo, ya sea dentro de 1 ms desde que la entrada detecta un borde, o dentro de un múltiplo fijo de 10 ms desde entonces, preferiblemente con margen para algunos sesgos negativos (por ejemplo, el transformador y el relé introducen un retraso de 1.6 ms; así que quiero que el disparador salga 8.4+ (n * 10) ms desde el pulso de entrada, de esa manera el sesgo contrarresta el retraso introducido por el circuito.) - por supuesto "a pedido del usuario", digamos, el usuario escribe "1 "a un archivo / sys / class / ... y en la oportunidad más cercana (más o menos) la salida se" enciende ". El usuario escribe "0", y cuando llega el cruce por cero, el relé específico se desactiva.
Creo que esto requeriría escribir o piratear un módulo del núcleo. ¿Podría indicarme qué maneja los pines GPIO de Raspberry Pi en el núcleo, y qué tipo de temporizadores podría adjuntarle (a menos que ya existan algunos) para obtener este tipo de funcionalidad?
Respuestas:
No necesitas hackear el kernel. Solo necesita mover el proceso fuera de la cola del planificador.
De ahora en adelante, nuestro proceso recibe
cat /proc/sys/kernel/sched_rt_runtime_us
milisegundos de cadacat /proc/sys/kernel/sched_rt_period_us
segmento de tiempo de milisegundos, de ejecución ininterrumpida sin riesgo de ser adelantado durante ese tiempo (en la práctica, por defecto en BerryBoot: 0.95s por segundo). Si necesita más, lío con estos valores, pero no necesito más para mi propósito aquí.Estoy usando una función de temporizador en milisegundos (es decir, la precisión que necesito) en función
clock_gettime()
de registrar mis retrasos.Las llamadas se
timer(1)
restablecen, las llamadastimer(0)
devuelven el tiempo desde el reinicio.Debe realizar un enlace contra la
rt
biblioteca para que esto se compile: agregue-lrt
a su comando gcc.Ahora, para el bucle principal. Estoy usando una entrada de interruptor para "solicitud del usuario" pero puede usar la red, el temporizador o lo que sea. Todo lo que necesitas es obtener el valor booleano
in
.fuente
TRIAC_PIN
ain
, tendría que establecer elTRIAC_PIN
1, esperar una cantidad determinada de tiempo (en proporción a nivel de atenuación deseado) y luegoTRIAC_PIN
vuelva a establecer 0. ¿Funcionaría?if(in==out) continue;
aif(out==0) continue;
, ¿verdad? En realidad, soy totalmente nuevo en la programación para pi, así que tal vez eso no sea necesario. Supongo que todo esto está sucediendo sincrónicamente (es decir, no tenemos que preocuparnos de que se llame al bucle principal mientras los bucles anidados todavía se están ejecutando)