Buenas!
Hace años hice una libreria que decodifica mandos a distancia chinos analizando los pulsos, y estoy queriendo optimizarla por eficiencia y sobre todo velocidad de ejecucion.
En resumidas cuentas:
-un pulso con un duty de alrededor de 25% se considera un CERO
-un pulso con un duty de alrededor de 75% se considera un UNO
-un pulso con un duty de alrededor de 3,125% se considera el fin de la trama de pulsos (SYNC).
Otra forma de verlo es:
-CERO: 1 frame high, 3 frame low
-UNO: 3 frame high, 1 frame low
-SYNC: 1 frame high, 31 frame low
El mando a distancia envia 24 pulsos con CEROS o UNOS, y un ultimo pulso de SYNC.
Tengo un receptor RF conectado al pin de INT_EXT y cada vez que hay un flanco ascendente o descendente el PIC interrumpe y "registra" los tiempos.
En los flancos ascendentes comienza un nuevo pulso y pone el timer a 0
En los flancos descendentes guarda el tiempo del pulso (HighDuration)
En un nuevo flanco ascendente guarda el tiempo total del pulso (TotalDuration)
Con la siguiente formula obtengo el "duty" del pulso:
Duty = ((int32)HighDuration * 100) / TotalDuration;
Para darle un poco de margen no establezco un valor exacto para el duty, sino que pongo un rango de valores validos:
#define MIN_ZERO 15
#define ZERO 25 //teorico
#define MAX_ZERO 35
#define MIN_ONE 65
#define ONE 75 //teorico
#define MAX_ONE 85
#define MIN_SYNC 1
#define SYNC 3.125 //teorico
#define MAX_SYNC 5
Para saber si mi pulso es un CERO, UNO, SYNC o RUIDO lo paso por estos IF:
/* PULSO SYNC */
if((MIN_SYNC <= Duty) && (Duty <= MAX_SYNC)){
...
}
/* PULSO CERO */
else if((MIN_ZERO <= Duty) && (Duty <= MAX_ZERO)){
...
}
/* PULSO UNO */
else if((MIN_ONE <= Duty) && (Duty <= MAX_ONE)){
...
}
/* RUIDO */
else{
...
}
En resumen, mido cada pulso y luego lo paso por unos IF para ver si encaja en alguno y asi saber de que se trata.
Pero tanto la multiplicacion y division de int32, asi como la multitud de IFs me parece que hacen que sea un codigo muy poco optimo.
Funciona bien, pero creo que lo podria exprimir bastante mas.
Creo que calcular el duty en un valor de 0 a 100 (base 10) es algo innecesario, y seguramente trabajar en base 2 lo haria mucho mas optimo.
Al mismo tiempo los IF con > y < puedan evitarse o abreviarse.
Se os ocurren algunos truquitos de optimizacion?
Si quereis ver el codigo entero lo tengo en github:
https://github.com/ideaalab/rf_libraryGracias por la ayuda!