Approved Reseller
Approved Reseller
En este pequeño tutorial veremos cómo conectar una tarjeta Arduino a una tarjeta Raspberry Pi por comunicación SPI, encontrarás códigos de programación para tus primeras pruebas.
La comunicación SPI se implementa con 4 señales digitales:
Tanto la tarjeta Arduino Uno como las tarjetas Raspberry Pi cuentan con hardware integrado para implementar el protocolo. Como lo indica la descripción de las señales, los dispositivos comunicados por SPI pueden ser “Maestros” o “Esclavos”, siempre habrá un solo Maestro mientras que el número de esclavos puede ir desde 1 hasta el número de pines con los que podamos implementar señales SS
El ejercicio que realizaremos consiste, entonces, en controlar un LED conectado al pin #4 del Arduino desde la Raspberry Pi. Para ello ejecutaremos un script de python que solicite al usuario insertar un comando para ser enviado al Arduino a través del protocolo SPI, éste a su vez, estará programado para recibir todos los comandos respondiendo solo a 2: «on» para encender el LED y «off» para apagar el LED.
Utilizamos un convertidor de nivel lógico para conectar las señales de ambas tarjetas, esto es importante porque trabajan con distintos niveles lógicos de voltaje, el Arduino tienen un nivel lógico de 5V y la Raspberry Pi de 3.3V. Conectar las señales directamente podría resultar en un daño a la tarjeta con nivel lógico menor, es decir, la Raspberry Pi.
Para que podamos ejecutar un programa que intercambie información a través del protocolo SPI en nuestra Raspberry Pi, debemos habilitar el hardware correspondiente en dicha tarjeta. Esto lo podemos hacer de manera sencilla con ayuda de la herramienta de configuración raspi-config, si no has utilizado esta herramienta antes da click aquí para ver el paso a paso. Una vez que termines regresa para continuar con este tutorial.
Cargamos el siguiente código a nuestra tarjeta Arduino Uno:
#include char buf [100];//Definimos el arreglo de caracteres que será nuestro buffer de recepción volatile byte pos; //Indice auxiliar para administrar el índice del arreglo "buf" volatile boolean process_it; //Bandera auxiliar para saber cuando hemos recibido un comando char on[] = {111,110,10}; //Arreglo de carácteres correspondientes a la cadena "on\n" char off[] = {111,102,102,10}; //Arreglo de carácteres correspondientes a la cadena "off\n" int pin_led = 14; //Pin al cual se conecto la señal del led void setup (void) { Serial.begin (9600); pinMode(pin_led, OUTPUT); // Configuramos como salida el pin correspondiente a la salida de datos por parte del esclavo pinMode(MISO, OUTPUT); // Establecemos el modo de esclavo SPCR |= _BV(SPE); pos = 0; // buffer vacio process_it = false; //bandera auxiliar para indicar cuando un comando completo se encuentra en buffer // Habilitamos interrupciones por SPI SPI.attachInterrupt(); } // fin de setup // Rutina de interrupción SPI ISR (SPI_STC_vect) { byte c = SPDR; // tomamos el byterecibido que se encuentra en el registro de datos SPI //si contamos con espacio agregamos el byte a la cadena de caracteres if (pos < sizeof buf) { buf [pos++] = c; //Agregamos el caracter recibido // Si el caracter actual es un salto de línea sabemos que hemos recibido un comando completo if (c == '\n') process_it = true;//Levantamos la bandera } } // fin de la rutina de interupción SPI void loop (void) { if (process_it)//Si la bandera esta levantada procesamos el comando recibido { if(array_cmp(on,buf,3,pos)) digitalWrite(pin_led, 1); if(array_cmp(off,buf,4,pos)) digitalWrite(pin_led, 0); pos = 0; process_it = false; } // fin del procesamiento del comando recibido } // fin del loop boolean array_cmp(char *a, char *b, int len_a, int len_b){ int n; // Si la longitud es distinta regresa FALSO y terminamos la función if (len_a != len_b) return false; // Comparramos pares de bytes formados por los los elementos que tienen el mismo índice en sus respectivos arreglos //Si algún par está formado por bytes distintos, regresa FALSO y termina la función for (n=0;n
Para seguir leyendo…
Copiamos el siguiente código a un script de python en nuestra Raspberry Pi y lo ejecutamos con Python3. Al ejecutarlo, el programa solicitará ingresar un comando, el comando será enviado al Arduino al oprimir la tecla «Enter». Con el comando «on» se enciende el led integrado del Arduino y con el comando «off» se apaga.
# Importamos los paquetes necesarios import RPi.GPIO as GPIO #Para controlar pines de la tarj$ import spidev #Para implementar comunicación SPI import time GPIO.setmode(GPIO.BCM) #Definimos el modo para referirnos a los pines de la Raspberry Pi spi = spidev.SpiDev() #Creamos el objeto spi spi.open(0,0) #Abrimos el puerto SPI - Módulo 0, Dispositivo 0 spi.max_speed_hz = 5000 #Establecemos la velocidad máxima -->muy importante<-- try: while True: comando = input("Ingresar comando (on/off): ") #Solicitamos ingresar comando comando = comando + "\n" #Agregamos salto de línea al final del comando ingresado comando = comando.encode() #Convertimos el comando a un arreglo de bytes spi.xfer(comando) #Mandamos el comando time.sleep(0.25) #Esperamos 0.25 except KeyboardInterrupt: # Ctrl+C print ("Interrupción por teclado") finally: spi.close() GPIO.cleanup() print ("GPIO.cleanup() y spi.close() ejecutados ")