Semana 3

Esta semana comenzaremos a explorar las posibilidades de conectividad entre el microcontrolador y periféricos externos. Dichos periféricos externos usualmente son sensores, actuadores o dispositivos de comunicación. Estos dispositivos poseen alguna capacidad de cómputo. Comenzaremos estudiando SPI o Serial Peripheral Interface.

Objetivos

  1. Comprender el funcionamiento del bus SPI.
  2. Realizar ejercicios de comunicación entre un microcontrolador y un dispositivo mediante el uso de SPI.
  3. Practicar el uso del bus SPI mediante la comunicación entre un sensor y un microcontrolador.

Material de Referencia

Aquí esta el enlace con el material introductorio.

El framework de arduino soporte el bus SPI.

Ejercicio SPI

Realizaremos un ejercicio práctico para conectar un sensor a un controlador utilizando el puerto SPI. El sensor a utilizar será el BME280 de la empresa Bosh. El BME280 es un sensor ambiental que permite medir humedad relativa, presión y temperatura. Como controlador, vamos a utilizar el ESP32 y el framework de arduino.

Para realizar el ejericicio utilizaremos el siguiente material:

Pinouts

La siguiente figura muestra los pines del sensor a utilizar:

../_images/BME280Pinout.jpeg

Las señales tienen la siguiente función:

  • VCC: alimentación a 3.3V.
  • GND: 0V.
  • SCL: Clock SPI.
  • SDA: MOSI SPI.
  • CSB: CS o SS (Chip Select) SPI.
  • SDO: MISO SPI.

En relación al controlador a utilizar, hay varias opciones:

Aquí se puede ver información de los pines SPI para el ESP32 pico:

  • Clock SPI: pin 18
  • MISO: pin 19
  • MOSI: pin 23
  • CS: pin 5

En este enlace se puede ver otro controlador.

Y en este para otro módulo basado en el ESP32 y el módulo ESP32-WROOM-32D.

Los controladores se puede comprar aquí:

ESP32 pico.

DevKit32.

ESP32-OLED-18650-BAT.

Para conectar el sensor con el controlador se procede así:

ESP32 pico DevKit32 BME280 SPI
3V3 3V3 VCC
GND GND GND
pin 18 SCK/18 SCL CLOCK
pin 23 MOSI/23 SDA MOSI
pin 5 SS/5/LED CSB SS
pin 19 MISO/19 SDO MISO

Software

Para realizar la prueba del sensor es necesario instalar estas dos bibliotecas:

Programa de prueba

Una vez instalada la biblioteca Adafruit BME280. Se debe abrir el ejemplo BME280test.ino. Y realizar las siguiente modificaciones:

Comentar la el archivo de cabeceras Wire.h. Este archivo corresponde al API I2C. Modificar el pinout del SPI:

24
25
26
27
28
 #include <SPI.h>
 #define BME_SCK 18
 #define BME_MISO 19
 #define BME_MOSI 23
 #define BME_CS 5

Comentar la línea que declara el objeto I2C y descomentar la correspondiente a SPI:

33
34
35
 //Adafruit_BME280 bme; // I2C
 Adafruit_BME280 bme(BME_CS); // hardware SPI
 //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

A continuación se observa el código completo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 /***************************************************************************
 This is a library for the BME280 humidity, temperature & pressure sensor

 Designed specifically to work with the Adafruit BME280 Breakout
 ----> http://www.adafruit.com/products/2650

 These sensors use I2C or SPI to communicate, 2 or 4 pins are required
 to interface. The device's I2C address is either 0x76 or 0x77.

 Adafruit invests time and resources providing this open source code,
 please support Adafruit andopen-source hardware by purchasing products
 from Adafruit!

 Written by Limor Fried & Kevin Townsend for Adafruit Industries.
 BSD license, all text above must be included in any redistribution
 ***************************************************************************/

 //#include <Wire.h>

 #include <Adafruit_Sensor.h>
 #include <Adafruit_BME280.h>


 #include <SPI.h>
 #define BME_SCK 18
 #define BME_MISO 19
 #define BME_MOSI 23
 #define BME_CS 5


 #define SEALEVELPRESSURE_HPA (1013.25)

 //Adafruit_BME280 bme; // I2C
 Adafruit_BME280 bme(BME_CS); // hardware SPI
 //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

 unsigned long delayTime;

 void setup() {
 Serial.begin(9600);
 Serial.println(F("BME280 test"));

 bool status;

 // default settings
 // (you can also pass in a Wire library object like &Wire2)
 //status = bme.begin(0x76);ç
 status = bme.begin();
 if (!status) {
     Serial.println("Could not find a valid BME280 sensor, check wiring!");
     while (1);
 }

 Serial.println("-- Default Test --");
 delayTime = 1000;

 Serial.println();
 }


 void loop() {
 printValues();
 delay(delayTime);
 }


 void printValues() {
 Serial.print("Temperature = ");
 Serial.print(bme.readTemperature());
 Serial.println(" *C");

 Serial.print("Pressure = ");

 Serial.print(bme.readPressure() / 100.0F);
 Serial.println(" hPa");

 Serial.print("Approx. Altitude = ");
 Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
 Serial.println(" m");

 Serial.print("Humidity = ");
 Serial.print(bme.readHumidity());
 Serial.println(" %");

 Serial.println();
 }

Al ejecutar el código el resultado será algo similar a esto:

Temperature = 25.44 *C
Pressure = 850.51 hPa
Approx. Altitude = 1452.61 m
Humidity = 51.67 %

Temperature = 25.43 *C
Pressure = 850.43 hPa
Approx. Altitude = 1453.42 m
Humidity = 51.67 %

Temperature = 25.43 *C
Pressure = 850.47 hPa
Approx. Altitude = 1453.03 m
Humidity = 51.67 %

La temperatura se reporta como un número en punto flotante en grados centígrados. La presión se reporta como un número en punto flotante en Pascales. Note que el valor de presión se divide por el literal 100.0F (constante en punto flotante) para convertir a hecto Pascales el resultado. Para el cálculo de la altitud aproximada, es necesario pasar la presión sobre el nivel del mar de la ciudad al día y hora de la prueba en unidades de hecto Pascales. Finalmente se reporta la humdad relativa en punto flotante.

Análisis de la biblioteca SPI y la hoja de datos del sensor

Abra el código fuente de la biblioteca del sensor.

  • Analice el código del constructor de la clase. ¿Qué estrategia utilizan para diferenciar el SPI por hardware al SPI por software?
  • ¿En qué parte del código se inicializa el objeto SPI?
  • Haciendo la lectura del código fuente, ¿Qué bit se envía primero, el de mayor peso o el de menor peso?
  • ¿Cuál modo de SPI utiliza el sensor?
  • ¿Cuál es la velocidad de comunicación?
  • El sensor soporta dos modos SPI. Leyendo la información en la hoja de datos, cómo sería posible configurar el modo?
  • ¿Cuál es el protocolo para escribir información en el sensor?
  • ¿Cuál es el protocolo para leer informacion del sensor?
  • Busque en el código fuente de la biblioteca, ¿Dónde se lee el chip-ID del sensore BME280?
  • Muestre y explique detalladamente los pasos y el código para identificar el chip-ID. No olvide apoyarse de la hoja de datos
  • ¿Qué otros pasos se requieren para inicializar el sensor?