Icono del sitio Home Assistant Fácil

SPI con Arduino y sensor BMP280

Sensor de temperatura y presión  BMP280 con Arduino

Anteriormente ya se ha hablado de varios protocolos de comunicación como I2C, RS-485 y Serial. Hoy es el turno de hablar de SPI con Arduino, uno de los protocolos de comunicación más difundidos y utilizados en el mundo de los microcontroladores.

De hecho, es tan común y popular, que es posible que ya lo hayas empleado sin siquiera saberlo, ya que es utilizado por muchos sensores y Shields Arduino. Quizás los más conocidos sean el Ethernet Shield y el sensor BME280, muy comunes ambos en proyectos relacionados con el IoT.

Para comprender a fondo cómo utilizar SPI con Arduino vamos a ver:

Todo esto lo vas a poder ver a continuación en el artículo donde hablaré de SPI con Arduino a fondo. Ponte cómodo que empezamos.

¿Qué es y cómo funciona SPI?

SPI son las siglas por las que se conoce el Serial Peripheral Interface (en español, Interfaz de Comunicación Serie). Este protocolo de comunicación es utilizado para comunicar varios circuitos integrados entre sí. Eso sí, permite distancias cortas y altas velocidades. El protocolo surgió en la década de 1970, desarrollado por Motorola, en busca de reducir el número de pines que se necesitaba para conectar dos o más circuitos integrados.

Antes de SPI la mayoría de los circuitos utilizaban una interfaz paralela para comunicarse. Este tipo de interfaces necesitan cerca de diez pines (algunas incluso más). Imagina el sufrimiento del que tenía que diseñar el PCB para conectar tantos pines.

SPI es un protocolo síncrono que funciona como una arquitectura maestro-esclavo.

En esta arquitectura existen dos tipos de dispositivos:

El siguiente ejemplo te ayudará a comprender mejor el funcionamiento de SPI con Arduino. 

Analogía funcionamiento SPI con Arduino

Piensa en una clase, donde hay un profesor y varios estudiantes. Como es lógico, el profesor es el que coordina la clase lo que significa que los estudiantes tienen que estar atentos a él. 

Cuando el profesor va a hacer una pregunta se dirige a un estudiante (ya sea por su nombre o señalándole con el dedo), luego realiza la pregunta y espera por la respuesta del alumno.

Una vez el alumno ha respondido, el profesor da por terminada la conversación y puede interactuar con otro estudiante. 

En este caso, el profesor es el dispositivo maestro o controlador (cuidado no es un juego de palabras) y los estudiantes juegan el papel de periféricos o esclavos. La diferencia entre la comunicación del profesor y sus alumnos y entre el esclavo y el maestro es que no utilizan el mismo lenguaje. Luego veremos cuál es el que utilizan los microcontroladores.

En la siguiente figura puedes apreciar la arquitectura necesaria para conectar varios dispositivos utilizando SPI.

Como puedes ver son necesarios tres pines comunes para todos los dispositivos, estos son:

Teniendo en cuenta que todos los pines anteriores son comunes a todos los dispositivos, es necesario que exista un mecanismo mediante el cual el maestro indique con qué esclavo o periférico se desea comunicar. Para esto es necesario utilizar un pin específico para cada esclavo:

A diferencia de I2C, en SPI solo puede existir un dispositivo maestro y no existe límite para el número de esclavos.

Comunicación SPI con Arduino

Más o menos tenemos claro la lógica que utiliza un protocolo maestro-esclavo y de cómo se conectan los componentes a un bus SPI. Ahora vamos a ver cómo funciona en realidad la comunicación. 

Etapas de la comunicación SPI Arduino

En SPI es posible resumir el proceso de comunicación entre el maestro y un esclavo en tres etapas:

En la siguiente imagen se muestra un ejemplo de comunicación SPI donde se han señalado las tres etapas.

Etapa 1: Activación de esclavo

El primer paso para comunicarse con un esclavo es poner el pin SS correspondiente en estado bajo. Una vez realizado esto el esclavo puede leer los datos enviados por el pin MOSI y escribir datos en el pin MISO.

