Compartir en facebook Compartir en google+ Compartir en twitter Compartir en pinterest Compartir en linkedin

Comunicando con Arduino

Publicado en Junio de 2017

A la hora de escribir este artículo no sabía como llamarlo, porque se cubren muchos aspectos diferentes sobre la comunicación serie. Al final decidí llamarlo Comunicando con Arduino porque me pareció la utilidad más sabrosa a la hora de realizar un proyecto de este tipo. Y lo he enfocado a un tema que se me ha resistido desde el principio: controlar un servo motor por impulsos con Python. Debido a que no existe una librería que controle impulsos con Python para Orange Pi (al menos yo no la he encontrado... Con el lenguaje C si hay librerías, pero no con Python) mover un servo se convirtió en el principal objetivo, así que conectando una placa Arduino conseguiremos dicho control. Pero este sólo es uno de los retos de este proyecto. Una vez que tenemos las 2 placas conectadas, podremos usar la capacidad de la placa Arduino y sus entradas y salidas digitales para leer sensores o manejar PWM (Pulse Width Modulation o Modulación por ancho de pulsos). Empecemos.

Que necesitas:

Partimos de una Orange Pi 2 con Armbian y la librería orangepi_PC_gpio_pyH3 además del paquete Python para controlar la regleta GPIO. Conectar una placa Arduino es tan sencillo como decir que vamos a enviar señales a través del puerto TX (trasmisión) del GPIO conectado al puerto RX (recepción) de la placa Arduino y recibir la respuesta en Orange Pi en el puerto RX conectado al TX de la Arduino. Asumo que tienes algo de experiencia con Arduino. Si no, lee algo y juega un poco antes de empezar. Es muy sencillo y hay muchos tutoriales con los que aprender de una forma rápida y sencilla.

Las placas Arduino son capaces de realizar lecturas y escrituras analógicas, es decir, todos los distintos valores con decimales, en una escala arbitraria, mientras que el pin GPIO de Orange Pi sólo es capaz de enviar y recibir señales digitales, es decir UNO o CERO (verdadero o falso).

Así que tendremos que hacer algo para conectar una placa con otra y que se entiendan. Hay varias maneras de hacerlo, y una de ellas es usando un conversor de niveles lógicos que también nos va a servir para igualar las tensiones a las que trabajan los dos dispositivos, ya que Arduino trabaja a 5V y la Orange Pi lo hace a 3.3v y evitar sobrecargas en el GPIO. Una imagen del que yo he usado y las conexiones.

Conversor de niveles lógicos 3.3v a 5v TTL bidireccional

Un poco más de luz sobre estas conexiones:

    Placa Orange Pi
  • 3.3v al pin 1 del GPIO
  • Ground pin 6
  • RX pin 8
  • TX pin 10
    Placa Arduino
  • 5v al pin 5v
  • Ground pin GND
  • RX pin TX->1
  • TX pin RX<-0

Ya tenemos conectadas las placas. Pon especial atención a los pines, porque un error podría dañarlas. Para enviar el código a Arduino, desconecta los cables RX y TX antes de conectarla al ordenador, porque si no, te dará fallo de escritura. Conecta la placa Arduino a través de USB al ordenador y pásale este código que nos servirá para probar si hay comunicación entre ambas placas.

byte test = 0;

void setup(){
	Serial.begin(9600);
}

void loop(){
	if (Serial.available()) {
		test = Serial.read();
		Serial.print("Caracter recibido: "");
		Serial.println(test, DEC);
	}
}

Ahora, dependiendo de la versión del kernel que estés utilizando puede que tengas activado, o no, el puerto de comunicaciones serie por hardware en los pines 8 y 10 (TX y RX), busca si existe algo como esto: /dev/ttyAMA0, o /dev/ttyS2 and /dev/ttyS3. Si no, tenemos que habilitar las comunicaciones serie a través de UART3 en estos pines. Empieza por convertir el archivo script.bin al formato FEX para poder editarlo:

cd /boot
sudo bin2fex script.bin script.fex

Edita script.fex:

sudo nano script.fex

Busca la sección [uart0] y configúralo para deshabilitar uart0-2 y habilitar uart3 con el modo de 2 pines en los pines 8 y 10:

[uart0]
uart_used = 0
uart_port = 0
uart_type = 2
uart_tx = port:PA04<2><1><default><default>
uart_rx = port:PA05<2><1><default><default>

[uart1]
uart_used = 0
uart_port = 1
uart_type = 4
uart_tx = port:PG06<2><1><default><default>
uart_rx = port:PG07<2><1><default><default>
uart_rts = port:PG08<2><1><default><default>
uart_cts = port:PG09<2><1><default><default>

[uart2]
uart_used = 0
uart_port = 2
uart_type = 4
uart_tx = port:PA00<2><1><default><default>
uart_rx = port:PA01<2><1><default><default>
uart_rts = port:PA02<2><1><default><default>
uart_cts = port:PA03<2><1><default><default>

[uart3]
uart_used = 1
uart_port = 3
uart_type = 2
uart_tx = port:PA13<3><1><default><default>
uart_rx = port:PA14<3><1><default><default>
uart_rts = port:PA15<3><1><default><default>
uart_cts = port:PA16<3><1><default><default>

Guarda los cambios y convierte de nuevo el formato de FEX a bin

sudo fex2bin script.fex script.bin

y reinicia. El nombre del dispositivo es ttyS3 y la velocidad por defecto es 57600. Ahora podemos ver que lo tenemos /dev

orangepi@orangepi2mini:~$ ls /dev/tty*
/dev/tty    /dev/tty19  /dev/tty3   /dev/tty40  /dev/tty51  /dev/tty62
/dev/tty0   /dev/tty2   /dev/tty30  /dev/tty41  /dev/tty52  /dev/tty63
/dev/tty1   /dev/tty20  /dev/tty31  /dev/tty42  /dev/tty53  /dev/tty7
/dev/tty10  /dev/tty21  /dev/tty32  /dev/tty43  /dev/tty54  /dev/tty8
/dev/tty11  /dev/tty22  /dev/tty33  /dev/tty44  /dev/tty55  /dev/tty9
/dev/tty12  /dev/tty23  /dev/tty34  /dev/tty45  /dev/tty56  /dev/ttyGS0
/dev/tty13  /dev/tty24  /dev/tty35  /dev/tty46  /dev/tty57  /dev/ttyGS1
/dev/tty14  /dev/tty25  /dev/tty36  /dev/tty47  /dev/tty58  /dev/ttyGS2
/dev/tty15  /dev/tty26  /dev/tty37  /dev/tty48  /dev/tty59  /dev/ttyGS3
/dev/tty16  /dev/tty27  /dev/tty38  /dev/tty49  /dev/tty6   /dev/ttyS3
/dev/tty17  /dev/tty28  /dev/tty39  /dev/tty5   /dev/tty60
/dev/tty18  /dev/tty29  /dev/tty4   /dev/tty50  /dev/tty61
orangepi@orangepi2mini:~$

Correcto, está en ttyS3. Vamos a usar un programa que envía y recibe señales a los puertos TX y RX en principio diseñado para comunicar con modems, pero nos sirve perfectamente para probar la comunicación. Se llama minicom y si no lo tienes instalado, instálalo con:

sudo apt-get install minicom

Ahora, con todos los cables conectados y la placa Arduino alimentada, ejecuta el programa.

minicom -b 9600 -o -D /dev/ttyS3
Welcome to minicom 2.7

OPTIONS: I18n
Compiled on Apr 26 2017, 00:45:18.
Port /dev/ttyS3, 13:26:16

Press CTRL-A Z for help on special keys

Para obtener ayuda y manejo del programa pulsa CTRL+a y luego z y obtendrás una pantalla de ayuda:

+-------------------------------------------------------------------+
|                      Minicom Command Summary                      |
|                                                                   |
|              Commands can be called by CTRL-A <key>               |
|                                                                   |
|               Main Functions                  Other Functions     |
|                                                                   |
| Dialing directory..D  run script (Go)....G | Clear Screen.......C |
| Send files.........S  Receive files......R | cOnfigure Minicom..O |
| comm Parameters....P  Add linefeed.......A | Suspend minicom....J |
| Capture on/off.....L  Hangup.............H | eXit and reset.....X |
| send break.........F  initialize Modem...M | Quit with no reset.Q |
| Terminal settings..T  run Kermit.........K | Cursor key mode....I |
| lineWrap on/off....W  local Echo on/off..E | Help screen........Z |
| Paste file.........Y  Timestamp toggle...N | scroll Back........B |
| Add Carriage Ret...U                                              |
|                                                                   |
|             Select function or press Enter for none.              |
+-------------------------------------------------------------------+

Si pulsas una tecla, Arduino te devolverá el valor decimal de la tecla pulsada. ¡Se están comunicando!. Genial. Para salir, pulsa CTRL+a, z y x. Ahora vamos a mover el servo. Desconecta la alimentación de la Arduino y los cables de TX y RX. El servo que yo he usado utiliza un pin a 5v, otro a masa (Ground) y otro para la recepción de datos. Conecta el de datos al Pin 9 y los otros a los correspondientes a la alimentación. Inyecta el siguiente código al Arduino, pero si lo copias y pegas de aquí, te dará problemas porque hay símbolos HTML. Abre el editor de Arduino y escríbelo:

#include <Servo.h>

Servo servoPan, servoTilt;
String data = "";
byte number = 0;
int grados = 90;
void setup() {
    
    servoPan.attach(9); 
    //servoTilt.attach(10); //Para 2 servos, movimiento vertical no usado
    Serial.begin(9600);
}

void loop(){
  if (Serial.available()) {
    char singleChar = Serial.read();
    
    Serial.print("Tecla pulsada: ");
    Serial.println(singleChar);

      if (singleChar == 'i'){
        if (grados < 170){
          Serial.print("Moviendo izquierda: ");
          Serial.println(grados);
          grados += 2;
          servoPan.write(grados);
        }

      } else if (singleChar == 'd'){
        if (grados > 20) {
          Serial.print("Moviendo derecha: ");
          Serial.println(grados);
          grados -= 2;
          servoPan.write(grados);  
        }
      }  else if (singleChar == 'c'){
          Serial.println("CENTRANDO");
          grados = 90;
          servoPan.write(grados);
        }     
  }
}

Abre de nuevo el programa de comunicaciones:

minicom -b 9600 -o -D /dev/ttyS3

y si ahora pulsas la tecla i el servo girará hacia la izquierda. Si pulsas d girará hacia la derecha y si pulsas c el servo irá a la posición centrada.

Un poco laborioso pero muy sencillo ¿verdad?. Ahora puedes recibir lecturas de sensores y mostrarlas o gestionarlas. Por ejemplo. Para escribir en un archivo las lecturas del puerto serie puedes usar programas como interceptty que capturará todas las comunicaciones por puerto serie.

Espero que te haya sido de utilidad, no dudes en escribir un comentario si ves algún error o si puedo ayudarte.


Utiliza este espacio si quieres añadir algún comentario adicional o si tienes alguna duda.

Todos los comentarios serán validados antes de su publicación.
  1. Andrés

    Lo que estaba buscando hace tiempo. Funciona perfecto, muchas gracias por este excellente trabajo.


  2. Santiago

    Vaya, genial tutorial y muy útil, también te felicito por el resto de la web, un buen sitio en español de Orange PI.

    Yo también conseguí mover un servo de manera similar pero conectando arduino por el puerto de serie al USB de la Orange pi pc plus, ya que no tengo el Conversor de niveles lógicos....

    De todas formas sigo intentando mover el servo directamente desde orangepi, ya que el proyecto estará siempre encendido 24x7 y creo que será mas eficiente si puedo prescindir de arduino. He leido que con JAVA y con C es posible. ¿Sabéis algo al respecto?

    Además entiendo que con java deberá ser bastante sencillo invocarlo desde una web...

    Un saludo.


  3. Javier

    Hola Santiago. Gracias. Si, también se puede conectar arduino a través del puerto serie igual que en un pc con Windows. En este tutorial quería probar otra cosa, pero si que puedes. Para instalar Java: http://orangepiweb.es/java-en-orange-pi.php

    Para PWM con C, instala WiringPI. Ya nos contarás. Saludos.



Nombre*

Email* Nunca será publicado ni compartido

Comentario*



Copyright © 2016. Todos los derechos reservados | Diseño JaviPSantos

Solicitamos su permiso para obtener datos estadísticos de su navegación en esta web, en cumplimiento del Real Decreto-ley 13/2012. Si continúa navegando consideramos que acepta el uso de cookies.

OK | Más información