ESPECIFICACIÓN SDL MANIPULADOR ELECTRÓNICO
INTRODUCCIÓN
La llave telegráfica se le ha denominado en castellano, tradicionalmente, manipulador. Manipular vine del latín manipulare y en su acepción de nombre, manipulador, en el diccionario de la RAE viene la siguiente definición "Aparato destinado a abrir y cerrar el circuito en las líneas telegráficas".Para evitar confusiones entre manipulador llave y manipulador electrónico, keyer en inglés, vamos a referirnos como manipulador simplemente al circuito electrónico y como llave al dispositivo que abre y cierra el circuito para que el manipulador genere la secuencia de puntos y rayas a velocidad constante.
El manipulador se puede hacer con lógica discreta, bastante complicada, un circuito específico o con un microprocesador o microcontrolador. En este último caso en el que se va a usar programación en lugar de lógica cableada es donde viene a ser necesario usar una especificación clara y concisa que permita escribir un código que cumpla a rajatabla con la especificación.
Hay muchas formas de hacer una especificación, pero para programación viene muy bien usar SDL. Es un lenguaje gráfico que es fácil leer, tiene translación directa a código, C, PASCAL, ensamblador... y hay herramientas que permiten validar la especificación antes de tirar una sola línea de código.
Por esta razón he dedicado un tiempo considerable a diseñar un manipulador que cumpla con los modos más usados, IAMBICO A, B y ULTIMATIC. La ejecución final sobre un circuito concreto será objeto de otro trabajo, pero puede ser una placa Arduino si se consigue montar una multitarea por interrupciones o un microprocesador cualquiera que disponga de varias entradas de interrupción, temporizadores, etc.. que nos permitan montar un sistema multitarea para ejecutar este código.
SDL puede funcionar de forma secuencial, pero su gran potencia viene de ser un lenguaje que permite trabajar con sistemas operativos multitarea y aunque en este caso solo hay una tarea, lo que no exige disponer de un SO multitarea, los mensajes son asíncronos y pueden surgir en cualquier momento y por tanto no es posible usar lazos tipo do whyle para temporizadores ya que se perderían eventos y el funcionamiento dejaría de ser correcto.
Hecha la introducción vamos a desgranar la especificación que está divididos en dos grandes grupos, el autómata y las funciones que son invocadas desde los distintos estados del autómata según surjan los eventos.
EVENTOS DE ENTRADA
Un manipulador de este tipo solo tiene sentido si se una una llave de dos palas. Por tanto hay 4 eventos posibles, pulsar una u otra pala y liberar una u otra pala. Estos 4 eventos se envían al sistema mediante un mensaje en el que se codifica cada evento. Por tanto hay un mensaje tipo pala cuyos argumentos serán la pala afectada, izda o dcha y el estado de ésta, pulsada o liberada.Cada acción desencadenada por un cambio de estado de las palas lleva asociado de alguna manera una temporización, por tanto hay dos mensajes asociados a la temporización. Uno de salida para fijar el temporizador necesario y otro de entrada al sistema para indicarle qué temporizador ha desbordado o finalizado. Tenemos pues, un mensaje de salida SetTimer y otro de entrada TimeOUT.
Además de fijar temporizadores se tiene que interactuar con la electrónica para abrir o cerrar el circuito que va a generar el símbolo correspondiente. Esto se hace mediante un mensaje de salida cKey y cMute. Vamos a distinguir entre poner en emisión el circuito con el mensaje cKey y bloquear el audio con cMute.
El sistema requiere de ciertas conflagraciones y para ello vamos a usar un mensaje de entrada ConfigKeyer. Como respuesta a los cambios de conflagración y para monitorizar el funcionamiento del sistema hay una serie de mensajes específicos a pantalla que deberán de tratar de forma especifica, ignorándolos si no son útiles, en la solución física que se realice.
La figura adjunta resume el sistema y los interfaces con el exterior.
Partimos de un estado inicial en el que el autómata estará en estado de reposo, las palas liberadas y los temporizadores parados. Este es el estado INICIO y se llega a él tras la inicialización de variables.
En el estado inicio se atiende solamente a mensajes de las palas, temporizador de fin de emisión y mensajes de configuración. Los mensajes de configuración son ignorados en el resto de los estados ya que no tiene sentido modificar el comportamiento del manipulador mientras se está procesando algún símbolo, está pulsada alguna llave o hay algún temporizador en curso.
Por rápido que pulsemos ambas palas, siempre llegará antes una que otra aunque solo sea por una cuestión de precedencia que se haya establecido en la solución electrónica, prioridad de las interrupciones HW, muestreo, etc. Así que nunca llegará un mensaje que diga que se han pulsado o liberado ambas palas a la vez.
Empezaremos por el mensaje de configuración:
Este mensaje puede traer el estado del modo QSK, WPM, MODO, WSPACE o WTTORX.
- QSK puede valer 0 (QSKOFF) no QSK o 1 (QSKON) si QSK.
- WPM es un valor numérico entre 8 y 50 palabras por minuto.
- MODO puede valer IAMBA (1) o IAMBB (2) o EULTIMATIC (3).
- WSPACE puede valer WSPACEON (1) o WSPACEOFF (0).
- WTTORX es un valor numérico de espera de final de emisión.
En este estado se está a la espera que se pulse alguna pala. Si estuviera pulsada alguna de ellas se ignoran los eventos que puedan producirse hasta que no estén liberadas ambas palas.
Por tanto a la recepción de un mensaje Pala se analiza en al función TransicionaINICIO.
Lo primero que se hace al entrar en la función TransicionaINICIO es analizar el mensaje de las palas mediante al función AnalizaPala. A la salida comprobamos el estado de las palas, si ambas palas están pulsadas o ambas están liberadas, se sale de esta función con la variable SEC (Símbolo En Curso) a cero. De lo contrario, solo una de las palas está pulsada, se sale de esta función con la variable SEC en PUNTO y la memoria de pala punto borrada o RAYA y la memoria de la pala raya borrada. Además se llama antes de salir a la función TX, que genera un mensaje de emisión que deberá ser tratado por el HW adecuadamente.
La función AnalizaPala valora qué acción se ha hecho. Qué pala se ha pulsado o liberado qué pala se ha pulsado primero, si es el caso y memoriza el estado de las palas en las variables de estado. La salida de esta función deja las variables de estado de acuerdo a la acción que se ha recibido en el mensaje.
La ficción TX se encarga de fijar los temporizadores en función de si el símbolo a emitir es un punto o una raya y genera el mensaje correspondiente de emisión.
En el caso que no tengamos activo el modo QSK se genera un temporizador extra con el tiempo de espera para RX, de tal forma que la señal cMute se quitará cuando venza este tiempo si no hay otro evento intermedio que reinicie el temporizador.
La solución HW tiene que tener en cuenta también que otras restricciones deban tenerse en cuenta, pero en general el manipulador entrega una señal de abre/cierra circuito a ritmo de la velocidad programada en palabras por minuto y de acuerdo al orden de pulsar/liberar las palas de la llave conectada al manipulador.
La salida de la función TransicionaINICIO da paso al análisis del la variable SEC. Si al analizar las palas se vio un estado no previsto SEC == 0, por tanto se mantiene el autómata en el estado INICIO. SEC == PUNTO, se produce un cambio de estado a estado PUNTO o si SEC == RAYA, se produce un cambio de estado al estado RAYA. En estos dos cambios de estado se han generados los mensajes de emisión y se han lanzado dos temporizadores, uno que determina el tiempo que dura la emisión del símbolo, PUNTO o RAYA y otro que determina al duración del símbolo y eventualmente también está en curso un temporizador TIMTORX de espera a RX cuyo valor es WTTORX.
Llegado a este punto se ha pulsado una pala válida, se han desencadenado las acciones que facilitan la emisión del símbolo correspondiente y se ha cambiado al estado correspondiente. Seguimos el análisis por el estado PUNTO, que funcionalmente es idéntico al estado RAYA.
En el estado PUNTO pueden suceder solo dos tipos de eventos, venza un temporizador de los que están en curso o cambie el estado de las palas. Un cambio en el estado de las palas puede ser, liberar la pala PUNTO ya que estamos en este estado por haberse pulsado previamente la pala punto o pulsar la pala RAYA, sin haber liberado la pala punto. Este mensaje se analiza como ya se vio anteriormente. El resultado del análisis del estado de las palas se memoriza su estado, pero no se produce cambio de estado del autómata puesto que hay un símbolo en curso y éste tiene que acabar previamente. Por tanto, en este estado se aceptan los cambios de estado de las palas pero se memorizan para su posterior tratamiento. Por ejemplo, si se libera la pala punto hay que esperar a que acabe la emisión del símbolo para cambiar al estado que corresponda una vez acabe la emisión del punto.
Bien, los temporizadores en curso a tener en cuenta son dos, el temporizador TIMERTX y SIMBOLO. El primero siempre acabará primero. Por tanto cuando acaba el temporizador TIMERTX se ejecuta la función RX y nos mantenemos en el estado.
La función RX simplemente pasa el circuito de salida a estado abierto, pero se controla también la señal cMute.
Si QSK == 1, entonces controlamos la señal cMute, en caso contrario solo la señal cKey.
Una vez vence el temporizador SIMBOLO hay que ver lo que se tiene que hacer en función del estado de las palas. Como ya se dijo, el estado de las palas está memorizado ya que se analizó el posible mensaje que se produjo mientras se está emitiendo el símbolo. Los estados de las palas pueden ser 4, ambas liberadas, ambas pulsadas, punto o raya pulsada. Por ejemplo, mientras se emite el punto podemos haber liberado la pala de punto y seguidamente pulsado la pala de raya, esta operación se ha memorizado y por tanto la podemos estudiar ahora que ha acabado la emisión del símbolo.
- Ambas palas pulsadas: se emite el símbolo contrario al que está en curso, en este caso una raya mediante la función TXR. Analizamos si estamos en modo ULTIMATIC, en tal caso pasamos al estado ULTIMATIC y en caso contrario se pasa al esta IAMBIC. En ambos tipos de manipulador la primera vez que se detecta que ambas palas están pulsadas se pasa a emitir el símbolo contrario. En lo que difieren estos dos manipuladores es cómo se trata las repeticiones mientras están pulsadas ambas palas. En modo IAMBIC se alternan puntos y rayas y luego al liberar ambas palas hay una ligera diferencia entre el modo A y B del manipulador IAMBIC. En manipulador ULTIMATIC lo que hace es emitir de forma continua el símbolo que corresponde a la última pala pulsada, mientras ambas se mantienen pulsadas.
- No están pulsadas ambas palas, pero se ha pulsado y liberado durante al emisión del punto, la pala raya. Es difícil hacer esto, pero se tiene en cuenta por si sucediera. En este caso se ha memorizado que se pulsó muy poco tiempo la para raya, por tanto MPALAR == 1 y se tiene que emitir este símbolo, así que se ejecuta la función TXR, se inicia la emisión de una raya. Ahora se analiza el estado de ambas palas. Si la pala punto está pulsada, recordemos que hemos entrado en este camino porque no estaban pulsadas ambas palas y se ha pulsado momentáneamente la pala raya, continuamos en el estado punto, en caso contrario, no está pulsado el punto, se pasa al estado RAYA.
- La pala raya no se pulsó, por tanto hay dos posibilidad es, que el punto siga pulsado, es decir hay que repetir el símbolo punto mediante TXP o que se haya liberado la pala punto. En el primer caso se emite un punto y se continua en el estado PUNTO, en el segundo caso, no hay pala punto pulsada, analizamos si WSPACE == WSPACEON. Esta variable nos indica si queremos añadir un espacio entre letras al final de la emisión del símbolo o no. Si se cumple la comparación se pasa al estado ESPERAESPACIO pero se lanza un temporizador ESPACIO con una duración de 3*TPUNTO.
En el estado ESPERAESPACIO se aceptan los mensajes de las palas, para memorizar su estado y cual se pulsó primero. Tengamos en cuenta que este estado dura 3 puntos y por tanto es posible que de tiempo a dar dos pulsaciones, una de punto y otra de raya. Esto es muy posible con un manipulador de una sola pala ya que n dos movimientos se hace esta secuencia. Por tanto saber qué pala se pulsó primero es importante.
El otro mensaje que se acepta es el de temporización. El temporizador en curso nos da el tiempo de espera para iniciar la emisión del siguiente símbolo. Si se pulsa alguna pala se analiza como ya se vio con la función AnalizaPala. Como vimos memoriza las acciones de las palas. Cuando venza el temporizador hay que decidir qué hacer. Para ello se usa la función MemEsperaEspacio. Del resultado de este análisis puede ser que no se haya pulsado ninguna pala, por tanto se pasa al estado INICIO o que se haya pulsado al menos una y se tiene que iniciar la emisión y pasar al estado correspondiente de punto o raya.
La función MemEsperaEspacio va a ir estudiando los distintos casos y pondrá en emisión, si corresponde, almacenando en la variable SEC lo que haga.
- Si ambas palas están pulsadas o han estado pulsadas en algún momento, se inicia la emisión por la que se pulsó primero, borrando la memoria de la que se atiende.
- Si no están pulsadas ambas palas se comprueba si está pulsada o se ha pulsado momentáneamente el punto. Se ser así se emite un punto y se fija SEC a PUNTO.
- Si no se cumple ninguno de los casos anteriores se comprueba se está o se ha pulsado la pala RAYA. En tal caso se emite una raya y la variable SEC se pone a RAYA. En caso contrario no se hace nada y la variable SEC vale cero.
El estado RAYA funciona de la misma manera que el estado punto, solo que se centra en la pala RAYA. Es funcionalmente simétrico al estado punto.
Tanto el estado punto como el estado raya tienen salida hacia los estados IAMBIC o ULTIMATIC en función de lo programado en la variable MODO.
El modo IAMBICO se caracteriza porque repite de forma alternada puntos y rayas mientras ambas palas están pulsadas. En este modo y durante la ejecución del símbolo en curso se aceptan mensajes de las palas, como hemos visto en casos anteriores. Al acabar el temporizador en curso se desencadenan las acciones que pueden provocar cambios de estado.
Esta función analiza el estado de la variable SEC y transmite el símbolo contrario que tenga almacenado. Cambia al nuevo símbolo y así sucesivamente mientras ambas palas estén pulsadas.
Si ambas palas no están pulsadas hay tres posibilidades. Una pala pulsada, punto o raya y ninguna pala pulsada. En el caso de haber una sola pala pulsada se emite el símbolo correspondiente y se pasa al estado del símbolo que se emite, PUNTO o RAYA. En este caso se detiene la alternancia y se continua con la pala pulsada. Por ejemplo la Y es -.-- se puede hacer pulsando la raya, luego el punto y cuando está dando la raya que sigue al punto se levanta la pala punto y de esta forma se vuelve a emitir una raya. Esta forma de manipular no emplea la función memoria. Esta letra se puede hacer de otra forma aprovechando la memoria de pala, haciendo una pulsación corta de la pala punto mientras se está emitiendo la primera raya, pero en este caso no se entraría en el modo IAMBIC que tiene sus peculiaridades.
Si una vez que recibe el mensaje de fin de temporizador SIMBOLO ambas palas están levantadas, se sale del modo IAMBIC, pero dependiendo de si se está en modo A o B la forma de salir es distinta.
Al regresar de la función CheckIAMBIC se analiza la variable AUX y si vale 0 se pasa al estado ESPERAESPACIO ya que se lanzó el temporizador ESAPCIO si vale 3 significa que no hay que esperar y se pasa al estado INICIO directamente, si vale PUNTO o RAYA significa que estamos en modo B y por tanto hay que ir al estado ESPERAIAMB donde nos quedamos mientras se emite el símbolo extra en curso. EL estado ESPERAESPACIO ya lo hemos visto y no cambia nada. El estado ESPERAIAMB es un paso intermedio para dar curso al símbolo extra de IAMBIC B.
En el estado ESPERAIAMB volvemos a aceptar los mensajes de las palas que se almacenan como ya vimos y hasta que no llega el temporizador no se toman acciones. El temporizador recibido se analiza en al función EsperaIamB. Si el temporizador es de fin de TX, TIMERTX, entonces se para a RX y nos mantenemos en el mismo estado. Si el temporizador es el de SIMBOLO ya tomamos acción en función de si se ha pulsado alguna pala o el estado de WSPACE.
Si no se ha pulsado ninguna pala y WSPACE == WSPACEON, entonces se lanza el temporizador ESAPCIO y se pasa al estado ESPERAESPACIO, si WSPACE == WSPACEOFF se pasa al estado INICIO directamente y si se ha pulsado alguna pala se ejecuta el símbolo correspondiente, pasando al estado PUNTO o RAYA según el símbolo en curso.
La función EsperaIamB analiza el estado de las palas. Mediante la variable AUX informa de la acción a tomar y a la salida se evalúa el estado de AUX.
No es estrictamente necesario usar una función para estas acciones, pero por limitaciones de la herramienta de simulación SDL es necesario hacer estas llamadas a función en lugar de meter todo junto.
Además luego es más sencillo analizar fallos en pequeños trozo de código en lugar de funciones muy grandes con varios switch case, if else anidados.
En el caso de tener el modo ULTIMATIC, en lugar de pasar al estado IAMBIC desde los estados PUNTO o RAYA se pasa al estado ULTIMATIC. Solo con este pequeño cambio de camino es suficiente para implementar un nuevo manipulador, el tipo ultimatic, en lugar del manipulador iambico.
En este modo volvemos a usar el mismo procedimiento. Mientras se está en el estado ULTIMATIC se está emitiendo un símbolo y por tanto almacenamos las acciones de las palas para luego evaluar. Cuando vence TIMERTX pasamos a RX, pero permanecemos en el estado ULTIMATIC y cuando vence SIMBOLO se analizan las palas. Si ambas palas permanecen pulsadas se repite el símbolo, esta es la diferencia sustancial con el iambico y es que no alterna.
Si por el contrario no están pulsadas ambas palas se llama a la función PalasUltimatic donde se analiza el estado de las palas.
La función PalasUltimatic es muy similar a la ya vista para IANBICO pero no tiene que distinguir nada más de si hay una o ninguna pala y si WSPACE está a ON u OFF.
Ya ha quedado analizado el 100% de la especificación, ahora es el momento de codificar sobre una placa HW determinada y comprobar el funcionamiento en modo real.
La herramienta de simulación, Pragma Dev Studio, permite analizar los casos uno por uno generando los mensajes y comprobando la respuesta para ver si es lo esperado. Es un trabajo un poco pesado, pero es de gran ayuda ver si la especificación cumple con lo esperado o no. Depurar un SW en el que no hay una mínima garantís de estar bien pensado introduce una dificultad extra. Funciona mal por estar mal codificado o es porque la idea no es correcta. Llegado a este punto se empiezan con los parches que acaban haciendo un código "infumable" y pasados unos días, semanas o meses ni nosotros mismos lo comprendemos.
La dificultad que introduce un autómata, con muchos estados y mensajes que van y vienen, nos debe llevar a plantearnos seriamente hacer un análisis previo exaustivo. Si no se dispone de una herramienta de simulación/validación es de gran ayuda el análisis crítico de otros para ver si se comprende todo lo especificado y cumple con lo previsto.
Pasar de SDL a C es algo laborioso pero "trivial". Otro asunto es generar mensajes asíncronos que respondan a los eventos HW sin que éstos se pierdan. Un sistema de muestreo puede funcionar si la granularidad del muestreo es suficientemente pequeña como para asegurarnos que no se pierda ningún evento, pero para que esto sea viable es necesario que el tiempo de ejecución del código entre muestras sea suficientemente bajo. Si solo pensamos en un manipulador que va a dar una señal abierto/cerrado a otro HW es posible usar una CPU lenta y podremos usar un sistema de muestro sin grandes complicaciones. Si por el contrario el manipulador es parte del SW de otro sistema más complejo como pueda ser un TRX que tiene que atender a otros muchos eventos, como calcular y programar las frecuencias de emisión o recepción según se a el caso, salidas a pantalla, etc.. es posible que el tiempo que esté ocupada la CPU en algunos procesos exceda con creces el mínimo necesario para muestrear sin que se pierdan eventos. Pensemos que a 20 palabras por minuto un punto dura 120ms. si una puslación de un punto por tanto debe durar menos de este tiempo y debemos ser capaces en este tiempo de capturar los cambios de las palas y hacer el resto de tareas. Por tanto, en casos así es mucho mejor que los eventos HW sean atendidos por interrupciones de tal forma que se capturen, se encolen y sean atendidos cuando sea posible. Es evidente que si aún así el tiempo de ejecución supera los 120ms no podremos emitir a 20ppm, pero si los eventos se recogen en tiempo real y se atienden a tiempo de no violar los tiempos definidos por la velocidad de transmisión, entonces tendremos un sistema eficiente.
No hay comentarios:
Publicar un comentario
Espero que te sea útil. Te agradezco la crítica constructiva y todo tipo de comentarios no ofensivos, despectivos o mal intencionados