Control de tiempo dentro de un bucle: envío de datos a intervalos exactos [cerrado]

0

Tenemos un programa donde enviamos datos de forma inalámbrica a través de GPRS. Recuperamos valores de los ADC, hacemos nuestros cálculos, los mostramos en la pantalla y también los enviamos a servidores remotos. El bucle puede ser considerado como este

while(1)
{
  _ReadADC();
  _LCD_Display();
  _DoCurrentCalcultions();
  _SendCurrentData();  /* I want to send this data exactly every minutes */
}

El problema al que me estoy enfrentando en este momento es que, en ocasiones, los datos no se envían con éxito, por lo que hay saltos, pero eso no es lo que me preocupa.

Quiero poder enviar datos exactamente cada vez, por ejemplo. 11:00:00, 11:01:00, 11:02:00 tenga en cuenta que el segundo valor permanece igual, solo que el valor de los minutos cambia. Ahora no tengo el reloj en tiempo real (RTC) en mi tablero, pero definitivamente tengo temporizadores. Lo que estoy pensando es que debería dar un tiempo de holgura en mi bucle y, si los cálculos toman más o menos tiempo, debo ajustar ese tiempo en la holgura y enviar datos precisamente cada minuto.

Cómo puedo hacer eso, ha pasado mucho tiempo desde que hice la programación de sistemas integrados.

    
pregunta engineer

2 respuestas

2

Necesitas usar un temporizador periférico. Configúralo para generar una interrupción cada minuto. La interrupción debe establecer una bandera global (recuerde hacerla volátil). El bucle principal sondea la bandera y comprueba si ha transcurrido un minuto, borra la bandera, prepara los datos y los envía.

Si no puede configurar el temporizador para hacer intervalos de minutos, intente configurarlo en intervalos de un segundo, también configure un indicador en el controlador de interrupciones (el nombre es, por ejemplo, newSecond ). El bucle principal solo tiene que borrar la bandera, incrementar un contador y, cuando llegue a 60, preparar los datos para enviar (y restablecer el contador).

    
respondido por el filo
0

1) En primer lugar, GPRS es un servicio de mejor esfuerzo, por lo que su latencia es variable. Puedes intentar todo lo que quieras para lograr una precisión de tiempo, pero si el ancho de banda no está disponible, todo sería en vano.

2) Hay dos patrones preferidos para aplicaciones como la tuya:

  • En el patrón de ahorro de energía , el dispositivo se queda dormido entre el muestreo / envío. Se utiliza un temporizador externo de nano-poder o un watchdog interno para generar un evento de activación. Tenga en cuenta que el período de activación puede ser más pequeño que el período de envío requerido, lo que le brinda a su código la oportunidad de preparar los datos con anticipación y enviarlos inmediatamente después de que se active un cierto temporizador.
  • En precisión , el bucle principal lee constantemente el ADC y usa el exceso de muestreo / promedio móvil para contrarrestar las fluctuaciones del ADC. Esto le deja con el valor actualizado con frecuencia que puede utilizar para sus cálculos en cada muestra o en algunos intervalos. La interrupción de un temporizador externo o interno se utiliza para activar el procedimiento de envío, lo que hace que el período de envío sea independiente del código de cálculo. Esto requiere un soporte de administración de tareas algo complejo porque no es una buena idea hacer un procesamiento largo en la función de interrupción en sí. Una variante más simple de esto sería afirmar el indicador de "tiempo para enviar" en la interrupción y salpicar su código de larga duración con llamadas al procedimiento "verificar el indicador y enviar cuando esté listo".

3) En ambos patrones arriba se usa la interrupción del temporizador. El temporizador externo cuidadosamente elegido le puede dar una gran precisión fuera de la caja, pero complica los esquemas. Dada la naturaleza incierta de GPRS, la precisión de los temporizadores MCU internos debería ser suficiente. Las hojas de datos de MCU generalmente incluyen una descripción detallada del procedimiento de calibración para RTC, que es ideal para este propósito.

4) Ningún temporizador es preciso . Incluso un muy buen temporizador externo con base de cristal tendrá alguna desviación. Esta es exactamente la razón por la que sugerí los temporizadores MCU internos en primer lugar, ya que son lo suficientemente precisos durante un cierto período de tiempo . A la larga, puede utilizar su conexión GPRS para la sincronización del reloj. El más simple sería el servicio NITZ cuando esté disponible en el proveedor actual. Sin embargo, si tiene conexión a Internet, puede intentar usar NTP también.

5) Finalmente, asegúrese de que esto no sea un problema XY. Pregúntese lo siguiente: ¿desea enviar datos a tiempo fijo solo porque necesita saber cuándo se obtuvieron? En caso afirmativo, la marca de tiempo de preparación simple en los datos permite que se envíen a intervalos irregulares, eliminando la dependencia de la latencia GPRS y el tiempo de cálculo. Aún necesita un temporizador preciso para firmar sus datos, pero, de lo contrario, su código puede hacer cálculos y enviar resultados sin restricciones de tiempo.

    
respondido por el Maple

Lea otras preguntas en las etiquetas