Encienda y deje que el LED permanezca encendido si el valor está por encima del umbral en el ciclo de tiempo principal

4

Estoy totalmente atascado con este problema bastante trivial (?), tengo este pseudo código que convertiré a C (estoy programando un MCU ATmega8):

Include libraries
Threshold = 40 //Celsius

While true
    Temp = Read_temp_from_sensor()

    If Temp > Threshold
         Turn on LED
    Else
         Turn off LED

¿Hay alguna manera de hacer que el LED permanezca encendido durante el ciclo While, pero solo mientras la lectura de temperatura del sensor sea superior al valor de umbral?

Supongo que no quiero evaluar los valores en el bloque If / Else en cada ciclo, ¿estoy en el camino correcto aquí?

    
pregunta mikejoh

2 respuestas

4

Esto es exactamente lo que haces: evalúas si / else en cada ciclo. Su código es básicamente correcto, solo tiene un defecto: si la temperatura está cerca del umbral, su LED parpadeará rápidamente, ya que las lecturas de temperatura estarán por encima de 40 y por debajo de 40 un poco. Puede que no quieras eso. Para evitar esto, debe implementar histéresis : debe superar algunos márgenes de temperatura para encender o apagar el LED. Algo como esto:

Threshold = 40 //Celsius
Hysteresis = 1
While true
    Temp = Read_temp_from_sensor()

    If Temp > Threshold + Hysteresis
         Turn on LED
    Else If Temp < Threshold - Hysteresis
         Turn off LED

Es posible que desee considerar apagar el microcontrolador entre ciclos de bucle, utilizando interrupciones del control de vigilancia para activarlo en intervalos de tiempo iguales.

    
respondido por el miceuz
3

Su pseudocódigo (junto con la histéresis miceuz explicada en su respuesta) debería funcionar bien. A veces, dependiendo de su requerimiento, la histéresis puede no ser necesaria, ya que un LED parpadeante es bueno para lo que quiere hacer. Es un requisito un tanto inusual, pero surge de vez en cuando.

Me gustaría señalar, sin embargo, que hacer esto en el bucle principal podría ser problemático en algunos casos de uso. Si el bucle en sí es largo o está lleno de llamadas de bloqueo (por ejemplo, una función de lectura en serie que se devuelve solo después de que se recibe un mensaje), esto podría causar un retraso en la respuesta de los LED. Si el tiempo de respuesta es importante para usted, puede asegurarse de que el bucle principal se ejecute dentro de un período inferior al tiempo de respuesta deseado.

Hay soluciones alternativas disponibles. Posiblemente son demasiado complicados para ser más que un interés académico para aplicaciones simples, pero nunca se sabe cuándo necesitaría más.

  • Ejecute el código LED como una función que se ejecuta periódicamente, nuevamente con un período más corto que el tiempo de respuesta deseado. Esta 'función' podría activarse desde una interrupción, o en sistemas mucho más complicados, como una tarea en un sistema operativo en tiempo real.
  • Si la función de obtener temperatura está usando el ADC, en su lugar, podría configurar el ADC como un comparador si no le importa cuál es la temperatura real (o tal vez use un canal separado del ADC como un comparador, que es << em> think el AVR permite), y use la interrupción del comparador para disparar el LED. Esto no requeriría una verificación regular y esencialmente garantizaría una respuesta muy rápida.
  • Si el umbral también se usará para algún tipo de corte de seguridad, o para activar una ráfaga de medición rápida de ADC en la que está intentando detectar algo que ocurre justo después (algo así como un disparador de osciloscopio), puede valga la pena pasar por alto el AVR por completo y usar un comparador real. Son baratos, fáciles de usar, rápidos y se pueden conectar a uno de los interruptores de cambio de pin AVRs (llamado interrupción externa en el mega8).
respondido por el Chintalagiri Shashank

Lea otras preguntas en las etiquetas