Felix Maocho

Para quien le interese lo que a nosotros nos interesa

Arduino – Comunicar la tarjeta Arduino con el PC

Por Félix Maocho
17/8/2013

.

Objetivo de este post:

Enseñar a establecer y utilizar una vía de comunicación entre la Tarjeta y el PC de modo que se pueda recibir información de lo que hace la tarjeta y en un posdt posterior enseñar que tambien se puede enviar órdenes desde el Pc que modifiquen la actuación de la tarjeta.
_________________

La tarjeta de Arduino tiene como objeto construir aparatos interactivos, es decir, no sólo objetos de movimientos complejo, como puedan ser los de un reloj de torre, que además de las horas, de las fases de la luna y cosas por el estilo, sino objetos que puedan interactuar con sus dueños cambiando su forma de actuar de acuerdo a los deseos de sus dueños, como por ejemplo ocurre con una radio reloj despertador, aparato que tu puedes manipular, tanto la hora de comenzar a sonar, como la emisora que sintonice o el volumen del sonido, para que actúe de acuerdo con tus deseos. Para ello es fundamental establecer medios que permitan al usuario manipular el objeto.

La forma más obvia de comunicarse es dotar la objeto de interruptores, diales y otros actuadores físicos que informen al aparato de nuestras intenciones, como se hace el despertador, pero también existen otras formas que es enviar y recibir señales por diversos conductos al aparato sin necesidad de tocarlo físicamente.

En Arduino, uno de los medios más habituales, es comunicar con la tarjeta, un sistema sencillo denominada comunicación serial, en la que de momento, nos vamos a limitar a realizar la comunicación a través del cable USB, que une el PC con la tarjeta controladora, pero que solo a modo de información indico que es posible efectuarlo por otros procedimientos, tanto alámbricos como inalámbricos, como pueden ser ultrasonidos, rayos infrarrojos, o WiFi y por tanto tambien es posible conectar a través de Internet.

De igual forma la señal puede proceder de un PC o de cualquier otros dispositivo capaz de emitir comunicaciones seriadas, lo que permite interactuar con los aparatos que construyamos conectados bien por cable o bien mediante conexiones inalámbricas, lo que permite situar, tanto los aparatos, como partes de ellos, en cualquier lugar,próximo o lejano. Sin embargo de momento nuestro objetivo es más modesto y nos limitaremos a explicar la comunicación con el PC a través del cable USB, dejando otras formas de comunicación para el futuro.

Así pues, de momento, al cable USB le hemos encontrado tres funciones diferentes:

Primero, Introducir el programa en lenguaje máquina en la tarjeta controladora, inmediatamente antes de que la tarjeta arranque. Esta es una labor en la que es insustituible, pero una vez ha acabado la transmisión del programa, Arduino no precisa de la lógica del PC para trabajar.
La segunda misión del cable USB, es suministrar la corriente eléctrica a 5 volt. Que precisa Arduino para su funcionamiento, o sea, que utiliza el PC como fuente de energía  de la tarjeta, Tampoco esto esta función es imprescindible, Arduino tiene previsto recibir la electricidad de otras fuentes, como puede ser una pila eléctrica, o un transformador AD/CD  (transformador de corriente alterna (AD) a continua (CD), similar al que tiene los cargadores de los teléfonos). Para ello tiene prevista una entrada de alimentación externa capaz de trabajar entre 7 y 12  voltios, que se sitúa en el mismo lado de la tarjeta que la entrada USB.U

na pequeña diferencia entre la entrada USB y la de alimentación externa, es que en este segundo caso, se precisa que suministre tensión con un voltaje superior a los 5 V que suministra la entrada USB, la razón es que Arduino estabiliza internamente la corriente en los 5 voltios con la precisión que necesita, labor que procediendo la energía del PC,  ya viene realizada

Por ejemplo, seis pilas normales de 1,5 de voltio producen 9 Volts nominales, y algo menos, cuando ya están a media carga pero suficientes para Arduino, Tambien valen seis pilas recargables normales, aunque estas nunca llegan a producir más de 1,2 volts, o sea 7.2 volts en conjunto en el mejor de los casos.
Por tanto, una tarjeta Arduino que tuviera ya cargado el programa y una fuente eléctrica alternativa, puede trabajar indefinidamente separada del ordenador. Así trabajan por ejemplo los aparatos de domótica, como los controladores de persianas o los equipos de vigilancia, o en robótica donde el robot se desplaza libre de toda atadura.

