Suponiendo que desea utilizar una interrupción para muestrear cada milisegundos n y que su uC se ejecuta en un reloj mucho mayor, puede ajustar el tiempo de espera de la interrupción a la señal recibida.
La mayoría de los sistemas no sincronizados utilizan un esquema de sobremuestreo entre 8 y 32 muestras por bit. Como muchas implementaciones de hardware UART.
No sé cómo se ve la señal, pero si hay un patrón de bits conocido, como un código de inicio en algún lugar, puede comenzar a muestrear en el primer borde de esa condición de inicio, luego si el número de muestras es alto o bajo que espera que llegue + o - 20%, asume que es la condición de inicio y ajusta el tiempo de espera para la compensación. Cuantas más mediciones hagas, más precisa será tu afinación.
Sin embargo, esto es sensible a las condiciones de inicio que no ocurren también en un flujo de datos en curso. Si alguna transmisión siempre contiene bits del tamaño de 100 ms, vuelve a ser fácil. Elija alto o bajo y cuando ese nivel comience, comience a contar.
Supongamos que tiene 20 conteos por bit (tiempo de espera de 5 ms), si cuenta 38 conteos bajos (según su elección), sabe que su reloj no se apagará en un 45%, por lo que supone que vio 2 bits bajos y su reloj se ejecuta rápido por 2/40 = > 5% y se ajusta el prescaler de interrupción o reloj en consecuencia. Por lo general, el reloj se desplaza lentamente, de esta manera, siempre sabrá cómo decodificar los bits (ya que está realizando un exceso de muestreo con un margen grande) y puede sintonizar su decodificador a la señal continuamente.
Esto es, en efecto, una especie de Soft-PLL, que se ejecuta solo en el supuesto de que su reloj uC tenga una precisión de al menos el 20% (los últimos RC de uC son los predeterminados de fábrica en todo el rango VCC) y que su señal entrante sabe mejor.
EDITAR:
Si su módulo maneja bajo y alto y en una entrada digital, el ruido recibido en la transición de un bit a otro técnicamente nunca es más que una muestra en una señal de baja frecuencia. Por lo tanto, si usa 5 muestras por bit, estadísticamente tiene 4 muestras confiables por bit, debe estar apagado en un 20%, eso deja 3. Eso debería estar bien, pero está en el borde, puede elegir al menos 8 muestras, pero de nuevo, cuanto mayor sea su precisión de sintonización será. Es solo un intercambio entre interrupciones. Pero si su uC se ejecuta en un 1MHz miserable, cada 5 ms sigue siendo maní en términos de interrupción de código.