USB to Serial

por | 13 junio, 2016

Arduino se conecta a nuestro ordenador a través del puerto USB, pero el puerto USB se debe conectar al microcontrolador a través del puerto serie, por ello debemos entender cómo están relacionados el puerto USB y el puerto serie.

En un Arduino usamos el puerto USB para tres funciones: cargar nuestro programa ya compilado en la memoria flash, conectarnos al puerto Serie (UART) predefinido en cada Arduino para comunicarnos durante la ejecución del programa y adicionalmente alimentar a Arduino. Todo ello se puede hacer sin la necesidad del puerto USB, pero dada la facilidad de uso y que todos los ordenadores disponen de un puerto USB, nos facilita mucho hacer estas operaciones.

El puerto serie conectado al USB lo usamos como puerto de consola o puerto de debug.

UART: http://es.wikipedia.org/wiki/Universal_Asynchronous_Receiver-Transmitter. Las funciones principales de la UART son de manejar las interrupciones de los dispositivos conectados al puerto serie y de convertir los datos en formato paralelo, transmitidos al bus de sistema, a datos en formato serie, para que puedan ser transmitidos a través de los puertos y viceversa.

La UART normalmente no genera o recibe directamente las señales externas entre los diferentes módulos del equipo. Usualmente se usan dispositivos de interfaz separados para convertir las señales de nivel lógico del UART hacia y desde los niveles de señalización externos, como puede ser RS232 o RS485. Una UART está normalmente en un circuito integrado usado para comunicaciones serie sobre un ordenador u otro dispositivo periférico.

Los microcontroladores como el ATmega328p tiene USART (Universal Syncronous Asyncronous Receiver Transmitter). Una USART puede trabajar igual que una UART, pero tiene la capacidad adicional de actuar como síncrona, esto significa que los datos van sincronizados con una señal de reloj. El reloj es recuperado desde los propios datos o enviado como como una señal externa. En ese caso no se usan los bits de start y stop, lo que permite una velocidad en baudios mayor al operar en modo síncrono porque la temporización de los bits tienen una cierta garantía y más bits pueden ser usados para datos en lugar de cabeceras.

Por el contrario la UART dispone de una señal de reloj interno y los datos en el bus pueden tener una temporización más irregular. Las UART requieren bits de start y stop y los datos asíncronos sólo se sincronizan con los bits de start y stop. La palabra asíncrono indica que la UART recupera la temporización de los caracteres desde el flujo de datos, usando el bit de start y el de stop para indicar el marco de cada carácter.

En la transmisión síncrona, la señal de reloj es recuperada de forma separada del stream de datos, esto mejora la eficiencia de la transmisión al haber más bits de datos en la transmisión. Una conexión asíncrona no manda nada cuando el dispositivo que transmite no tiene nada que mandar, pero un interfaz síncrono debe mandar caracteres para mantener el sincronismo entre emisor y receptor, normalmente el carácter ASCII “SYN” se encarga de rellenar este hueco y esto puede ser hecho automáticamente por el dispositivo transmisor.

Diferencia entre UART y USART:

Más información sobre la USART del MCU ATmega328p, ver página 170 de http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

Estándares de comunicación serie que definen las características eléctricas de los drivers y los receptores:

Explicación de la diferencia entre comunicación RS232 y TTL: RS-232 vs. TTL Serial Communication y http://www.atmel.com/Images/doc4322.pdf

Niveles lógicos

Los niveles lógicos de los microcontroladores, son los niveles físicos de voltaje por los que se interpreta un microcontrolador un 1 y un 0. Niveles lógicos: https://en.wikipedia.org/wiki/Logic_level

En el caso de los ATmega AVR usan Tecnología TTL: http://es.wikipedia.org/wiki/Tecnolog%C3%ADa_TTL. Su tensión de alimentación característica se halla comprendida entre los 4,75V y los 5,25V (como se ve, un rango muy estrecho). Normalmente TTL trabaja con 5V. Los niveles lógicos vienen definidos por el rango de tensión comprendida entre 0,0V y 0,8V para el estado L (bajo) y los 2,2V y Vcc para el estado H (alto). La velocidad de transmisión entre los estados lógicos es su mejor base, si bien esta característica le hace aumentar su consumo siendo su mayor enemigo. Motivo por el cual han aparecido diferentes versiones de TTL como FAST, LS, S, etc y últimamente los CMOS: HC, HCT y HCTLS. En algunos casos puede alcanzar poco más de los 400 MHz.