No obstante el cable USB tiene otra tercera misión, que es de la que vamos a hablar hoy, que es permitir enviar y recibir información de/desde  el procesador USB al procesador del PC, esto es lo que llamamos una “conexión serie” o en ingles “serial”. Serie significa “uno después del otro” Por ejemplo, un asesino en serie, es un asesino, que realiza su matanza una tras otra. En la transferencia de datos en serie, transferimos los datos un bit detrás de otro.

Como vemos en la ilustracion que abre el post,, através del  cable USB pueden emitirse estados altos y bajos de tensión. La información que se manda/recibe entre el ordenador y Arduino, es básicamente, cambios de un de estado alto a bajo. Igual que hacemos para  encender y apagar un LED. Comprenderemos que es posible inventarse un “morse” de ceros y unos, Un extremos enciende y apaga un pin y en el otro extremo se le el voltaje de la red. Solo tendremos convenir a que velocidad puede cambiar el estado en el apararto que envia los caracteres o sea los bauduios o bits por segundo de la conexión, para que ambas máquinas puedan entenderse.

Nosotros ya hemos utilizado la comunicación de serie, pues así es como enviamos sketches a la placa Arduino. Al compilar, lo que hacemos es convertir el código que hemos escrito a datos binarios, (unos y ceros). Cuando cargamos  Arduino, los bits se mandan a través del cable USB a la placa Arduino, donde se almacenan en el chip principal.

La próxima vez que subas un sketch, fíjate en los LED próximos al conector USB, que  parpadean cuando se están transmitiendo datos. Uno led se enciende cuando Arduino recibe datos (RX) y uno parpadea cuando está transmitiendo datos (TX)

Mandato “begin”


Para establecer una conexión serial, lo primero es indicar a Arduino que vamos a conectar con él, y indicarle el protocolo de comunicación que vamos a utilizar en esta conexión. Eso lo indicamos en la función “setup”, (que es en la que se indican siempre la configuración y servicios de Arduino, que vamos a utilizar en el programa), con el mandato “begin” (comenzar) que tiene la siguiente sintaxis.

Serial.begin(velocidad)

  • Serial.begin” indica, que vamos a utilizar la comunicación “Serial”.
  • velocidad” es el número expresado en baudios, o lo que es igual, el numero de bites que se transmiten en un segundo. Hay diferentes velocidades de comunicación posible pues no todos los aparatos siempre tienen la misma velocidad de conexión. Por ejemplo, los antiguos módem acústicos de los teléfonos eran muy lentos, mientras que los módem de fibra óptica son muy rápidos.

Las velocidades que Arduino soporta son 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 o 115200. En la comunicación de Arduino con el PC podemos utilizar una intermedia, como 9.600 baudios. Así pues para abrir nuestra comunicación, en la función “setup” declaramos que vamos a utilizar la comunicación “serial” con el mandato. Ello crea un “buffer” de datos que puede enviarse en una y otra dirección :

Serial.begin(9600)

Mandatos “print” y “println”

Una vez que hemos declarado que vamos a comunicar PC y la tarjeta, podemos hacer que la tarjeta envíe el “buffe” con datos al PC para que los saque por la pantalla utilizando dos posibles mandatos funcionamiento muy parecidos “print”, (imprimir) y “println”, (imprimirnl)  que hacen lo mismo,, cargar los datos, con el formato que se le indique, en el “buffer· y enviarlos  al PC, (que los muestra en pantalla), con la única diferencia de que además “printnl”, finaliza los datos a enviar con un carácter “nl”, que provoca el cambio de línea, (“nl” = nueva línea), con lo que evitamos que en pantalla se amontonen las cosas que enviemos una detrás de otra, y podamos controlar fácilmente cuando deseamos cambiar de línea de texto.

Por tanto si deseamos que lo que vamos enviando aparezca uno al lado del otro, (o separado por espacios en blanco que habrá tambien que enviar), utilizaremos el mandato “print” y cuando deseemos que el texto aparezca en diferente línea el último bloque de texto lo enviaremos con un mandato “printnl”.

La sintaxis para ambas es la misma

Serial.print(val, format)
Serial.printnl(val, format)

  • “Serial,print” o “Serial.printnl”  mandan enviar al PC una información, añadiendo al final en el segundo caso un carácter de “nueva línea”)
  • “val” Serra el valor a enviar, un carácter, una cadenas de caracteres o el valor de una variable, el carácter suelto hay que separarlo con  comilla simple, (si deseamos mandar “A” escribiremos  ‘A’), si lo que queremos mandar es varios caracteres lo escribiremos entre comillas dobles, , (si deseamos mandar “AB” escribiremos  “AB”), si lo que deseamos es mandar el valor de una variable escribiremos solo el nombre de la variable sin comillas.
  • “format” es un parámetro opcional, (no obligatorio),  que por defecto indica que lo que mandamos son caracteres imprimibles, pero si queremos mandar otra información para que la tome un programa en el PC que la elabore, (algo que veremos más adelante), puede tener los siguientes tipos BYTE, BIN (binarios o base 2), OCT (octales o base 8), DEC (decimales o base 10), HEX (hexadecimales o base 16) o un número, (que indica la cantidad de decimales que tiene). Por ejemplo:
    • Serial.print(ab) imprime  “ab”
    • Serial.print(78) imprime  “78”
    • Serial.print(78, BYTE) imprime “N”  (pues se corresponde con el ASCII78 es equivalente a escribir “Serial.print(N)
    • Serial.print(78, DEC) imprime “78” (que 78 en base 10  78= 70 +8)
    • Serial.print(78, BIN) imprime “1001110” (que es 78 en base 2 78=16+0+0+8+4+2+0)
    • Serial.print(78, OCT) imprime “116” (que es 78 en base 8  78= 64+8+6)
    • Serial.print(78, HEX) imprime “4E”  (que es a 78 en base 16 70 =((4×16)+ E (=14))
    • Serial.println(1.23456, 0) imprime “1”
    • Serial.println(1.23456, 2) imprime “1.23”
    • Serial.println(1.23456, 4) imprime “1.2346”

Aunque será bueno que recordemos para el futuro que podemos mandar al PC cosas de diferente tipo, lo habitual de momento será simplemente querer que nos aparezca en pantalla un mensaje en texto y lo mas compresible en pantalla son los caracteres imprimibles, por lo que, (de momento), basta con escribir:

Serial.print(mensaje) o  Serial.println(mensaje)

Nos falta por explicar el mandato que hace lo inverso, es decir recoger lo que hayamos escrito en la pantalla del ordenador y lo introduzca dentro del programa de Arduino, pero como esto está saliendo muy largo lo de jo para el siguiente post.

– – – – – – –  Actualizacion al 25/08/20134 – – – – – – – 

Recientemente e he actualizado la versión IDE que utilizaba y al ir a utilizar con ella el mandato “print” me ha informado que ya no soporta la palabra “BYTE” y que debo utilizar el mandato “write”. En efecto he me mirado la versión inglesa del manual  y en ella ha desaparecido la palabra BYTE que si aparece en la versión española .

Estudiando ambos mandatos, no llego a tener del todo claro el porque existen dos mandatos tan similares ni cual es la diferencia entre cada uno de ellos, por lo que todo lo que viene a continuación debe considerarse cono provisional y sujeto a error, pues se corresponde a lo que he creído entender (pero de lo que no estoy seguro), de los manuales, entrándome la duda de si estos estén totalmente actualizados, pues al menos  la versión española parece estar desactualizada.

El mandato “write” hace en principio lo mismo que el mandato “print”· pero parece que se especializa en el envío de caracteres mientes que el “print” se reserva para el envío de números . Concretamente la descripción del mandato dice “Escribe datos binarios en el puerto serie. Estos datos se envían como un byte o una serie de bytes; para enviar los caracteres que representan los dígitos de un número usar función print () en su lugar.” .

La sintaxis de “write” es así mismo parecida, pero más sencilla y completa  que la de “print” y tiene los siguientes formatos:

Serial.write(val)
padding-left: 90px;”>Serial.write(str)
90px;”>Serial.write(buf, len)

len = Serial.write(str)

Donde

  • “Serial. Write” ordena enviar al PC una información.
  • “val” es un valor de solo byte, un número positivo de 0 a 255
  • “str”: una cadena ‘string’ para enviar como una serie de bytes el string tiene una longitud siempre de un caracter más de los enviados pues el sistema añade automáticamente un nulos, (código ASCII 0 = )., al final para indicar el fin del string y que sepa el receptor cuando tiene que terminar de leer
  • “arr”: es igual que en el caso anterior un ‘array’ pero aquí es de longitud determinada
  • len: longitud del array que se envía.

Retorno,.- A diferencia de “print”, ”write devuelve un número que es la longitud de bytes que ha enviado, el tomar ese valor es opcional y solo tiene sentido aprovechar si vamos a utilizar posteriormente en el sketch.

– – – – – – –  Fin de la Actualizacion  – – – – – – – 

Monitor serial

Falta aun otra cosa imprescindible, preparar el PC para que envíe y recoja los mensajes de Arduino. Una forma sencilla de hacerlo, (no la única), es abrir una pantalla serial que trae el software de Arduino que se carga en el PC.

Para hacerlo tenemos que acceder al entorno IDE de Arduino en nuestro PC, (el mismo que utilizamos para escribir, compilar y traspasar los sketch y en su menú superior desplegar las “Herramientas” y seleccionar la que se denomina “Monitor serial”

Una vez obtenida elegir en la esquina inferior derecha la misma velocidad de comunicación que hayamos puesto en la instrucción “beguin”

Sabido todo, procedamos a escribir un programita que maneje estos conceptos.

}

El programa no puede ser más sencillo . Comenzamos declarando la variable “contador” que guardará las vueltas que demos a la funcion “loop”. A continuación indicamos en la funcion “setup”, que vamos a establecer una comunicacion serial a 9600 baudios, e inmediatamente mandamos imprimir el mensaje “Hola Mundo” con el mandato “serial.println“. Como por esta funcion solo se pasa una vez, solo se escribiráa una vez el mensaje en pantalla. Observen que una vez escrito el mensaje, el siguiente mensaje cominza en una nueva línea. pues el mandato ha mandado a continuación “nl” (nueva línea).

Otra cosa que debe observar es que los mandatos “serial.print” y “serial.println” funcionan tanto en la funcion “setup” lo cual no es lo habitual, la mayoría de los mandatos solo funcionan en la funcion “loop” y solo los mandatos que declaran la configuración de la tarjeta arduino que vas a utilizar funcionan en “setup”. Esta excepcion es muy útil pues una forma de localizar errores de programación es colocar mensajes “chivato” que te indiquen que es lo que está pasando  en ciertos puntos del programa, por ejemplo pudiramos habernos confundido a la hora de definir un parámetro del un pin y que luego el cable lo estuviéramos conectando a otro pin. En caso de dudas de este tipo, un mensaje nos indica claramente el valor que tiene una variables en un punto derterminado del programa.

Entramos en el loop que solo hace tres cosas, emitir un mensaje fijo “numero de vuelta” con un mandato “print”, pot lo que no cambia de línea. A continuación mandamos imprimir el valor que tiene la variable “contador”, (que guarda el número de vueltas que damos a “loop”. Esta vez lo hacemos con el mandato “printnl”, por lo que se provoca el paso a una nueva línea.

Finalmente actualizamos el valor de contador sumando 1 a lo que ya tuviera.

Felix Maocho

17 agosto 2013 - Posted by | Robotica | , , , ,

2 comentarios »

  1. Muy interesante lo tratato y muy util para mi. Estoy buscnado la forma de cargar el sketch de arduino en forma inalambrica porque no siempre es posible tener la placa a mano, aun no he encontrado ningun blog que toque el tema (solo tu lo mencionas). Gracias por tu aporte

    Comentario por Enrique Gongora C. | 27 agosto 2014 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: