Tutorial: Arduino y el bus SPI

Este es el primero de dos capítulos en los que vamos a empezar a investigar el bus de datos SPI, y cómo podemos controlar los dispositivos que lo usan con nuestros sistemas Arduino.

El bus SPI puede parecer una interfaz compleja de dominar, sin embargo, con un breve estudio de esta explicación y ejemplos prácticos, ¡pronto se convertirá en un maestro de bus! Para hacer esto, aprenderemos la teoría necesaria y luego la aplicaremos controlando una variedad de dispositivos. En este tutorial, las cosas se mantendrán lo más simples posible.

Pero en primer lugar, ¿qué es? Y algo de teoría SP

SPI es un acrónimo de «Interfaz periférica en serie». Es un bus de datos serie síncrono: los datos pueden viajar en ambas direcciones al mismo tiempo, a diferencia de (por ejemplo) el bus I2C que no puede hacerlo. Para permitir la transmisión de datos síncrona, el bus SPI utiliza cuatro cables. Se llaman:

  • MOSI-Master-out, Slave-in. Esta línea transporta datos de nuestro Arduino a los dispositivos controlados por SPI;
  • MISO-Master-in, Slave out. Esta línea transporta datos de los dispositivos controlados por SPI de vuelta al Arduino;
  • SS – Slave-select. Esta línea le dice al dispositivo en el autobús que deseamos comunicarnos con él. Cada dispositivo SPI necesita una línea SS única de vuelta al Arduino;
  • Reloj serie SCK.

Dentro de estos tutoriales, consideramos que la placa Arduino es la maestra y los dispositivos SPI son esclavos. En nuestras placas Arduino Uno y compatibles, los pines utilizados son:

  • SS – digital 10. Puede usar otros pines digitales, pero 10 es generalmente el valor predeterminado, ya que está junto a los otros pines SPI;
  • MOSI-digital 11;
  • MISO-digital 12;
  • SCK-digital 13;

Usuarios de Arduino Mega: MISO es 50, MOSI es 51, SCK es 52 y SS generalmente es 53. Si está utilizando un Arduino Leonardo, los pines SPI están en los pines del encabezado ICSP. Consulte aquí para obtener más información. Puede controlar uno o más dispositivos con el bus SPI. Por ejemplo, para un dispositivo, el cableado sería:

sspiss1

Los datos viajan de ida y vuelta a lo largo de las líneas MOSI y MISO entre nuestro Arduino y el dispositivo SPI. Esto solo puede suceder cuando la línea SS se establece en BAJA. En otras palabras, para comunicarnos con un dispositivo SPI en particular en el bus, establecemos la línea SS en ese dispositivo en BAJO, luego nos comunicamos con él y luego establecemos la línea de nuevo en ALTO. Si tenemos dos o más dispositivos SPI en el bus, el cableado se asemejaría a lo siguiente:

sspiss2

Observe cómo hay dos líneas SS: necesitamos una para cada dispositivo SPI en el bus. Puede utilizar cualquier pin de salida digital libre en su Arduino como línea SS. Solo recuerde tener todas las líneas SS altas, excepto la línea conectada al dispositivo SPI que desee usar en ese momento.

Los datos se envían al dispositivo SPI en forma de bytes. Ya debe saber que ocho bits forman un byte, por lo tanto, representan un número binario con un valor entre cero y 255.

Al comunicarnos con nuestros dispositivos SPI, necesitamos saber de qué manera el dispositivo trata con los datos: MSB o LSB primero. MSB (bit más significativo) es el lado izquierdo del número binario, y LSB (bit menos significativo) es el lado derecho del número. Eso es:

binnum

Además de enviar valores numéricos a lo largo del bus SPI, los números binarios también pueden representar comandos. Puede representar ocho configuraciones de encendido/apagado utilizando un byte de datos, por lo que los parámetros de un dispositivo se pueden establecer enviando un byte de datos. Estos parámetros variarán con cada dispositivo y deben ilustrarse en la hoja de datos del dispositivo en particular. Por ejemplo, un CI potenciómetro digital con seis potes:

sdata1

