bclose

El bus SPI

Arduino y el Serial Perifereal Interface
tienda online prometec

Objetivos

 

 

    • Comprender los problemas de la comunicación serie.
    • Presentar el bus SPI.
    • Mostrar la conexión con uno y con múltiples esclavos.
    • Ventajas e inconvenientes con el Bus I2C.
 

Material requerido.

 

 Imagen de Arduino UNO Paciencia y buena disposición de espíritu, porque esta va ser una de esas sesiones teóricas que si bien te puedes saltar casi sin que se note, es conveniente que entiendas los conceptos que hay detras de un bus de comunicaciones.

Esta sesión es prácticamente una traducción literal de la página de Sparkfun en inglés sobre el mismo tema, que podéis encontrar en

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

Los errores que haya en esta sesión son ciertamente míos, pero lo que de bueno hay es directamente atribuible a Sparkfun.

La comunicación serie

 

Si ya tenemos un protocolo de transmisión de datos asíncrono como las puertas series que vimos anteriormente ¿Por qué necesitamos otro bus serie? ¿Hay algo malo con la comunicación  serie del que no hayamos hablado?

Teóricamente no hay ningún problema, pero ya sabéis que el demonio está en los detalles, y así dijimos que bastaba con definir una velocidad común para transmitir datos inmediatamente entre dos puntos, pero la realidad es terca.

No tenemos ninguna garantía de que ambos extremos estén, de hecho, a la misma velocidad, lo que puede hacer que enviamos todos nuestros datos y la otra parte no se entere, bien porque no está a la misma velocidad o bien porque sencillamente esta en babia.

No tenemos ninguna manera de garantizar que la otra parte ha recibido el mensaje, sencillamente suponemos que todo ha ido bien.

 
  • Este es un buen momento para mencionar la ley de Murphy, que dice que si algo puede ir mal, seguro que irá mal y además en el peor momento.
  • Todavía hay mucha gente que cree que Murphy era un pesimista, ademas de un cachondo, pero no. Algún día recibirá el reconocimiento que merece.
 

El primer problema que suele aparecer es que las velocidades a en los dos extremos sean diferentes. Fin de la comunicación (Seguro que a estas alturas ya habéis experimentado este problema entre Arduino y la consola en algún momento)

El segundo problema es que la forma de fijar la velocidad pactada se debe hacer con un reloj propio a cada extremo. O sea dos relojes a poner de acuerdo, Murphy se frota las manos. Es cuestión de tiempo de que pequeñas diferencias entre los cuarzos que los sincronizan den lugar a problemas de comunicación.

Para corregir este problema, en las comunicaciones seria se pacta otro aspecto que hasta ahora no habíamos comentado, Se añade un par de bits extra a la comunicación en forma de un bit de Start y otro de Stop. (Fijaros que para enviar 8 bits de datos ahora tenemos que enviar 10 bits)

Start y Stop bits

De este modo aumentado en un 25% (8bits / 2) en la carga de trasmisión serie, podemos re sincronizar los relojes de ambos extremos usando estos bits de Start y Stop.

Pero esto supone además un aumento en el hardware para decodificar la señal y sincronizar los relojes. Y puestos a complicar las cosas ¿Porque no buscar una solución síncrona al problema?

La solución que dio la industria fue múltiple, entre las que se encuentran el bus I2C que ya vimos en su día y el bus SPI que vamos a ver ahora.

 

El bus SPI, Una solución síncrona

 

El SPI es un protocolo de comunicación  síncrona de 4 hilos, entre dispositivos electrónicos presentado por Motorola en 1982, que ha ganado bastante aceptación en la industria como sistema de comunicación de muy corta distancia, normalmente dentro la placa de circuito impreso.

Es un protocolo de transmisión que permite alcanzar velocidades muy altas y que se diseñó pensando en comunicar un micro controlador con distintos periféricos y que funciona a full dúplex (Una forma retorcida de decir que puede enviar y recibir datos al mismo tiempo).

SPI utiliza una solución síncrona, porque utiliza unas líneas diferentes para los datos y el Clock. El Clock es una señal que indica al que escucha exactamente cuándo leer las líneas de datos, con lo que el problema de perdida de sincronía se elimina de raíz.

Clock y Data