Solo un esclavo puede tener su pin SS en estado bajo al mismo tiempo, de lo contrario es posible que existan errores de comunicación o incluso que alguno de los esclavos resulte dañado. De esta gestión se encarga el maestro.

Etapa 2: Transferencia y/o recepción de información

Esta etapa es donde se intercambia información entre los dispositivos. Las transferencias se realizan mediante los pines MOSI y MISO en unidades de 8 bits, es decir, 1 byte. Ojo, que se pueden transmitir varios bytes, pero siempre en unidades completas. En otras palabras, no se puede enviar 1 byte y medio, por ejemplo.

Si necesitas enviar 1 byte y medio tendrás que hacerlo en 2 bytes.

Cabe destacar que, tal y como se puede ver en la imagen, un estado alto (HIGH) en los pines de datos representan un 1 lógico; mientras un estado bajo (LOW) representa un 0 lógico.

La señal de reloj juega un papel fundamental en esta etapa. En cada pulso de reloj el dispositivo maestro lee el estado del pin MISO; y además, pone la línea MOSI en estado alto (HIGH) o bajo (LOW), en dependencia del bit a transmitir. De igual forma el esclavo obtiene el estado del pin MOSI (lee el bit enviado por el maestro) y modifica el estado del pin MISO (envía información al maestro).

Como puedes ver ambos dispositivos pueden transmitir información al mismo tiempo sin ningún inconveniente. Es por esto que SPI también es una comunicación full-duplex.

Durante toda esta etapa el pin SS debe permanecer en estado bajo (LOW).

Etapa 3: Desactivación de esclavo

Una vez se ha intercambiado toda la información necesaria es preciso indicarle al esclavo que ya no se va a continuar interactuando con él. Para esto es necesario poner el pin SS nuevamente en estado alto (HIGH).

Parámetros de SPI Arduino

Como has podido apreciar la comunicación es muy sencilla, sin tramas complejas ni otros mecanismos. Sin embargo, al ser SPI un estándar libre, cada dispositivo lo implementa de manera un poco diferente. Esto significa que se debe prestar especial atención a la hoja de características técnicas del dispositivo con el que se desea establecer la comunicación.

A la hora de establecer una comunicación utilizando SPI es necesario tener en cuenta tres parámetros:

Frecuencia de reloj

Lo primero que hay que revisar a la hora de utilizar un dispositivo que emplea SPI es su máxima frecuencia de comunicación, es decir, cuál es la máxima frecuencia a la que el maestro puede manejar el pin SCK para enviar o recibir información desde el esclavo. Este parámetro usualmente aparece en las hojas de datos de los componentes o en los manuales de usuario.

En caso de que se emplee una frecuencia de operación mayor a la máxima soportada por el dispositivo no será posible establecer una comunicación con el esclavo.

Orden de transferencia de bits

Otro parámetro a tener en cuenta es el orden en que se deben enviar y/o leer los bits del esclavo

Esto se debe a que algunos dispositivos comienzan transmitiendo los bytes desde el bit más significativo (MSB), mientras que otros lo realizan desde el bit menos significativo (LSB). A continuación, puedes ver un ejemplo de cómo varía la etapa de transferencia.

En la figura se muestra como quedaría la transmisión de un byte con valor 182 utilizando ambos métodos. Es importante destacar que si un dispositivo no recibe los bits en el orden correcto puede interpretar de forma errónea dicha información.

Modos de transmisión

De modo general se definen 4 modos de transmisión, que dependen de la polaridad y la fase utilizada para la señal de reloj.

La polaridad se refiere al estado en que se debe mantener la señal reloj cuando está inactiva, esta puede ser alta o baja. 

La fase, por otra parte, define el momento en que la información es escrita en el pin de salida. Esto puede ser en el flanco de bajada (cuando va de alto a bajo) o en el flanco de subida (cuando va de bajo a alto) de la señal de reloj.

En la siguiente tabla puedes ver un resumen de los cuatro modos.

Modo PolaridadFase
Modo 0Estado bajoFlanco de bajada
Modo 1Estado bajoFlanco de subida
Modo 2Estado altoFlanco de subida
Modo 3Estado altoFlanco de bajada

En la siguiente figura puedes ver las señales de reloj y datos para cada uno de estos modos.