Este dispositivo requiere dos bytes de datos. El byte ADDR le dice al dispositivo cuál de los seis potenciómetros controlar (numerados de 0 a 5), y el byte de DATOS es el valor para el potenciómetro (0~255). Podemos usar enteros para representar estos dos valores. Por ejemplo, para establecer el potenciómetro número dos en 125, enviaríamos 2 y luego 125 al dispositivo.

¿Cómo enviamos datos a dispositivos SPI en nuestros bocetos?

En primer lugar, necesitamos usar la biblioteca SPI. Se incluye con la instalación IDE de Arduino predeterminada, así que ponga lo siguiente al inicio de su croquis:

#include "SPI.h"

A continuación, en void.setup() declara qué pin(s) se usarán para SS y los establece como SALIDA. Por ejemplo,

pinMode(ss, OUTPUT);

donde ss se ha declarado previamente como un entero de valor diez. Ahora, para activar el bus SPI:

SPI.begin();

y, finalmente, necesitamos decirle al boceto de qué manera enviar datos, MSB o LSB primero utilizando

SPI.setBitOrder(MSBFIRST);

o

SPI.setBitOrder(LSBFIRST);

Cuando sea el momento de enviar datos por el Bus SPI a nuestro dispositivo, tres cosas tienen que suceder. Primero, establezca el pin digital con SS en bajo:

digitalWrite(SS, LOW);

Luego envíe los datos en bytes, un byte a la vez usando:

SPI.transfer(value);

El valor puede ser un entero/byte entre cero y 255. Finalmente, cuando termine de enviar datos a su dispositivo, finalice la transmisión configurando SS high:

digitalWrite(ss, HIGH);

Enviar datos es bastante simple. Por lo general, la parte más difícil para las personas es interpretar la hoja de datos del dispositivo para comprender cómo deben estructurarse los comandos y los datos para la transmisión. Pero con algo de práctica, estos pequeños obstáculos se pueden superar.

¡Ahora algunos ejemplos prácticos!

Es hora de subirse al bus SPI y controlar algunos dispositivos. Siguiendo los ejemplos a continuación, debe obtener una comprensión práctica de cómo se pueden usar el bus SPI y los dispositivos con nuestras placas Arduino.

MCP4162 Ejemplo

Nuestro primer ejemplo utilizará una parte simple pero interesante: un potenciómetro digital (también usamos uno en el tutorial de I2C). Esta vez tenemos un reóstato de 10k de la serie MCP4162 de Microchip:

digipotss

Aquí está la hoja de datos para su lectura. Para controlarlo necesitamos enviar dos bytes de datos: el primer byte es el byte de control, y afortunadamente para este ejemplo siempre es cero (ya que la dirección para el valor del limpiaparabrisas es 00h ). El segundo byte es el valor para configurar el limpiaparabrisas, que controla la resistencia. Así que para configurar el limpiaparabrisas necesitamos hacer tres cosas en nuestro boceto

Primero, establecer la línea SS (slave select) en baja:

digitalWrite(10, LOW);

Luego enviar los dos byes de datos:

SPI.transfer(0); // command byteSPI.transfer(value); // wiper value

Finalmente establecer la línea SS de nuevo en alta:

digitalWrite(10, HIGH);

Fácil de hacer. La conexión a nuestra placa Arduino es muy simple, considere el pinout MCP4162:

mcp4162pinout

Vdd se conecta a 5V, Vss a GND, CS a digital 10, SCK a digital 13, SDI a digital 11 y SDO a digital 12. Ahora veamos los valores disponibles del MCP4162 en el siguiente croquis:

/* SPI bus demo using a Microchip MCP4162 digital potentiometer */#include "SPI.h" // necessary libraryint ss=10; // using digital pin 10 for SPI slave selectint del=200; // used for various delaysvoid setup(){ pinMode(ss, OUTPUT); // we use this for SS pin SPI.begin(); // wake up the SPI bus. SPI.setBitOrder(MSBFIRST); // our MCP4162 requires data to be sent MSB (most significant byte) first}void setValue(int value){ digitalWrite(ss, LOW); SPI.transfer(0); // send command byte SPI.transfer(value); // send value (0~255) digitalWrite(ss, HIGH);}void loop(){ for (int a=0; a<256; a++) { setValue(a); delay(del); } for (int a=255; a>=0; --a) { setValue(a); delay(del); }}