Por eso mismo, no se necesita pactar  la velocidad de transmisión, ya que será el Clock quien fije la velocidad y puede ser variable a lo largo de la comunicación sin que sea un problema (Aunque por supuesto según el dispositivo habrá un límite de velocidad).

Uno de los motivos por los que SPI es tan popular es que el hardware de recepción puede ser un sencillo Shift register como los que vimos en la sesión N,  Lo que es una solución mucho más simple (Y barata) que una UART (Universal Asíncronous Receiver Transmitter o  sistema universal asíncrono de recepción y transmisión serie) de comunicación serie.

 

Como se reciben los datos

 

En un bus SPI una de las partes genera el Clock al que llamamos master, y el resto son los esclavos, pudiendo haber uno o varios en el bus. A la señal de reloj se le suele llamar CLK por Clock o SCK por Serial Clock.

Cuando el master envía información, lo hace por una línea de datos que normalmente de nombre MOSI (Master Out Slave In) y si el esclavo responde lo hace a través de una línea llamada MISO (Master In Slave Out) siguiendo una de esas tradiciones de imaginación desbordante en los nombres tecnológicos.

Lineas SCK MOSI y MISO

Como es el master quien genera el Clock, necesita saber de antemano, si un esclavo va a devolver una respuesta y de que longitud, para mantener el Clock hasta que la transferencia esté completa.

Esto no es normalmente un problema porque cuando el master pide a, digamos un sensor, que le envié una lectura, normalmente sabemos que van ser 2 bytes.

 

Selección de esclavo Slave Select SS

 

Hay una última línea de control, llamada Slave Select o SS, que indica a un esclavo que el mensaje que viene es para él, o bien que se reclama que envié una respuesta a una petición del master.

SCK, MOSI, MISO y SS lines

La línea SS normalmente se mantiene HIGH y se activa con LOW, lo que despierta al esclavo seleccionado. Cuando se termina la transferencia la línea se levanta a HIGH y el esclavo se desactiva.

 

Bus con múltiples esclavos

 

Hay dos maneras de conectar múltiples esclavos a un bus SPI. Con una línea SS por cada esclavo o en cascada:

En general cada esclavo requiere su propia línea SS para ser activado, y así evitar que dos hablen a la vez, porque el resultado sería ruido inútil. Basta con activar la línea correspondiente y el esclavo esta listo para recibir sus órdenes

Es un sistema cómodo, siempre y cuando no sean muchos esclavos porque podemos necesitar muchas líneas.

Multiple Slave Select

Cuando el número de esclavos crece suele ser más frecuente conectarlos en cascada, con el MISO de uno (Salida), conectado al MOSI (Entrada) del siguiente. En este caso solo usamos una única línea SS, que se comparte entre todos los esclavos.

Esta configuración es típica de una situación en la que le master envía datos pero no recibe nada de vuelta, como en el caso de una cadena de múltiples  display LEDs ( Matrices de 8×8) , en los que se envía información para ser mostrada pero, no hay datos de vuelta. En este caso incluso podemos desconectar la línea MISO

Daisy chain en el bus SPI

Por último y para cerrar esta sesión, comentar que naturalmente vuestro Arduino soporta de serie el bus SPI, con una librería estándar que sorprendentemente se llama SPI y que podéis instalar tranquilamente, que gestiona todas las complicaciones y el arbitraje del protocolo.

 

Comparación con I2C y con puerto serie normal

 

Ventajas del Bus SPI

 
  • Comunicación Full Duplex. Envía y recibe a la vez lo que aumenta la velocidad.
  • Más rápido que el I2C y que el puerto Serie asíncrono normal
  • El tamaño de los mensajes puede ser arbitrariamente grande
  • Se requiere un hardware sencillo (Léase barato)
  • Requiere un menor consumo y menor electrónica de conexión que el I2C
  • Como el Clock lo proporciona el master, los esclavos no necesitan osciladores ( O sea, otra vez más barato)
 

Y como en la vida no hay nada gratis, las desventajas son:

 
  • Necesita más pines que el I2C o el Puerto serie normal.
  • Las comunicaciones tiene que estar perfectamente establecidas de antemano. No puedes enviar mensajes de diferentes longitudes cuando te convenga.
  • No hay señal de conforme del esclavo, se espera que obedezca y punto.
  • Master único y casi sin posibilidad de master múltiple
  • Funciona solo en distancias muy cortas
  • Normalmente necesita un pin adicional por cada esclavo y si el número de esta creces puede acabar siendo un problema.
 

 