Los flancos en que se actualizan los pines han sido marcados en azul y en rojo se han marcado los flancos en los que el esclavo lee el valor del pin. 

Comparación I2C vs SPI con Arduino

Una de las dudas más comunes a la hora de usar SPI con Arduino es saber si es mejor este protocolo o usar otro como I2C. Esto depende del proyecto en cuestión pero para que te hagas una idea vamos a ver una comparativa.

En la siguiente tabla se muestran, a modo de comparación, las principales propiedades de los protocolos I2C y SPI en las placas Arduino.

CaracterísticasSPII2C
Tipo de comunicaciónSincrona full-duplexSíncrona semi-duplex
Dispositivos maestros soportadosSolo unoIlimitado (teóricamente)
Dispositivos esclavos soportados*Ilimitado (teóricamente)112
Número de cables3 comunes a todos los dispositivos + 1 por cada esclavo2 comunes a todos los dispositivos
Velocidad 20 MHz100 KHz 
DistanciaCortas (típicamente menos de 20 cm)Cortas (típicamente menos de 20 cm)

* La cantidad máxima de esclavos en un bus SPI está determinado por la cantidad de pines disponibles en el microcontrolador para direccionar los esclavos.

Pros y contras de usar SPI con Arduino

Teniendo en cuenta todo lo visto hasta ahora se pueden destacar las siguientes ventajas:

Hasta aquí todo parece bien, sin embargo también hay algunas desventajas que caben destacar:

Y una vez tienes claro utilizar SPI con Arduino lo primero que debes hacer es identificar los pines.

Identificar pines SPI con Arduino

Debido a la gran variedad de placas de Arduino, la posición de los pines del SPI puede variar bastante de un modelo a otro. 

En la siguiente tabla puedes encontrar un resumen donde se muestra los pines digitales correspondientes a los pines SPI en la mayoría de las placas Arduino.

Placa ArduinoMOSIMISOSCKSSNivel de voltaje
Arduino UNO (o compatible)111213105V
Arduino Nano111213105V
Arduino Mega 2560515052535V
Arduino 101111213103.3V
Arduino MKR100081093.3V

Adicionalmente, los pines SPI se encuentran en el cabezal ICSP (presente en la mayoría de las placas Arduino), esto ha permitido el diseño de Shields que utilicen este protocolo y sean compatibles con los distintos modelos de placas Arduino. Uno de los ejemplos más representativos es el Ethernet Shield

En la siguiente imagen, obtenida del esquema eléctrico de la placa Arduino UNO se puede observar la correspondencia entre las señales SPI y los pines de la cabecera ICSP.

La conexión de los pines SPI en el cabezal ICSP es igual para todas las placas Arduino.

En caso de que planees utilizar una placa basada en ESP8266 es necesario ser cuidadosos al determinar los pines SPI, ya que la mayoría de estas no poseen conector ICSP.

En estas placas los pines de SPI tienen la siguiente asignación:

Cabe la posibilidad de utilizar SPI por software utilizando otros pines. Ten en cuenta que al hacerlo así estás perdiendo velocidad en la conexión con el BUS SPI con Arduino.

Librería SPI con Arduino

Para controlar el bus SPI con Arduino existe la librería SPI, que permite enviar y recibir datos utilizando dicho bus. Siempre y cuando Arduino se comporte como maestro. En otras palabras, la librería solo permite programar la placa para que funcione como maestro, y no como esclavo.

Esta librería cuenta con dos clases:

Inicio analizando la clase SPISettings, ya que es la más simple.

Clase SPISettings

Un objeto de esta clase puede ser utilizado para configurar el bus SPI. Esto implica especificar:

La sintaxis para crear un objeto de este tipo es la siguiente:

Donde:

Funciones de la Clase SPI

La clase SPI es estática, lo que quiere decir que no hace falta crear una instancia u objeto de la clase. Es como las librerías Serial o Wire.

Directamente escribes la clase (SPI) y luego llamas a la función correspondiente. Aquí alguna de estas funciones.

SPI.begin()

Esta función inicializa el bus SPI y configura los pines SCK, MOSI y SS como salida.

Su sintaxis sería:

Como puedes ver es muy simple y ni siquiera requiere parámetros.