Ahora para ver los resultados del croquis. En el siguiente videoclip, a recorremos el rango de resistencia y medimos el valor del reóstato con un multímetro:

Antes de seguir adelante, si los potenciómetros digitales son nuevos para usted, considere leer esta breve guía escrita por Microchip sobre las diferencias entre los potenciómetros mecánicos y digitales.

Otro ejemplo:

En este ejemplo, utilizaremos el potenciómetro digital de cuatro canales AD5204 de Analog Devices (hoja de datos.pdf). Contiene cuatro potenciómetros lineales de 10 k ohmios, y cada potenciómetro es ajustable a una de las 256 posiciones.

Los ajustes son volátiles, lo que significa que no se recuerdan cuando se apaga la alimentación. Por lo tanto, cuando se aplica la potencia, todos los potenciómetros están preestablecidos en el centro de la escala. Nuestro ejemplo es el ejemplo de montaje en superficie SOIC-24, sin embargo, también se fabrica en formato DIP.

ad5204ss

Para facilitar la vida, se puede soldar en una placa de desbloqueo SOIC que la convierte en un paquete de orificio pasante:

ad5204boardss1

En este ejemplo, controlaremos el brillo de cuatro Ledes. El cableado es muy simple. Los pines están en la hoja de datos.

ex34p2schematic1

Y el boceto:

#include <SPI.h> // necessary libraryint ss=10; // using digital pin 10 for SPI slave selectint del=5; // used for fading delayvoid setup(){ pinMode(ss, OUTPUT); // we use this for SS pin SPI.begin(); // wake up the SPI bus. SPI.setBitOrder(MSBFIRST); // our AD5204 requires data to be sent MSB (most significant byte) first. See data sheet page 5 allOff(); // we do this as pot memories are volatile}void allOff()// sets all potentiometers to minimum value{ for (int z=0; z<4; z++) { setPot(z,0); }}void allOn()// sets all potentiometers to maximum value{ for (int z=0; z<4; z++) { setPot(z,255); }}void setPot(int pot, int level)// sets potentiometer 'pot' to level 'level'{ digitalWrite(ss, LOW); SPI.transfer(pot); SPI.transfer(level); digitalWrite(ss, HIGH);}void blinkAll(int count){ for (int z=0; zvoid indFade(){ for (int a=0; a<4; a++) { for (int l=0; l<255; l++) { setPot(a,l); delay(del); } for (int l=255; l>=0; --l) { setPot(a,l); delay(del); } }}void allFade(int count){ for (int a=0; a<count; a++)="" {="" for="" (int="" l="0;" l<255;="" l++)="" setpot(0,l);="" setpot(1,l);="" setpot(2,l);="" setpot(3,l);="" delay(del);="" }="">=0; --l) { setPot(0,l); setPot(1,l); setPot(2,l); setPot(3,l); delay(del); } }}void loop(){ blinkAll(3); delay(1000); indFade(); allFade(3);}

La función allOff() y allOn() se utiliza para ajustar los potenciómetros para mínimo y máximo respectivamente. Usamos AllOff () al inicio del boceto para apagar los led. Esto es necesario, ya que en el encendido, los limpiaparabrisas generalmente se configuran a mitad de camino.

Además los usamos en la función blinkAll () para bl parpadear los led. La función setPot() acepta un número de limpiaparabrisas (0~3) y un valor para configurar ese limpiaparabrisas (0~255). Finalmente, la función indFade () hace un buen trabajo al apagar y encender cada LED en orden, causando un efecto muy similar a la modulación de ancho de pulso.

Finalmente, aquí está en acción:

Así que ahí lo tienes, con suerte una introducción fácil de entender al mundo del bus SPI y cómo controlar los dispositivos dentro. Como siempre, ahora depende de ti y de tu imaginación encontrar algo que controlar o hacer otras travesuras. En el próximo artículo de SPI veremos la lectura y escritura de datos a través del bus SPI.

Este post es presentado por pmdway.com-todo para fabricantes y entusiastas de la electrónica, con entrega gratuita en todo el mundo.

Para mantenerse al día con los nuevos puestos en tronixstuff.com, suscríbase a la lista de correo en el cuadro de la derecha, o síganos en twitter @tronixstuff.

por Favor, comparta con los demás:

Imprimir

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *