La electrónica integrada consiste en interconectar circuitos (procesadores u otros circuitos integrados) para crear un sistema simbiótico. Para que esos circuitos individuales intercambien su información, deben compartir un protocolo de comunicación común. Se han definido cientos de protocolos de comunicación para lograr este intercambio de datos y, en general, cada uno de ellos puede clasificarse en una de las dos categorías siguientes: paralelo o serie.

Paralelo frente a serie

Las interfaces paralelas transfieren varios bits al mismo tiempo. Suelen requerir buses de datos, que se transmiten a través de ocho, dieciséis o más hilos. Los datos se transfieren en enormes olas de 1’s y 0’s.

Las interfaces seriales transmiten sus datos, un solo bit a la vez. Estas interfaces pueden funcionar con tan solo un cable, pero normalmente nunca con más de cuatro.

Piensa en las dos interfaces como un flujo de coches: una interfaz paralela sería la mega-autopista de más de 8 carriles, mientras que una interfaz en serie es más bien una carretera rural de dos carriles. Durante un tiempo determinado, la mega-autopista puede llevar a más personas a su destino, pero esa carretera rural de dos carriles cumple su función y cuesta una fracción de los fondos para construirla.

La comunicación paralela tiene ciertamente sus ventajas. Es rápida, sencilla y relativamente fácil de implementar. Pero requiere muchas más líneas de entrada/salida (E/S). Si alguna vez has tenido que pasar un proyecto de un Arduino Uno básico a un Mega, sabrás que las líneas de E/S de un microprocesador pueden ser preciosas y escasas. Por lo tanto, a menudo optamos por la comunicación en serie, sacrificando la velocidad potencial por el espacio de los pines.

Serie asíncrona

A lo largo de los años, se han creado docenas de protocolos serie para satisfacer las necesidades particulares de los sistemas embebidos. USB (bus serie universal) y Ethernet son algunas de las interfaces serie informáticas más conocidas. Otras interfaces serie muy comunes son SPI, I2C y el estándar serie del que vamos a hablar hoy. Cada una de estas interfaces serie puede clasificarse en uno de estos dos grupos: síncrona o asíncrona.

Una interfaz serie síncrona siempre empareja su(s) línea(s) de datos con una señal de reloj, por lo que todos los dispositivos de un bus serie síncrono comparten un reloj común. Esto hace que la transferencia en serie sea más sencilla y a menudo más rápida, pero también requiere al menos un cable adicional entre los dispositivos que se comunican. Algunos ejemplos de interfaces síncronas son SPI e I2C.

Asíncrono significa que los datos se transfieren sin apoyo de una señal de reloj externa. Este método de transmisión es perfecto para minimizar los cables y pines de E/S necesarios, pero significa que tenemos que hacer un esfuerzo extra para transferir y recibir datos de forma fiable. El protocolo serie que discutiremos en este tutorial es la forma más común de transferencias asíncronas. Es tan común, de hecho, que cuando la mayoría de la gente dice “serie” está hablando de este protocolo (algo que probablemente notarás a lo largo de este tutorial).

El protocolo serial sin reloj que discutiremos en este tutorial es ampliamente utilizado en la electrónica embebida. Si estás buscando añadir un módulo GPS, Bluetooth, XBee’s, LCDs en serie, o muchos otros dispositivos externos a tu proyecto, probablemente necesitarás usar un poco de técnica serie.

Si no estás súper familiarizado con alguno de esos conceptos, considera revisar esos enlaces.

Ahora bien, vayamos a un viaje en serie…

Reglas de la comunicación serie

El protocolo serie asíncrono tiene un número de reglas incorporadas – mecanismos que ayudan a asegurar transferencias de datos robustas y libres de errores. Estos mecanismos, que obtenemos por prescindir de la señal de reloj externa, son:

  • Bits de datos,
  • Bits de sincronización,
  • Bits de paridad,
  • y la tasa de baudios.

Gracias a la variedad de estos mecanismos de señalización, verás que no hay una única forma de enviar datos en serie. El protocolo es altamente configurable. La parte crítica es asegurarse de que ambos dispositivos en un bus serie están configurados para utilizar exactamente los mismos protocolos.

Tasa de baudios

La tasa de baudios especifica la velocidad con la que se envían los datos a través de una línea serie. Normalmente se expresa en unidades de bits por segundo (bps). Si inviertes la tasa de baudios, puedes saber cuánto tiempo se tarda en transmitir un solo bit. Este valor determina el tiempo que el transmisor mantiene una línea serie alta/baja o en qué periodo el dispositivo receptor muestrea su línea.