Después de ejecutar esta función no se deben utilizar las funciones digitalWrite() o analogWrite() en los pines de SPI

SPI.end()

Esta función realiza lo contrario a SPI.begin(), es decir, que des-inicializa el bus SPI. De esta forma es posible utilizar las funciones digitalWrite() o analogWrite() para controlar los pines de SPI nuevamente.

Su sintaxis es la siguiente

Como puedes ver, al igual que SPI.begin(), es muy simple y no requiere parámetros.

SPI.beginTransaction()

Esta función es utilizada para preparar el bus SPI al comienzo de una transferencia y tiene dos propósitos:

  1. Establecer los parámetros necesarios para la transferencia a realizar.
  2. Indicar que el bus SPI está siendo utilizado. De lo contrario otra librería que emplee el bus SPI podría intentar utilizarlo, generando errores en la comunicación.

Su sintaxis es:

Donde:

En dependencia de la naturaleza de los parámetros es posible utilizar esta función de dos formas diferentes.

Cuando los parámetros a utilizar son constantes, es decir que siempre serán los mismos, es posible declarar el objeto SPISettings en la propia llamada a la función. Tal y como se muestra en el siguiente ejemplo.

Esta sintaxis provoca que el código obtenido se ejecute más rápido.

En caso de que los parámetros no sean constantes es necesario declarar el objeto SPISettings y después utilizarlo como parámetro al ejecutar la función. En el siguiente ejemplo lo puedes ver.

Esta función debe ejecutarse antes de poner el pin SS del esclavo a nivel bajo.

SPI.transfer()

Esta función envía y recibe datos con un esclavo previamente seleccionado. Se puede ejecutar de 2 formas diferentes en dependencia de la cantidad de parámetros.

Cuando una función puede ser llamada de diferentes maneras dependiendo del número de parámetros o el tipo de estos, se dice que es una función o un método sobrecargado

La primera sobrecarga de la función admite un parámetro.

Donde:

La segunda sobrecarga de la función admite dos parámetros.

Donde:

SPI.endTransaction()

La función SPI.endTransaction() es la encargada de liberar el bus SPI una vez se han terminado las transferencias a realizar. En otras palabras, permite que otras librerías puedan utilizar nuevamente el bus.

Su sintaxis es:

Esta función debe ser ejecutada antes de establecer el pin SS del esclavo en estado alto.

Ejemplo comunicación SPI con Arduino y AD5206

Ya está bien de tanta teoría, ahora toca la parte práctica. Ahora verás cómo controlar la intensidad de 6 LEDs utilizando un potenciómetro digital mediante el protocolo SPI con Arduino.

Para este proyecto necesitarás:

* Es posible utilizar cualquier otra placa como Arduino Nano o Arduino MEGA 2560.

Potenciómetro digital AD5206

Si llevas un tiempo en esto de la electrónica de seguro que sabes qué es un potenciómetro o resistencia variable y has trabajado con ellos. 

De modo muy simple, se puede decir que un potenciómetro no es más que un resistencia al que le puedes variar su valor. Existen una increíble variedad: rotativos, deslizantes, de tornillo, etcétera…

Si tienes dudas y quieres aprender más, puedes revisar el artículo sobre potenciómetros con Arduino.

El AD5206 es un potenciómetro digital de 6 canales. Esto significa que tiene seis resistencias variables (potenciómetros) incorporadas para ser controladas de forma individual. Hay tres pines en el chip para cada una de las seis resistencias variables internas, y se pueden conectar con ellas de la misma manera que usaría un potenciómetro mecánico.

Esto lo convierte en un componente ideal para reemplazar potenciómetros mecánicos, en la implementación de filtros programables, ajuste de ganancia automática en sistemas analógicos, entre otras cosas.

Inspeccionando la primera página de su hoja de datos puedes comprobar que:

En la siguiente figura, se puede ver la distribución de pines presente en dicho circuito integrado.

Como se puede apreciar, cuenta con 6 potenciómetros digitales, una interfaz SPI y dos pines de alimentación. En la siguiente tabla puedes ver un resumen de los pines y sus funcionalidades.

