Estoy trabajando en un proyecto que envía datos en serie para controlar la animación de luces LED, que deben estar sincronizadas con un motor de animación. Parece que hay un gran buffer serial de escritura (OSX (POSIX) + FTDI chipset usb serial device), por lo que sin estrangular manualmente las llamadas a write(), el software puede adelantarse varios segundos a las luces.Serial: write() throttling?
Actualmente estoy restringiendo manualmente la velocidad de escritura en serie a la velocidad de baudios (8N1 = 10 bytes en serie por 8 bytes de datos, 19200 bps en serie -> 1920 bytes por segundo como máximo), pero tengo un problema con la animación Sin sincronización con las luces a lo largo del tiempo, comienza bien, pero después de 10 minutos hay un desfase notable (100ms +) entre la animación y las luces.
Este es el código que se restringe la velocidad de escritura en serie (llamada una vez por cuadro animación, 'transcurrido' es la duración de la trama actual, 'velocidad de transmisión' es el bps (19200)):
void BufferedSerial::update(float elapsed)
{
baud_timer += elapsed;
if (bytes_written > 1024)
{
// maintain baudrate
float time_should_have_taken = (float(bytes_written)*10)/float(baudrate);
float time_actually_took = baud_timer;
// sleep if we have > 20ms lag between serial transmit and our write calls
if (time_should_have_taken-time_actually_took > 0.02f)
{
float sleep_time = time_should_have_taken - time_actually_took;
int sleep_time_us = sleep_time*1000.0f*1000.0f;
//printf("BufferedSerial::update sleeping %i ms\n", sleep_time_us/1000);
delayUs(sleep_time_us);
// subtract 128 bytes
bytes_written -= 128;
// subtract the time it should have taken to write 128 bytes
baud_timer -= (float(128)*10)/float(baudrate);
}
}
}
Claramente, hay algo mal, en alguna parte.
Un enfoque mucho mejor sería poder determinar el número de bytes actualmente en la cola de transmisión, y tratar de mantenerlo por debajo de un umbral fijo, pero no puedo encontrar la manera de hacerlo en un OSX (Sistema POSIX).
Cualquier consejo apreciado.
sincronización a través de buffers es algo que POSIX es generalmente mal adaptado para manejar; Los primeros intentos de audio y video sincronizados en todos los sistemas operativos de los consumidores son un buen ejemplo de lo malo que es. Puede que tenga que escribir en el UART de serie directamente o buscar o escribir un controlador que permita ioctls plesiócronas como "emitir este byte no antes de tiempo _n_. – msw
¿Tiene control sobre el motor de animación? –
¿Se ha corregido la velocidad de fotogramas de la animación? –