La velocidad en baudios puede ser casi cualquier valor dentro de lo razonable. El único requisito es que ambos dispositivos operen a la misma velocidad. Una de las tasas de baudios más comunes, especialmente para cosas sencillas en las que la velocidad no es crítica, es 9600 bps. Otras velocidades “estándar” son 1200, 2400, 4800, 19200, 38400, 57600 y 115200.

Cuanto más alta sea la velocidad en baudios, más rápido se envían/reciben los datos, pero hay límites a la velocidad de transferencia de datos. Normalmente no verás velocidades superiores a 115200 – eso es rápido para la mayoría de los microcontroladores. Si la velocidad es demasiado alta, empezarás a ver errores en el extremo receptor, ya que los relojes y los periodos de muestreo no pueden seguir el ritmo.

Enmarcar los datos

Cada bloque (normalmente un byte) de datos transmitido se envía en realidad en un paquete o trama de bits. Las tramas se crean añadiendo bits de sincronización y paridad a los datos.

Entremos en los detalles de cada uno de estos trozos de trama.

Trozo de datos

Lo verdaderamente importante de cada paquete serie son los datos que transporta. Llamamos ambiguamente a este bloque de datos un trozo, porque su tamaño no se indica específicamente. La cantidad de datos en cada paquete puede ser de 5 a 9 bits. Ciertamente, el tamaño estándar de los datos es el byte básico de 8 bits, pero otros tamaños tienen sus usos. Un trozo de datos de 7 bits puede ser más eficiente que uno de 8, especialmente si sólo estás transfiriendo caracteres ASCII de 7 bits.

Después de acordar la longitud de los caracteres, los dos dispositivos serie también tienen que acordar el modo de transmisión de sus datos. ¿Los datos se envían del bit más significativo (msb) al menos, o viceversa? Si no se indica lo contrario, normalmente se puede asumir que los datos se transfieren primero al bit menos significativo (lsb).

Bits de sincronización

Los bits de sincronización son dos o tres bits especiales que se transfieren con cada trozo de datos. Son el bit de inicio y el bit de parada. Haciendo honor a su nombre, estos bits marcan el comienzo y el final de un paquete. Siempre hay un solo bit de inicio, pero el número de bits de parada se puede configurar en uno o dos (aunque normalmente se deja en uno).

El bit de inicio siempre se indica mediante una línea de datos inactiva que pasa de 1 a 0, mientras que el bit o los bits de parada vuelven al estado inactivo manteniendo la línea en 1.

Bits de paridad

La paridad es una forma de comprobación de errores muy simple y de bajo nivel. Hay dos alternativas: par o impar. Para producir el bit de paridad, se suman los 5-9 bits del byte de datos, y la paridad de la suma decide si el bit está activado o no. Por ejemplo, suponiendo que la paridad esté configurada como par y que se añada a un byte de datos como 0b01011101, que tiene un número impar de 1’s (5), el bit de paridad se pondría a 1. A la inversa, si el modo de paridad estuviera configurado como impar, el bit de paridad sería 0.

La paridad es opcional y no se utiliza mucho. Puede ser útil para transmitir a través de medios ruidosos, pero también ralentizará un poco la transferencia de datos y requiere que tanto el emisor como el receptor implementen la gestión de errores (normalmente, los datos recibidos que fallan deben ser reenviados).

9600 8N1 (un ejemplo)

9600 8N1 – 9600 baudios, 8 bits de datos, sin paridad y 1 bit de parada – es uno de los protocolos serie más utilizados. Entonces, ¿qué aspecto tendrían uno o dos paquetes de datos 9600 8N1? Veamos un ejemplo.

Un dispositivo que transmita los caracteres ASCII “O” y “K” tendría que crear dos paquetes de datos. El valor ASCII de O (que es mayúscula) es 79, que se descompone en un valor binario de 8 bits de 01001111, mientras que el valor binario de K es 01001011. Lo único que queda es añadir bits de sincronización.

No se indica específicamente, pero se supone que los datos se transfieren primero con el bit menos significativo. Observa cómo cada uno de los dos bytes se envía al leer de derecha a izquierda.

Como estamos transfiriendo a 9600 bps, el tiempo que se emplea en mantener cada uno de esos bits alto o bajo es 1/ (9600 bps) o 104 µs por bit.

Por cada byte de datos transmitido, en realidad se envían 10 bits: un bit de inicio, 8 bits de datos y un bit de parada. Así, a 9600 bps, estamos enviando 9600 bits por segundo o 960 (9600/10) bytes por segundo.

Ahora que sabes cómo construir paquetes serie, podemos pasar a la sección de hardware. Allí veremos cómo se implementan esos 1’s y 0’s y la tasa de baudios a nivel de señal.

Cableado y hardware

Un bus serie consiste en sólo dos cables – uno para enviar datos y otro para recibirlos. Como tal, los dispositivos serie deben tener dos pines serie: el receptor, RX, y el transmisor, TX

Es importante tener en cuenta que esas etiquetas RX y TX son con respecto al propio dispositivo. Así que RX de un dispositivo debe ir a TX del otro, y viceversa. Es extraño si estás acostumbrado a conectar VCC con VCC, GND con GND, MOSI con MOSI, etc., pero tiene sentido si lo piensas. El transmisor debería estar hablando con el receptor, no con otro transmisor.

Una interfaz serie en la que ambos dispositivos pueden enviar y recibir datos es full-duplex o half-duplex. Full-duplex significa que ambos dispositivos pueden enviar y recibir simultáneamente. La comunicación semidúplex significa que los dispositivos serie deben turnarse para enviar y recibir.

Algunos buses serie pueden funcionar con una sola conexión entre el dispositivo emisor y el receptor. Por ejemplo, nuestras pantallas LCD habilitadas en serie son todo oídos y no tienen realmente ningún dato que transmitir al dispositivo de control. Esto es lo que se conoce como comunicación serial simplex. Todo lo que necesita es un solo cable desde el TX del dispositivo maestro a la línea RX del oyente.

Implementación del hardware

Hemos cubierto la comunicación serie asíncrona desde un punto de vista conceptual. Sabemos qué cables necesitamos. Pero, ¿cómo se implementa realmente la comunicación en serie a nivel de señal? En realidad, de varias maneras. Hay todo tipo de estándares para la señalización en serie. Veamos un par de las implementaciones de hardware más populares de la comunicación serie: nivel lógico (TTL) y RS-232.

Cuando los microcontroladores y otros circuitos integrados de bajo nivel se comunican en serie, normalmente lo hacen a nivel TTL (transistor-transistor lógico). Las señales en serie TTL existen entre el rango de alimentación de voltaje de un microcontrolador – normalmente de 0V a 3,3V o 5V. Una señal en el nivel VCC (3,3V, 5V, etc.) indica una línea inactiva, un bit de valor 1 o un bit de parada. Una señal de 0V (GND) representa un bit de inicio o un bit de datos de valor 0.

El RS-232, que se puede encontrar en algunos de los ordenadores y periféricos más antiguos, es como el serial TTL volteado. Las señales RS-232 suelen oscilar entre -13V y 13V, aunque las especificaciones permiten cualquier cosa entre +/- 3V y +/- 25V. En estas señales, un voltaje bajo (-5V, -13V, etc.) indica la línea inactiva, un bit de parada o un bit de datos de valor 1. Una señal RS-232 alta significa o bien un bit de inicio, o bien un bit de datos de valor 0. Es lo contrario de la serie TTL.

Entre los dos estándares de señales en serie, el TTL es mucho más fácil de implementar en los circuitos integrados. Sin embargo, los niveles de baja tensión son más susceptibles de sufrir pérdidas en las líneas de transmisión largas. RS-232, o estándares más complejos como RS-485, son más adecuados para las transmisiones en serie de largo alcance.

Cuando se conectan dos dispositivos serie, es importante asegurarse de que sus voltajes de señal coinciden. No puedes conectar directamente un dispositivo serie TTL con un bus RS-232. Tendrás que desplazar esas señales.

Continuando, exploraremos la herramienta que utilizan los microcontroladores para convertir sus datos en un bus paralelo hacia y desde una interfaz serie. ¡Las UARTs!

UARTs

La pieza final de este rompecabezas serial es encontrar algo para crear los paquetes seriales y controlar esas líneas físicas de hardware. Entra la UART.

Un receptor/transmisor asíncrono universal (UART) es un bloque de circuitos responsable de implementar la comunicación en serie. Esencialmente, la UART actúa como un intermediario entre las interfaces paralela y serie. En un extremo de la UART hay un bus de ocho o más líneas de datos (más algunos pines de control), en el otro están los dos cables serie – RX y TX.

