Mi intención es dedicar unas cuantas entradas a explicar la implementación si aprecio que existe algún interés ya que es mas trabajoso explicarlo que hacerlo. Últimamente los proyectos de cacharreo astronómico nacionales son muy escasitos...Y no: AVR != Arduino.
LX200 es un protocolo, propiedad de fabricante de equipamiento astronómico
Meade Instruments, cuyo objeto es el control de telescopios astronómicos.
Adopta el modelo
cliente-servidor ,siendo el dispositivo cliente generalmente un PC ,o Tablet ,el cual ejecuta software de planetario o adquisición de imágenes.
El servidor suele esta implementado en el firmware del telescopio(montura).
En otros casos puede implementarse parcialmente un traductor en el lado del cliente como se hacia con la versión estándar de
PicGoto.
Esto sería una conversación de inicio de sesión típica con su traducción al español :
Cliente: :Ga:#:Gt# (¿Donde estás?)
Servidor: +36*50#-002*50# (En Almería.)
Cliente:::Sg +36*43#:St-004*12# (Eso fue ayer.Ahora estás en Benajarafe.)
Servidor 1 (vale)
Cliente::SL23:15:00# (Son las once y cuarto.)
Servidor 1 (vale)
Cliente:::
gT#(
Te enciendo el GPS por si no te fías.)
Servidor: 1 (Gracias,Ya estoy orientado.)
Cliente: :GR#:GD# (¿Donde estás apuntado? )
Servidor: :05:15:10#-08*11'14# (A las coordenadas del Rigel.)
Cliente : :Sr13:26:48#:Sd-47*29'00# (Te paso las coordenadas de omega centauri.)
Servidor: 00 (Está bajo el horizonte , prepara el
detector de neutrinos.)
Cliente : :MS# ¡
Apunta allí ahora !
Servidor: 1 (No, paso, lo del detector era broma ,no apunto ni loco, que me rompo)
Se puede consultar el conjunto completo de comandos y respuestas en
LX200
El objetivo es implementar un
intérprete de
LX200;n o por gusto,sino porque es el protocolo más extendido y por estar lo suficientemente mal diseñado como para que tenga sentido emplear un lenguaje de especificación de
maquinas de estado finito como
Ragel .
Frente a otras herramienta muy extendidas como
Lex o, el código generado es lo suficientemente ligero y rápido para ser usado con microcontrolador y pequeños sistemas embebidos.
El compilador de
Ragel genera código sin dependencias de librerías externas en
C,D,Java o Ruby.
Las ventajas sobre programar directamente dicha máquina de estados en C son varias:
- Se usan expresiones regulares para describir la maquina y sus componentes.
- Se asocian acciones (trozos de código nativo) a las transiciones entre estados
- Es mas fácil de mantener, ampliar modificar y corregir.
- Puede generar diagramas gráficos de máquina que facilitan el análisis y la detección de errores.
El digrafo siguiente es la representación gráfica generada a partir de la maquina de estado que esta descrita en el bloque de código posterior. Es una implementación minimalista del protocolo
LX200 incluyendo comandos básicos de apuntado,guiado,puesta en hora,sincronización ...
Aunque cacho de código
Ragel siguiente parezca un truño infumable, lo es mucho menos que su implementación directa en
C.
%%{
machine command;
write data;
}%%
%%{
#Acciones
action getgrads {ADD_DIGIT(deg,fc); }
action getmin {ADD_DIGIT(min,fc); }
action getsec {ADD_DIGIT(sec,fc); }
action neg { neg=-1;}
action dir {move(stcmd);}
action Goto {GOTO;}
action stop {;}
action rate { RATE;}
action return_ra { lxprintra(mount.current_ra);}
action return_dec {lxprintde( mount.current_dec);}
action return_ra_target { lxprintra(mount.ra_target);}
action return_dec_target {lxprintde( mount.dec_target);}
action return_sid_time { ;}
action sync {mount.current_dec=mount.dec_target;
mount.current_ra=mount.ra_target;
rprintf("synced#");}
action settargetra { set_target_ra( deg,min, sec);}
action settargetde { set_target_de( deg,min, sec,neg);}
action rafrac {deg+=(fc-'0')*6;}
action return_local_time { ltime();}
action set_cmd_exec {set_cmd_exe(stcmd,(neg*(deg )));}
action addmin {deg=deg*3600+min*60;}
action addsec {deg+=sec;}
action storecmd {stcmd=fc;}
#definicion gramática LX terminos auxiliares
sexmin = ([0-5][0-9])$getmin@addmin ;
sex= ([0-5][0-9] )$getsec@addsec;
deg =(([\+] | [\-]@neg) | digit @getgrads) (digit @getgrads){2} "ß" sexmin ([:\'] sex)? ;
RA = ([0-2] digit) $getgrads ':' sexmin ('.'digit@rafrac | ':' sex) ;
#Definicion gramática comandos
Poll= 'G'( 'R'%return_ra | 'D'%return_dec |'r'%return_ra_target | 'd'%return_dec_target | 'L'%return_local_time |'S'%return_sid_time);
Move = 'M' ([nswe]@storecmd %dir | 'S'%Goto);
Rate = 'R' [CGMS] %rate;
Set='S' (([dazgt]@storecmd ' 'deg ) | ([rLS]@storecmd ' ' RA))%set_cmd_exec ;
Sync = "CM"%sync;
Stop ='Q' (''|[nsew])@storecmd %stop;
main := (':' (Set | Move | Stop|Rate | Sync | Poll)) '#' ;
# Initialize and execute.
write init;
write exec;
}%%
Lo he compilado con AVR-GCC para un ATMEGA128L y pasa como un telescopio verdadero para la implementación ASCOM de LX200.
(continuará)