ejecutando múltiples bucles simultáneamente

0

Intenté google, youtube, stackexchange pero no pude encontrar una respuesta adecuada. Estoy tratando de diseñar un sistema domótico con arduino que necesite controlar un ventilador y una luz. Simplemente activar un relé con arduino no es una cosa, pero aquí está el problema. También estoy controlando la velocidad del ventilador. Así que aquí está la estructura básica del código.

si el pin 1 es alto

[

identifique el punto de cruce por cero de la fuente de corriente alterna;

agregue un poco de retraso para regular la potencia de salida;

pulsa al triac;

activar el relé relacionado con el ventilador;

]

si el pin 2 es alto

[

activar el relé relacionado con la luz;

]

Cuando el pin 1 está alto, el bucle comienza a ejecutarse y permanece dentro del bucle hasta que el pin 1 está bajo. luego busca el estado del pin 2 [alto o bajo]. Entonces, la pregunta es cómo controlo la luz mientras el ventilador está encendido. Muchos foros están sugiriendo temporizadores pero ninguno en este tipo de situación. Si es posible, por favor indique un código mínimo, para que pueda comenzar desde eso. Gracias.

    
pregunta Raj Kiran

1 respuesta

0

Si desea hacer cosas con un bucle, entonces necesita cambiar las cosas para que la repetición del bucle se rija por el ciclo de red síncrono que se repite. Esta no es la forma más limpia de hacer las cosas, pero debería ser posible para que funcione.

Tenga en cuenta que solo hay una cosa lenta de controlar, el control de velocidad de cambio de fase del ventilador. Puede acomodar muchas otras cosas 'rápidas', leer un interruptor, configurar un relé, dentro del tiempo que demora esperar el siguiente cruce por cero.

while running:
    {
    wait_for_zero_crossing();
    read_fan_speed_control();
    compute_speed_to_delay_for_fan();
    delay_for_fan_speed_control_time();
    pulse_fan_triac();

    set_fan_relay();    
    read_light_control();
    set_light_relay();    
    ...    
    read_other_control();
    set_other_relay();
    }

Un método bastante mejor es usar interrupciones. Cuando tiene una tarea sincrónica como esperar los ciclos de la red, y una tarea asíncrona como leer los interruptores, es bueno usar interrupciones para manejar la parte crítica del trabajo, como esta. En general, usted desea que la rutina de servicio de interrupción (ISR) se ejecute lo más rápido posible, es decir, realice el menor trabajo posible. Mientras se gasten unos pocos ciclos fuera del ISR, se ejecutará su código asíncrono.

volatile int fan_control;      # needed so main and ISR communicate correctly

setup_ISR_to_run_every_100uS;  # for instance, 10kHz

while running:
    {
    read_fan_speed_control();
    fan_control = compute_speed_to_delay_for_fan();
    read_light_control();
    set_light_relay();
    ...
    read_other_control();
    set_other_relay();
    }

ISR:
    {
    if zero_crossing_just_happened():
        count = 0;
    else:
        count += 1;
    if count == fan_control:
        pulse_fan_triac();
    ...
    if count == other_control:
        pulse_other_triac();
    }

Como puede ver, es fácil ampliar esta sección de ISR para acomodar fácilmente otros canales de control de cambio de fase. Dejaré como implementar zero_crossing_just_happened() como un ejercicio para el lector.

Estos fragmentos son bocetos, obviamente mucho se ha omitido. He mostrado la declaración volatile ya que a menudo se olvida en estas situaciones. Obliga al compilador a volver a leer el valor de la memoria en cada lectura y no a intentar optimizarlo utilizando una copia basada en registros.

Una vez que haya aprendido a usar interrupciones, puede usarlas para escanear un dispositivo multiplexado, capturar datos de ADC en segundo plano, todo tipo de cosas que no puede hacer bien con un solo bucle asíncrono.

    
respondido por el Neil_UK

Lea otras preguntas en las etiquetas