Pines SPI en Arduino

 

Aunque últimamente han aparecido algunas librerías que nos permiten mover de sitio los pines de control del SPI en nuestros Arduino, tradicionalmente estos, estaban fijados a unos ciertos pines.

Eso significa, que para controlar el bus SPI es necesario usar esos pines inexcusablemente, aunque podemos elegir entre dos juegos de ellos, entre ciertos pines digitales, según el modelo y la tabla que especificamos abajo, y usando los equivalentes en el bus ICSP.

Esos pines son:

Modelo ArduinoMOSIMISOSCKSS SlaveSS Master
UNO11, ICSP-412, ICSP-113, ICSP-310Z
MEGA51, ICSP-450, ICSP-152, ICSP-353Z
LeonardoICSP-4ICSP-1ICSP-3Zz
DUEICSP-4ICSP-1ICSP-3z4,10,52
 
  • Fijate que aunque los pines del bus SPI cambian según el modelo de Arduino que usemos, siempre son los mismos en el ICSP.
  • Eso permite diseñar Shields coherentes con todos los modelos de Arduino.
 

Los pines ICSP son esos que están a la derecha centrados cuando leemos los rotulos en la placa: 

COmm bus pinot
Arduino ICSP

 

Resumen de la sesión

 

 

    • Hemos tratado de mostrar porque hay ocasiones en los que el puerto serie tiene limitaciones graves.
    • Presentamos el bus SPI y sus líneas de control.
    • Vimos como conectar múltiples esclavos al bus.
    • Hablamos de las ventajas e inconvenientes de este bus con respecto al bus I2C que vimos en sesiones previas, y con la comunicación serie normal.

 

 

 

 

(31) Comments

    • Juan reina

    hola buenas! enhorabuena por los post y los tutoriales en general, personalmente son de gran ayuda.
    Estoy con un proyecto de enviar datos de 2 sensores de temperatura ( dht22 y sonda termopar k con amplificador max31856 ). Tengo arduino UNO con la shield Ethernet w5100( comunicación con UNO a través
    de SPI) el problema viene cuando intento ver los datos del amplificador max31856, que tambien tiene comunicación por SPI. No llego a entender muy bien la manera de hacer el código para que la shield y el amplificador
    puedan enviar los datos, no me hace falta que sean a la vez. No se si alguien haya conseguido algún código de maestro con dos esclavos como es mi caso. Seguire el hilo de comentarios por si alguien se le ocurre algo.
    Muchas gracias de ante mano. Un saludo

  • Hola, como comentan estaría bien un ejemplo de como hacer lo de mas de un módulo SPI, tengo mucho tiempo buscando alguno y no encuentro, ojalá lo hagan. Saludos.

    • Pues sí… Andamos un poco mal de tiempo pero es algo que tenemos que hacer.

  • Hola deseo conectar el ICSP QUE VIENE CON EL MAX6675 al arduino pero por medio de LABVIEW como hago he tratado pero no puedo me gustaria que me ayudaras gracias

    • Me temo que no puedo ayudarte con Labview, a ver si hay alguien que pueda echarte una mano. Un saludo.

  • Hola! primero que nada muy buen post! y me queda una pregunta para un proyecto que tengo. Deseo comunicar dos arduinos a una distancia apróximada de 4m, ¿crees conveniente hacer la comunicación con SPI o que protocolo crees más conveniente?, o quiza sea bueno con este protocolo pero solo debo tener un cableado bien blindado de ruido.
    Espero tus comentarios.
    Saludos!

    • Hola David, yo probablemente usaría radiofrecuencia, así te evitas tirar cables. Es barato y sencillo de programar. Un saludo.

  • hola , podria indicarme como comunicarme a full duplex mi arduino due con mi ordenador ? ya sea por SPI o serial , no logro comunicarme , gracias

    • Hola Zosimo, el SPI del DUe es completamente normal por lo que yo se por lo que cualquier programa con el SPI deberia valerte

    • Sliver

    Como podria usar los pines 11,12,13 si quiero conectar una lcd en estos en lugar del SPI?

    • Hola Silver, no hay problema en que conectes el LCD siempre y cuando luego no uses el SPI

  • Buenos días.
    Mi nombre es Jorge Benitez, soy estudiante de ingeniería y actualmente me encuentro desarrollando un proyecto de adquisición y supervisión.
    Estoy usando empleando la capa física Ethernet y el protocolo Modbus TCP para comunicar el Arduino (Servidor) con una interfaz HMI en visual (Cliente).
    El sistema requiere alarmas empleando el servicio SMS de la red GSM, para lo cual estoy empleando el Shield GSM/GPRS basado en el chip Wiznet 5100.
    Actualmente se me está presentando un problema, y es que cuando la HMI da la orden de enviar la alarma, la comunicación entre el HMI y el Servidor se cierra producto de un error en el socket remoto.
    Quisiera saber: ¿es posible usar la librería SPI en conjunto a una comunicación serial?.
    Muchas gracias por su ayuda y felicidades por su página, desde hace tiempo la sigo y la recomiendo a mis conocidos.

    • Hola Jorge, pues la verdad es que no tengo ni idea de por qué te puede dar ese error. En cuanto a la pregunta, la mejor manera es que lo pruebes. En principio el SPI no utiliza los pines del puerto serie, pero no estoy seguro si te dará algún problema. Un saludo.

    • Albert

    Estimados, usar el bus SPI para varios dispositivos se usan los pines comunes 11, 12 y 13, y el CS distinto para cada dispositivo, hasta allí todo OK (la mayoría de los comentarios asi lo dicen) . En la red hay mucha teoría sobre SPI, pero no hay ejemplos de software (en arduino) de la programación de 2 o mas dispositivos SPI, allí el dilema en que estoy (batallando ya varios días) y veo que la mayoría de foristas comenta y están en lo misma. Con tan un solo ejemplo de programación de de SPI (un Maestro y dos esclavos) creo que seria de gran ayuda.

    • Hola Albert, es una gran idea lo que comentas. Intentaremos hacer un tutorial con varios componentes SPI a ver qué problemas podemos tener. Esperemos que pueda ser pronto… un saludo.

    • Felipe

    Hola, muy agradecido por tus cursos! son un gran aporte. Quisiera plantear una consulta, que tipo de comunicación sugieres (entre dos arduino) en el caso que uno de ellos tenga por obligación una interrupción por timer que se ejecuta cada 50 micro segundos (es muy rapida). Por que con serial al menos no lo he logrado. La cantidad de información es muy pequeña pero dada la rapidez con que se repite la interrupción, no logro conseguirlo por serial.

    Atte. Felipe

    • Pues a mí a parte de SPI sólo se me ocurre hacerlo serie o I2C, pero creo que el I2C sería más lento que el serie, y parece que no consigues que sea suficientemente rápido. A ver si tengo tiempo para investigarlo un poco y te puedo decir algo más.

  • Hola, tengo una duda. Tengo un mega 2560 core (imitación del arduino) y quiero comunicarme utilizando SPI con un controlador, MCP 2515. El problema es que al controlado MCP 2515 le llegan los mensajes que yo envío, pero este controlador no los envía a su vez al transceptor MCP 2551, y por tanto no me puedo comunicar con los sensores que deseo. ¿A que puede ser debido?¿ necesito darle alguna instrucción al MCP 2515?
    Gracias

    • Pues la verdad es que no voy a poder ayudarte mucho porque nunca he usado ese chip MCP 2551, así que ando un poco perdido.

  • Hola buenos dias.
    Tengo una duda, he realizado un robot para mi hijo del estilo a Zowi y el problema que tengo es que queria que mostrase simbolos en una matriz led con el MAZ7219 y a la vez emitiese un sonido o grabacion que tengo en una tarjeta SD. Si monto los circuitos independientes no tengo problema pero a la vez no lo consigo. he utilizado el pin 6 para activar el CS del adaptador tarjeta SD y el resto de patillas al puerto ISCP y para el MAX7219 utilizo el pin 10 para el CS, el pin 11 para CLK y el pin 12 para el DIN.
    Me podeis dar alguna idea de como implementarlo en el codigo arduino.

    MUCHAS GRACIAS.

    • Juan Fran te ayudariamos encantados pero no es posible sin conocer mucho mas de tu robot, lo siento

      • Hola y muchas gracias por la rapida respuesta. De momento tengo una placa Arduino UNO, una matrid led con MAX7219 y un lector de tarjetas micro SD. He intentado sacar en la matriz un simbolo y con la micro SD reproducir un sonido para decir el resultado (si sale un corazon, en el altavoz se escucha la palabra corazon), pero solo consigo hacerlo la primera vez ya que despues en la matriz led se encienden todos los led y ya no cambia.

        MUCHAS GRACIAS.

  • Hola, una pregunta, si quiero recibir datos de tres esclavos en un maestro simultáneamente ¿como podría poner los tres esclavos activos? Lo intento poniendo el pin SS del primer esclavo en LOW, recibe los datos y lo mando a HIGH y así ahora para el siguiente dispositivo, pero no funciona sólo me deja recibir datos de un dispositivo. ¿Alguna sugerencia? Muchas gracias

    • Hola Gina,

      La idea de un bus de comunicaciones es precisamente arbitrar los turnos a los que habla cada nodo para evitar que hablen a la vez y usas el SS para decidir a quien corresponde el turno. Por eso no puedes activar varios nodos a la vez ¿Vale?

  • Cordial saludo, excelentes y muy explícitos los temas expuestos, felicitaciones y muchas gracias, este arduo camino del aprendizaje… jamás termina.
    Permítame preguntarle, al hacer las conexiones para quemar el bootloader del ATMEGA 328 desde arduino uno, el pin SS (D10) va conectado al reset del AT328 a programar, pero si se hace esta misma programación desde un arduino mega los pines SS tanto del mega como el del At328 a programar, van unidos.
    Porque no hacerlo de una u otra forma igual para ambos casos? Gracias de antemano.

    • Pues no sabria decirte Jorge, pero ten en cuenta que el micro del Mega es mucho mas evolucionado que el del arduino UNO y eso en muchas ocasiones supone diferente hardware y diferentes necesidades

    • Gina

    Hola buenas tardes, tengo programada mi tft LCD touch y trabaja muy bien, ella posee una sd desde donde carga las imagenes en la pantalla, hasta ahi todo bien, ahora necesito tomar valores de los sensores y guardarlos en una memoria, para esto dispongo de un modulo sd card, el inconveniente esta en que las dos memorias usan la misma comunicacion la cual es SPI, tengo entendido que no hay rollo con esto, que se pueden conectar varios dispositivos al SPI y que basta con cambiar el pin SDCS y hacer ajustes en el codigo pero aun no lo logro, he intentado de varias maneras pero no me sale, Agradezco me puedas colaborar.

    • Hola Gina, Para usar varios dispositivos SPI en un mismo bus basta con actives el pin Chisp Select o CS del dispositivo que quieres direccionar y eso es todo al menos en teoria. Asegurate de usar un pin arduino diferenete para hacer el CS por cada elemento

    • Alexis

    Hola, tengo un proyecto en arduino UNO, osea resumiendo, puedo conectar por ejemplo un nrf24l01 y un lector SD, los 2 en la misma placa arduino UNO? le hice un auto a control a mi hijo con transmisor 2,4ghz, pero quisiera agregarle audio desde una tarjeta sd, con 2 arduinos independiente lo hago funcionar uno recibe datos, y el otro saca musica de la memoria sd, pero ambos juntos en un chip atmega 328? Gracias

    • Hola Alexis.
      Aunque yo no lo he probado, si se puede. Todos comparten las línes MOSI, MISO y CLK y la línea SS es una para cada esclavo, que la defines tú con los pines digitales que elijas. Importante: no olvidarte que el pin SS en el Uno (el 10) defínelo como OUTPUT aunque no lo uses, para que te funcione todo. Ya la parte de programación, quizás Admin pueda aconsejarte más pues no lo he probado, pero sí se puede configurar.

      Saludos.

    • Hola Alexis, deberia spoder con un unico arduino UNO, porque eso de tenerque poner dos parece poco eficiente. Me imagino que lo mas sencillo seria que usaras un shield mp3 para colocarlo con comodidad al UNO y sacar la conexion al NRF2401

Give a Reply

WordPress Anti-Spam by WP-SpamShield

¡Ofertón!

Robot Rover 4×4

Ahora por sólo

50€ + IVA

¡Lo quiero!