PinesDescripción
VDDAlimentación positiva 
GNDTierra
CSChip Select (equivalente a SS)
SDISerial Data Input (equivalente a MOSI)
CLKClock (equivalente a SCK)
AxTerminal positivo del potenciómetro (la x indica el número del potenciómetro) 
WxTerminal central del potenciómetro (la x indica el número del potenciómetro)
BxTerminal negativo del potenciómetro (la x indica el número del potenciómetro)

En este caso la interfaz SPI tiene una particularidad, y es que no existe el pin MISO. Eso se debe a que el potenciómetro (que actúa como esclavo) nunca envía información al microcontrolador.

En este ejemplo se usa cada resistencia variable como divisor de voltaje, conectando un pin lateral (pin Ax) a 5 V, el otro pin lateral (pin Bx) a tierra y tomando la salida de voltaje variable del pin central (Wx) . En este caso, el AD5206 proporciona una resistencia máxima de 10k ohmios, entregados en 255 pasos (255 es el máximo, 0 es el mínimo).

En otras palabras, que trabaja similar a la función analogWrite(), pero eso se hace más adelante.

Determinar parámetros para el bus SPI con Arduino

Si sigues indagando en la hoja de datos puedes encontrar las especificaciones necesarias para la comunicación. Observa la forma de onda ofrecida en la página 4.

Ahí se muestran los parámetros tCH y tCL que especifican el tiempo mínimo que la señal de reloj puede estar en estado alto y bajo respectivamente.

En la tabla de características dinámicas se encuentran los valores correspondientes a dichos parámetros. 

Teniendo en cuenta que para enviar un bit es necesario esperar un ciclo de reloj completo (tCH+tCL) se puede determinar que un bit tarda 40 ns en enviarse. Calculando el recíproco obtienes la máxima frecuencia admisible para comunicarse con el AD5206:

Lo siguiente es determinar con cuál modo SPI es compatible el AD5206. Teniendo en cuenta que no se dice explícitamente es necesario prestar atención al siguiente diagrama de tiempo obtenido de la hoja de características.

Como se puede apreciar el pin datos es modificado en los flancos de bajada de la señal de reloj. Además, el estado inactivo de la señal de reloj es en estado bajo. Esto coincide con el modo de operación SPI 0.

Por último, en la sección OPERATION de la hoja de datos se indica que los bits se tienen que enviar comenzando por el más significativo (MSB).

Hasta aquí ya tienes los parámetros necesarios para configurar el bus SPI. Sin embargo, aún no se ha especificado la estructura de la trama a enviar.

Trama de comunicación con AD5206

En la sección OPERATION también se muestra la estructura de la trama que se debe enviar al dispositivo. En la siguiente imagen la puedes observar.

Como puedes ver está compuesta por dos secciones:

Esto significa que para establecer la posición de un potenciómetro es necesario enviar dos bytes. El primero con el número del potenciómetro y el segundo con la posición. Para comprender mejor el significado de esta trama es mejor montar el circuito y verlo en funcionamiento.

Circuito SPI con Arduino y AD5206

En la siguiente imagen puedes ver el esquema del circuito a montar.

Con el fin de lograr variar la intensidad de los LEDs, estos se han conectado a los pines centrales de cada potenciómetro. Los pines de los extremos de los potenciómetros se han conectado a tierra (GND) y 5V. De esta forma cuando el potenciómetro esté en su menor posición (código 0) el LED se encontrará apagado y a medida que se vaya incrementando la posición el LED comenzará a incrementar su intensidad.

En la siguiente imagen puedes ver como debería quedar el circuito una vez montado en la placa de prototipos.

Si el circuito te parece demasiado complejo puedes probar utilizando un solo potenciómetro. En ese caso solo necesitarías un LED y una resistencia.

Código SPI con Arduino

Ya tienes todo el circuito montado. Ahora es momento de darle vida a esos LEDs.

Lo primero es añadir la librería SPI y definir el pin a utilizar para SS, en este caso el 10.

En la función setup() se configura el pin SS como salida digital y se pone en estado alto, de esta forma se garantiza que el esclavo no se active. Luego, se inicializa el bus SPI.

La función loop() contiene un ciclo que itera por cada uno de los potenciómetros. Para cada potenciómetro se incrementa la salida desde su valor mínimo (0) hasta el máximo (255) a intervalos de 10 ms. 