TTL logic levels: https://learn.sparkfun.com/tutorials/logic-levels/ttl-logic-levels

Niveles lógicos de Arduino: https://learn.sparkfun.com/tutorials/logic-levels/arduino-logic-levels

A medida que la tecnología avanza se crean dispositivos que necesitan menor consumo eléctrico y usan un menor voltaje de base (Vcc = 3.3 V en lugar de 5V). La técnica de fabricación es también diferente para dispositivos de 3.3V que permiten una huella menor y costes más pequeños. Para asegurar la compatibilidad de los dispositivos a 3.3V, se puede ver que la mayoría de los niveles de voltaje son casi los mismos para dispositivos de 3.3V y los de 5V. Un dispositivo de 3.3V puede interactuar con uno de 5V sin componentes adicionales. Por ejemplo un 1 lógico (HIGH) de un dispositivo de 3.3V será al menos 2.4V, esto sigue siendo interpretado como un 1 lógico en un dispositivo de 5V porque está por encima  de VIH que es 2V.

Sin embargo hay que tener en cuenta que un dispositivo de 3.3V es tolerante a señales de 5V, esta especificación es el “maximum input voltage” del dispositivo. En ciertos dispositivos de 3.3V, cualquier voltaje supuerior a 3.6V provocará un daño permanente en el chip, para evitar esto se puede usar un simple divisor de tensión (https://learn.sparkfun.com/tutorials/voltage-dividers) como una resistencia de 1KΩ y una de 2KΩ para bajar los 5V o usar un logic level shifter como https://www.sparkfun.com/products/12009

Voltaje 5V vs 3.3V http://jeelabs.org/2010/12/16/voltage-3-3-vs-5/

USB to Serial en Arduino

Cuando conectamos Arduino a un ordenador mediante un cable USB, el ordenador instala un puerto serie virtual (COM) desde el cual podemos acceder al puerto serie de Arduino. Por este motivo es necesario instalar en el ordenador los drivers de interfaz USB de los microcontroladores de Atmel, esto se hace automáticamente al instalar el IDE de Arduino.

Arduino UNO como otros Arduinos disponen de microcontroladores que no tienen un interfaz USB incorporado, por lo tanto no se pueden conectar directamente a un Ordenador. Para ello usan un segundo microcontrolador que hace de intermediario, generalmente un ATmega16u4 que dispone de un interfaz USB. Este microcontrolador dispone de un firmware especial que facilita la carga del programa en la flash del Arduino y comunicar posteriormente por el USB.

Este firmware y su código se puede ver en https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial

Los microcontroladores de 8 bits mega AVR con interfaz USB están configurados de fábrica con un bootloader USB, este permite hacer un In-System Programming desde el interfaz USB sin eliminar la parte del sistema o sin una aplicación preprogramada y sin un un interfaz externo de programación.

USB DFU (Device Firmware Update) Bootloader: http://www.atmel.com/Images/doc7618.pdf

Más información del microcontrolador en: http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf

Existen otros Arduino como el Arduino Leonardo cuya MCU (ATmega32u4) dispone de un interfaz USB incorporado y programamos y nos conectamos directamente al Arduino desde el ordenador sin intermediarios.

Más información en http://www.atmel.com/Images/doc7618.pdf

Cable FTDI

Cable FTDI es la forma más fácil de conectar el microcontrolador a un ordenador por USB. Consiste en un chip de conversión USB a Serie. Como ocurre con Arduino cuando lo conectamos, necesitamos los drivers de windows, cuando conectamos un cable FTDI también necesita sus drivers. Los driver FTDI vienen integrados en el IDE de Arduino.

FTDI es el fabricante más popular de chips conversores de USB a serie

Drivers:https://web.archive.org/web/20141005060035/http://www.ftdichip.com/Drivers/VCP.htm

Productos de FTDI:

Chip FTDI:

FT231X tiene un buffer de comunicación mayor comparado con el FT232R. El FT231X tiene los niveles lógicos de 3.3 V y con entradas tolerantes a 5V. FTDI provee de drivers para los dispositivos USB incluyendo driver certificados para Windows, incluido Windows 10.

Interesante artículo sobre la comunicación serie con MCUs AVR: http://www.evilmadscientist.com/2009/basics-serial-communication-with-avr-microcontrollers/

Cable para comunicar con dispositivos de 3.3V: https://www.sparkfun.com/products/9873

Al comprar un cable FTDI hay que estar atento al pineado que no es el que usan los Arduino Ethernet y otros elementos, es posible que para conectarlo a un Arduino haya que intercambiar algunos pines. Este es el pineado correcto y los colores de los cables para un FTDI para Arduino:

Existen en el mercado cable con otros colores y el pineado desordenado. Estos son los colores del cable y a que corresponde:

  • Red wire: 5V
  • Black wire: GND
  • White wire: RXD
  • Green wire: TXD
  • Yellow wire: RTS
  • Blue wire: CTS

Y el pineado bueno para arduino queda así:

Los cables CTS y RTS es el flow control (control de flujo). El pin RTS es una salida y debe conectarse al pin de entrada CTS del otro dispositivo de la conexión a la UART.

  • Si el pin RTS está a 0, indica que puede aceptar más datos en el pin RXD
  • Si el pin RTS está a 1, indica que no puede aceptar más datos.

Los cambios de estado del pin RTS ocurren cuando el buffer del chip alcanza los último 32 bytes de espacio para dejar tiempo al dispositivo externo para que pare el envío de datos.

El pin CTS es una entrada y debe ser conectado a la salida RTS del dispositivo al otro extremo.

  • Si el pin CTS está a 0, indica que el dispositivo externo puede aceptar más datos y transmitirá por el pin TXD.
  • Si el pin CTS está a 1, indica que el dispositivo externo no puede aceptar más datos y parará la transmisión de datos en los siguientes 0 – 3 caracteres, dependiendo de lo que haya en el buffer de salida. Se debe tener en cuenta que al ser un dispositivo USB opera en base a paquetes y no a bytes.

CTS y RTS en RS232: https://en.wikipedia.org/wiki/RS-232#RTS.2C_CTS.2C_and_RTR

También en algunos dispositivos serie nos podemos encontrar con el pin DTR que es el control de flujo https://en.wikipedia.org/wiki/Data_Terminal_Ready. El DTR permite a Arduino hacer el auto reset cuando un nuevo sketch es cargado a la memoria flash. Esto permite cargar un sketch sin tener que pulsar el botón de reset.

Una de las líneas del hardware flow control (DTR) del ATmega8U2/16U2, están conectadas a la línea de reset del MCU ATmega328P a través de un condensador de 100 nanofaradios. Cuando esta línea se pone a 0 V, es capaz de resetear el MCU de Arduino. El IDE de Arduino usa esta capacidad para permitir cargar código a Arduino simplemente presionando el botón upload y hace que el el timeout del bootloader pueda ser menor y estar mejor coordinado con el comienzo de la carga del sketch.

Cuando se detecta un flujo de datos a través del interfaz USB conectando un ordenador al Arduino, automáticamente se resetea la MCU de Arduino y durante el siguiente medio segundo, el bootloader se ejecuta en Arduino. Como el bootloader está programado para ignorar datos malformados (cualquier cosa que no sea nuevo código de un sketch), interceptará los primeros bytes de los datos enviados a la placa tras la conexión. Por este motivo si un sktech está programado para recibir una comunicación por el puerto serie tras iniciarse, hay que asegurarse que el software que manda esa información espera al menos un segundo después de que se abra la conexión hasta que se manden los primeros datos.

Ojo con los chips FTDI falsos: http://hackaday.com/2016/02/01/ftdi-drivers-break-fake-chips-again/

Ejemplo de uso de un FTDI: https://cdn-learn.adafruit.com/downloads/pdf/ftdi-friend.pdf

Ver este otro: http://www.tinyosshop.com/index.php?route=product/product&product_id=600

Ejemplo de placa FTDI comercial para programar tanto dispositivos a 5v como a 3.3 (los que habitualmente hay dispobles suelen ser a 5V), con selector de voltaje: http://www.tinyosshop.com/index.php?route=product/product&product_id=600, además este tiene DTR para conectar al reset y poder programar un arduino.

Los microcontroladores AVR de Arduino para programarlos directamente por puerto serie, van a 5V, aunque si se usa un programador de 3.3v le funciona porque el rx de arduino toma 0 cuando el voltaje es inferior a 0.7V.

Tal y como indica en las características del Arduino UNO en https://www.arduino.cc/en/main/arduinoBoardUno: “The Uno has a number of facilities for communicating with a computer, another Uno board, or other microcontrollers. The ATmega328 provides UART TTL (5V) serial communication, which is available on digital pins 0 (RX) and 1 (TX).”

Deja un comentario