07-10-2022, 07:05 PM
Gracias por el interés. Así pues explicaré cómo funciona una comunicación en serie asíncrona, que es la que se usa tanto para NMEA0183 como para Seatalk.
En primer lugar, hay que decir que se llama asíncrona porque no existe una línea adicional de impulsos (clock) que sincronice emisor y recepctor. Entonces, es muy importante que tanto el emisor "transmita" como el receptor "lea" el contenido de la línea de datos en tiempos iguales y muy precisos. Esto es especialmente comprometido a velocidades altas.
La línea está en reposo a nivel alto (1), y el inicio del bloque de datos se determina siempre por un primer nivel 0 en la línea. A partir de ahí, los relojes internos de emisor y receptor hacen que los bits siguientes se transmitan y se capturen en los mismos instantes de tiempo.
Vaya lío no?. Pues no, porque existe un dispositivo hardware programable y especializado en hacer estas cosas. Se llama USART (Universal Synchronous Asinchronous Receiver Transmitter). Ejemplo: http://informatica.uv.es/~rmtnez/sbm/TEMA25-b&w.pdf
Este chip está integrado actualmente dentro de los microcontroladores (uC). La Raspi lleva un uC como procesador principal con dos USARTS.
La comunicación asíncrona puede funcionar sobre diferentes soportes físicos: RS232, RS422, RS485, Seatalk (este último no es un estándard de la industria). Los soportes físicos hacen recerencia a los niveles de tensión que se considerarán como 0 y 1 lógicos: si se hace con un solo cable (unipolar) como RS232, o con un par diferencial como en el caso de RS422 y RS485. No me extenderé demasiado aquí, sólo diremos que RS422 es el soporte estándard para NMEA0183 y usa dos líneas de datos con niveles complementarios: (0/1 y 1/0), y esto sirve para reducir por diferencias el posible ruido que produzca interferencias en las dos líneas a la vez.
Algunos dispositivos, de Garmin principalmente, utilizan RS232 en sus canales de comunicación. Seatalk también funciona sobre una línea unipolar (cable de color amarillo) con tensiones de 12v para el 1 lógico y de 0 a 2-3v para el 0 lógico.
Una explicación detallada sobre niveles y cableados de RS232, RS422 y RS485 la tenéis aquí:
http://www.uco.es/electrotecnia-etsiam/p...Fisico.pdf
Hasta aquí hemos visto cómo enviar ceros y unos por uno o dos cables. En el caso de NMEA0183 esos cables son de una única dirección (simplex), es decir, el que "habla" siempre habla y el que "escucha" siempre escucha y no puede hablar por esos cables, tiene que usar otros para hacerlo. De ahí la maraña que se monta en instalaciones NMEA0183.
Seatalk funciona de manera distinta: Por el mismo cable, a veces "habla" un dispositivo y los demás "escuchan", otras veces "habla" otro dispositivo, y el resto recibe. A ese tipo de comunicación se le llama "half duplex". NMEA2000 se ubica también en este tipo de comunicación half duplex. La ventaja es la drástica reducción del cableado.
Bueno, y esos 0's y 1's que se envían por esos cables cómo se organizan?
Pues NMEA0183 utiliza bloques de 0/1 agrupados de 8 en 8 (bytes) en formato ASCII (basado en una tabla y legible por los humanos)
https://elcodigoascii.com.ar/
Y Seatalk (De NMEA2000 podemos hablar otro día) utiliza un formato de 9 bits en binario puro mucho más eficiente pero no traducible a texto. El noveno bit, cuando está a 1 indica que ese bloque de9 bits es el inicio del datagrama (sentencia seatalk). Los demás grupos de 9 bits tienen ese noveno bit a 0.
Problema: Las USARTS de la Raspberry no son capaces de configurarse con bloques de datos de 9 bits. Vale, eso lo sabíamos, por eso alguna librería Python maneja directamente un pin GPIO para leer los datos Seatalk. Pero, ¿qué comporta eso?.
1- Es necesario que la CPU atienda directamente la lectura de ese pin (La librería no sirve para enviar datos).
2- Además DEBE hacerlo en instantes de tiempo que coincidan con el punto central del tiempo de bit. Cualquier retraso o adelanto supondrá una lectura errónea.
3- La Raspberry utiliza un sistema operativo multitarea. Los cambios de tarea (hilos de programa) se suelen realizar cada milisegundo. Diréis: Qué rápido!!!. Pues no, no es suficiente para una lectura precisa de un bloque de 9 bits, y menos cuando va "cargada" ejecutando varios programas, plugins, etc.
4- Para hacer una lectura medianamente precisa de un pin es imprescindible programar el sistema de interrupciones de la Raspberry, y usar un timer hardware asociado. Poca gente programa a ese nivel.
Aquí tenéis un ejemplo de transmisión del datagrama Seatalk donde se envía SOG:
Los puntos indican los instantes de tiempo donde el receptor debe realizar una captura del estado del GPIO. El bit de menos peso (valor) es el de la izquierda en cada bloque.
Como se puede ver, el primer bloque de datos de 9 bits contiene un valor 0x152 en hexadecimal. El 1 indica inicio de datagrama, y los siguientes bloques tienen este bit a 0.
El valor 52 indica que ese datagrama contiene datos de SOG.
Vamos a ampliar para ver cuánto dura 1 bit:
A simple vista se puede ver: aproximadamente 0,2 milisegundos. Exactamente 1/4800 = 0,20833 milisegundos.
Si el trabajo de leer bit a bit lo tiene que hacer la CPU y no la USART, eso supone que cada 0,208 milisegundos EXACTAMENTE, esa "pobre y cargada" CPU debe hacer una lectura e ir acumulando (desplazando) para formar el bloque de nueve bits. La USART añade lo que se llama una FIFO, que es una memoria donde se acumulan los últimos bloques de datos que llegan, y se guardan allí hasta que el procesador principal los puede leer de esa USART. Es decir, con la USART es prácticamente imposible perder un dato.
Y todo eso sin contar con la sincronización inicial (start bit), porque entre ese primer nivel 0 y el primer instante donde se debe capturar el primer bit válido debe transcurrir exactamente un tiempo equivalente a 1 bit y medio.
Una USART normalita divide el tiempo de bit en 16, 64 y hasta más a baudrates bajos como usa Seatalk (4800). Y realiza la captura justo en el centro de ese intervalo.
NO siento el rollaco, porque al que no le interese lo puede saltar...
En primer lugar, hay que decir que se llama asíncrona porque no existe una línea adicional de impulsos (clock) que sincronice emisor y recepctor. Entonces, es muy importante que tanto el emisor "transmita" como el receptor "lea" el contenido de la línea de datos en tiempos iguales y muy precisos. Esto es especialmente comprometido a velocidades altas.
La línea está en reposo a nivel alto (1), y el inicio del bloque de datos se determina siempre por un primer nivel 0 en la línea. A partir de ahí, los relojes internos de emisor y receptor hacen que los bits siguientes se transmitan y se capturen en los mismos instantes de tiempo.
Vaya lío no?. Pues no, porque existe un dispositivo hardware programable y especializado en hacer estas cosas. Se llama USART (Universal Synchronous Asinchronous Receiver Transmitter). Ejemplo: http://informatica.uv.es/~rmtnez/sbm/TEMA25-b&w.pdf
Este chip está integrado actualmente dentro de los microcontroladores (uC). La Raspi lleva un uC como procesador principal con dos USARTS.
La comunicación asíncrona puede funcionar sobre diferentes soportes físicos: RS232, RS422, RS485, Seatalk (este último no es un estándard de la industria). Los soportes físicos hacen recerencia a los niveles de tensión que se considerarán como 0 y 1 lógicos: si se hace con un solo cable (unipolar) como RS232, o con un par diferencial como en el caso de RS422 y RS485. No me extenderé demasiado aquí, sólo diremos que RS422 es el soporte estándard para NMEA0183 y usa dos líneas de datos con niveles complementarios: (0/1 y 1/0), y esto sirve para reducir por diferencias el posible ruido que produzca interferencias en las dos líneas a la vez.
Algunos dispositivos, de Garmin principalmente, utilizan RS232 en sus canales de comunicación. Seatalk también funciona sobre una línea unipolar (cable de color amarillo) con tensiones de 12v para el 1 lógico y de 0 a 2-3v para el 0 lógico.
Una explicación detallada sobre niveles y cableados de RS232, RS422 y RS485 la tenéis aquí:
http://www.uco.es/electrotecnia-etsiam/p...Fisico.pdf
Hasta aquí hemos visto cómo enviar ceros y unos por uno o dos cables. En el caso de NMEA0183 esos cables son de una única dirección (simplex), es decir, el que "habla" siempre habla y el que "escucha" siempre escucha y no puede hablar por esos cables, tiene que usar otros para hacerlo. De ahí la maraña que se monta en instalaciones NMEA0183.
Seatalk funciona de manera distinta: Por el mismo cable, a veces "habla" un dispositivo y los demás "escuchan", otras veces "habla" otro dispositivo, y el resto recibe. A ese tipo de comunicación se le llama "half duplex". NMEA2000 se ubica también en este tipo de comunicación half duplex. La ventaja es la drástica reducción del cableado.
Bueno, y esos 0's y 1's que se envían por esos cables cómo se organizan?
Pues NMEA0183 utiliza bloques de 0/1 agrupados de 8 en 8 (bytes) en formato ASCII (basado en una tabla y legible por los humanos)
https://elcodigoascii.com.ar/
Y Seatalk (De NMEA2000 podemos hablar otro día) utiliza un formato de 9 bits en binario puro mucho más eficiente pero no traducible a texto. El noveno bit, cuando está a 1 indica que ese bloque de9 bits es el inicio del datagrama (sentencia seatalk). Los demás grupos de 9 bits tienen ese noveno bit a 0.
Problema: Las USARTS de la Raspberry no son capaces de configurarse con bloques de datos de 9 bits. Vale, eso lo sabíamos, por eso alguna librería Python maneja directamente un pin GPIO para leer los datos Seatalk. Pero, ¿qué comporta eso?.
1- Es necesario que la CPU atienda directamente la lectura de ese pin (La librería no sirve para enviar datos).
2- Además DEBE hacerlo en instantes de tiempo que coincidan con el punto central del tiempo de bit. Cualquier retraso o adelanto supondrá una lectura errónea.
3- La Raspberry utiliza un sistema operativo multitarea. Los cambios de tarea (hilos de programa) se suelen realizar cada milisegundo. Diréis: Qué rápido!!!. Pues no, no es suficiente para una lectura precisa de un bloque de 9 bits, y menos cuando va "cargada" ejecutando varios programas, plugins, etc.
4- Para hacer una lectura medianamente precisa de un pin es imprescindible programar el sistema de interrupciones de la Raspberry, y usar un timer hardware asociado. Poca gente programa a ese nivel.
Aquí tenéis un ejemplo de transmisión del datagrama Seatalk donde se envía SOG:
Los puntos indican los instantes de tiempo donde el receptor debe realizar una captura del estado del GPIO. El bit de menos peso (valor) es el de la izquierda en cada bloque.
Como se puede ver, el primer bloque de datos de 9 bits contiene un valor 0x152 en hexadecimal. El 1 indica inicio de datagrama, y los siguientes bloques tienen este bit a 0.
El valor 52 indica que ese datagrama contiene datos de SOG.
Vamos a ampliar para ver cuánto dura 1 bit:
A simple vista se puede ver: aproximadamente 0,2 milisegundos. Exactamente 1/4800 = 0,20833 milisegundos.
Si el trabajo de leer bit a bit lo tiene que hacer la CPU y no la USART, eso supone que cada 0,208 milisegundos EXACTAMENTE, esa "pobre y cargada" CPU debe hacer una lectura e ir acumulando (desplazando) para formar el bloque de nueve bits. La USART añade lo que se llama una FIFO, que es una memoria donde se acumulan los últimos bloques de datos que llegan, y se guardan allí hasta que el procesador principal los puede leer de esa USART. Es decir, con la USART es prácticamente imposible perder un dato.
Y todo eso sin contar con la sincronización inicial (start bit), porque entre ese primer nivel 0 y el primer instante donde se debe capturar el primer bit válido debe transcurrir exactamente un tiempo equivalente a 1 bit y medio.
Una USART normalita divide el tiempo de bit en 16, 64 y hasta más a baudrates bajos como usa Seatalk (4800). Y realiza la captura justo en el centro de ese intervalo.
NO siento el rollaco, porque al que no le interese lo puede saltar...