Una vez alcanzado ese nivel se realiza un pequeño retardo de 100 ms para comenzar el proceso inverso, es decir, para decrementar la salida desde su máximo valor hasta el mínimo (0).

Para establecer la posición del potenciómetro, se ejecuta la rutina digitalPotWrite(). Aquí ves la implementación de esta función.

La función recibe dos parámetros:

En su primera línea se ejecuta la función SPI.beginTransaction() con la configuración obtenida de la hoja de datos.

Cabe destacar que en este caso se ha definido una frecuencia máxima de 20 Mhz para dejar un margen con el máximo permitido por el chip.

Una vez establecida la configuración del bus se activa el esclavo poniendo el pin SS en estado bajo (LOW). Se ha adicionado un pequeño retardo para garantizar estabilidad, pero este puede omitirse sin inconvenientes.

Con el esclavo activado es hora de enviarle la trama. Para eso se ejecuta dos veces la función SPI.transfer(). En la primera ejecución se envía la dirección y en la segunda la posición a establecer.

Por último, cuando ambos bytes se han enviado se pone el pin SS nuevamente en estado alto para desactivar al esclavo y se ejecuta la función SPI.endTransaction() para liberar el bus SPI.

Pues sí, así de simple es establecer una comunicación utilizando SPI Arduino. Aquí te dejo todo el código, listo para cargar a tu Arduino

Si cargas el código y todo funciona bien ¡Felicidades!; si no, a continuación, te dejo un listado de los problemas más frecuentes con los que te puedes topar al utilizar SPI Arduino y sus posibles soluciones.

Problemas frecuentes con la comunicación SPI con Arduino

Es probable que cuando estés utilizando el bus SPI con Arduino los componentes no funcionen adecuadamente, es decir, que la comunicación no vaya del todo bien.

Esto puede ser debido a varias causas algunas de ellas las puedes ver a continuación.

Pin SS en placas Arduino basadas en AVR

Todas las placas basadas en microcontroladores AVR (como Arduino UNO, Arduino MEGA 2560 Arduino Nano, etc.) tienen un pin SS que es útil cuando actúan como esclavos controlados por un maestro externo. Teniendo en cuenta que la librería SPI solo admite el modo maestro, este pin debe establecerse siempre como salida; de lo contrario, el hardware podría configurar automáticamente el bus SPI en modo esclavo, haciendo que la librería deje de funcionar.

Una buena práctica para evitar ese inconveniente es utilizar el propio pin SS como selector para uno de los dispositivos esclavos. De esa forma se garantiza que el pin siempre esté configurado como salida.

Cables largos y ruido electromagnético en SPI con Arduino

Si estás utilizando cables relativamente largos (más de 25 cm) para conectar un dispositivo utilizando SPI con Arduino, es posible que existan problemas en la comunicación. Esos problemas se pueden deber a dos factores principalmente: la velocidad de transmisión y el ruido electromagnético.

Si esto te ocurre, lo primero que debes hacer es intentar utilizar cables más cortos. En caso de que no te sea posible debes comprobar que el sistema no esté cerca de ninguna fuente de ruido electromagnético, como pueden ser fuentes de alimentación conmutadas, radios, antenas, o incluso tu ordenador.

Si aún con todas estas medidas el problema persiste debes reducir la velocidad de comunicación. De esta forma el ruido afecta mucho menos a la señal.

Ejemplo comunicación SPI con Arduino y sensor BMP280

En este segundo ejemplo práctico vamos a ver cómo comunicar el sensor de temperatura y presión BMP280 utilizando el bus SPI con Arduino.

Este sensor es bastante común y lo puedes encontrar tanto Amazon como en Aliexpress por un precio muy asequible.

Asegúrate que el sensor BMP280 que compres tenga 6 pines ya que hay sensores con solo 4 pines que solo permiten comunicación por I2C.

Permite medir tanto la temperatura como la presión atmosférica y gracias a la librería de Adafruit, Adafruit_BMP280, vas a poder trabajar con él mediante el protocolo I2C como con el bus SPI.