Las UART existen como circuitos integrados independientes, pero es más común encontrarlas dentro de los microcontroladores. Tendrás que comprobar la hoja de datos de tu microcontrolador para ver si tiene alguna UART. Algunos no tienen ninguna, otros tienen una, otros tienen muchas. Por ejemplo, el Arduino Uno -basado en el “viejo fiel” ATmega328- tiene una sola UART, mientras que el Arduino Mega -construido sobre un ATmega2560- tiene la friolera de cuatro UARTs.

Como la R y la T en el acrónimo dictan, las UART son responsables de enviar y recibir datos en serie. En el lado de la transmisión, una UART debe crear el paquete de datos -añadiendo bits de sincronización y paridad- y enviar ese paquete por la línea de transmisión con una sincronización precisa (de acuerdo con la tasa de baudios establecida). En el lado de la recepción, la UART tiene que muestrear la línea RX a un ritmo acorde con la tasa de baudios esperada, recoger los bits de sincronización y escupir los datos.

Las UARTs más avanzadas pueden lanzar sus datos recibidos a un buffer, donde pueden permanecer hasta que el microcontrolador venga a buscarlos. Las UART suelen liberar sus datos en el búfer según el principio de “primero en entrar, primero en salir” (FIFO). Los búferes pueden ser tan pequeños como unos pocos bits, o tan grandes como miles de bytes.

UARTs por software

Si un microcontrolador no tiene una UART (o no tiene la suficiente), la interfaz serie puede ser controlada directamente por el procesador. Este es el enfoque que adoptan las librerías de Arduino como SoftwareSerial. El cambio de bits requiere un uso intensivo del procesador, y no suele ser tan preciso como una UART, pero funciona en caso de necesidad.

Errores comunes

Esto es todo lo que hay sobre la comunicación en serie. Me gustaría dejarte con algunos errores comunes que son fáciles de cometer para un ingeniero de cualquier nivel de experiencia:

RX-a-TX, TX-a-RX

Parece bastante simple, pero es un error que sé que he cometido más de un par de veces. Por mucho que quieras que sus etiquetas coincidan, asegúrate siempre de cruzar las líneas RX y TX entre los dispositivos serie.

En contra de lo que advertiría el estimado Dr. Egon Spengler, cruza los arroyos.

Desajuste de la tasa de baudios

Las velocidades en baudios son como los idiomas de la comunicación en serie. Si dos dispositivos no hablan a la misma velocidad, los datos pueden malinterpretarse o perderse por completo. Si todo lo que el dispositivo receptor ve en su línea de recepción es basura, compruebe que las velocidades en baudios coinciden.

Contención del bus

La comunicación serie está diseñada para permitir que sólo dos dispositivos se comuniquen a través de un bus serie. Si más de un dispositivo está tratando de transmitir en la misma línea serie, podría encontrarse con retención de bus. Dun dun dun….

Por ejemplo, si estás conectando un módulo GPS a tu Arduino, puedes conectar la línea TX de ese módulo a la línea RX del Arduino. Pero ese pin RX del Arduino ya está conectado al pin TX del convertidor USB a serie, que se utiliza cada vez que se programa el Arduino o se utiliza el monitor serie. Esto crea una situación potencial en la que tanto el módulo GPS como el chip FTDI están tratando de transmitir en la misma línea al mismo tiempo.

Dos dispositivos intentando transmitir datos al mismo tiempo, en la misma línea, es malo. En el “mejor” de los casos, ninguno de los dos dispositivos podrá enviar sus datos. En el peor de los casos, las líneas de transmisión de ambos dispositivos se pierden (aunque esto es poco frecuente y suele estar protegido).

Puede ser seguro conectar varios dispositivos receptores a un único dispositivo transmisor. No es lo más adecuado para las especificaciones y probablemente esté mal visto por un ingeniero experto, pero funcionará. Por ejemplo, si está conectando una pantalla LCD en serie a un Arduino, el enfoque más fácil puede ser conectar la línea RX del módulo LCD a la línea TX del Arduino. La línea TX del Arduino ya está conectada a la línea RX del programador USB, pero eso sigue dejando un solo dispositivo en control de la línea de transmisión.

Distribuir una línea de transmisión como esta puede ser peligroso desde la perspectiva del firmware, porque no puedes elegir qué dispositivo escucha qué transmisión. La LCD terminará recibiendo datos que no son para ella, lo que podría ordenarle entrar en un estado desconocido.

En general – ¡un bus serial, dos dispositivos seriales!

Jimblow. Serial Communication. Sparkfun. https://learn.sparkfun.com/tutorials/serial-communication