Ir a contenido
Cómo conectar Arduino y Raspberry Pi por comunicación SPI - 330ohms

Cómo conectar Arduino y Raspberry Pi por comunicación SPI - 330ohms

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:

  • SCLK (Clock): Es el pulso que marca la sincronización. Con cada pulso de este reloj, se lee o se envía un bit.
  • MOSI (Master Output Slave Input): Salida de datos del Maestro y entrada de datos al Esclavo.
  • MISO (Master Input Slave Output): Salida de datos del Esclavo y entrada al Master.
  • SS/Select: Para seleccionar un Esclavo, o para que el Maestro le diga al Esclavo que se active. Se requiere uno por cada Esclavo.

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.

Componentes necesarios

  • Raspberry Pi, cualquier modelo
  • Arduino UNO
  • Protoboard mini o chica
  • Resistor de 330 ohms
  • Led 5mm
  • Cables de conexion M-M y H-M
  • Convertidor de nivel lógico bidireccional – 3.3V <-> 5V TTL

Conexiones

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.

Raspberry Pi – Arduino Uno – SPI

Pasos previos a ejecutar el código

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.

Código de Arduino – Ardiuno Uno

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…

Código de Python3 – Raspberry Pi

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 ") 

¡Sigue explorando!

Artículo anterior Tutorial #8 de Raspberry Pi Pico: sensor ultrasónico - 330ohms