En este caso voy a utilizar 2 sensores para poder probar el funcionamiento del bus SPI con Arduino.

Si quieres saber más sobre el sensor te recomiendo que eches un vistazo a la hoja de características técnicas del BMP280.

Conexión BMP280 con Arduino utilizando SPI

El siguiente esquema eléctrico te muestra cómo conectar dos sensores BMP280 utilizando el bus SPI con Arduino.

Cada sensor BMP280 tiene 6 pines.

La conexión de los pines es la siguiente

PinSensor 1Sensor 2
VCC3,3V3,3V
GNDGNDGND
SCL (SCK)1313
SDA (MOSI)1111
CSB (SS)910
SDO (MISO)1212
Conexión pines de cada sensor con Arduino

Fíjate que en las conexiones los pines SCK, MOSI y MISO de los dos sensores van a los mismos pines de Arduino, es decir, comparte conexión. Sin embargo, para el pin de SS de selección de esclavo cada sensor se conecta con un pin diferente.

El sensor 1 se conecta al pin 9 y el sensor 2 al pin 10.

Y una vez conectado pasamos a ver el código.

Programación BMP280 SPI con Arduino

Para poder programar este sensor vamos a utilizar la librería de Adafruit Adafruit_BMP280. En el gestor de librerías busca la librería y la instalas.

Cuando la intentas instalar te pregunta si quieres instalar otras librerías que son necesarias para que la librería de Adafruit funcione. Haz clic en Install all.

Ahora ya está todo listo. El código que voy a utilizar es el siguiente.

Lo primero es importar todas las librerías necesarias. Luego crea 5 constantes para almacenar los pines SCD, MISO, MOSI y los dos pines SS de selección de esclavo.

Luego hay que crear dos objetos de la clase Adafruit_BMP280 que se llaman sensor1 y sensor2. Este constructor está sobrecargado y puede admitir 0, 1 o 4 parámetros.

Cuando no admite parámetros estás indicando que vas a trabajar con I2C, cuando indicas un único parámetro le estás diciendo que vas a utilizar el bus SPI con Arduino por hardware. El parámetro indica el pin donde has conectado el SS (selector de esclavo).

Por último, cuando indicas todos los pines del bus SPI con Arduino estás diciendo a la librería que vas a trabajar a través de SPI por software.

En nuestro caso utilizamos la sobrecarga que admite un único parámetro y pasamos el pin SS de cada sensor.

En la función setup() llamamos a la función begin() para iniciar cada sensor. En caso de no poder iniciar el sensor muestra un mensaje por el monitor serie y no continúa.

En la función es donde vamos a consultar la temperatura y la presión atmosférica. He creado una función que se llama mostrarInfoSensor(sensor) que admite un parámetro que es el objeto de la clase Adafruti_BMP280.

Dentro de esta función se consulta la temperatura con la función readTemperature() y la presión con readPressure(). Luego se muestra la información por el monitor serie.

Por último se hace una espera de 5 segundos entre cada medida.

Solo queda una cosa, comprobar que todo funciona correctamente cargando el código a Arduino y abriendo el monitor serie.

Aparecerá algo parecido a la anterior imagen.

Con esto damos por finalizado este tutorial del bus SPI con Arduino y el sensor BMP280.

Conclusiones sobre SPI con Arduino y sensor BMP280

Este tutorial has podido comprobar cómo utilizar el protocolo de comunicaciones SPI con Arduino y has visto un ejemplo de comunicación con el sensor de temperatura y presión BMP280.. Se trata de otra funcionalidad que incluyen los microcontroladores como los que llevan integrados los Arduino.

Esto no quiere decir que siempre tengas que utilizar SPI con Arduino o I2C. Cada proyecto va a requerir utilizar una tecnología y un protocolo concreto.

Lo importante es conocer cada uno de ellos y poder elegir consecuentemente.

Si lo que necesitas es una comunicación bidireccional full-duplex a través de un protocolo flexible y robusto con un consumo de energía bajo y transmisión de datos a gran velocidad, SPI con Arduino puede ser una buena opción.

Cualquier duda o sugerencia en los comentarios de aquí abajo. Gracias :)

Gracias a Shutterstock por la cesión de las imágenes.

Salir de la versión móvil