Termómetro digital con el sensor BME280

Vista previa

Este circuito mide la temperatura ambiente con el módulo BME280. Además de la temperatura, proporciona la presión atmosférica, la altitud y la humedad relativa. Los valores leídos por el sensor son desplegados a través de un display OLED SSD1306 128x32. Ambos módulos son controlados por una placa ESP32 de 30 pines. Los materiales empleados para éste proyecto son:

  1. Módulo BME280

  2. Display OLED azul SSD1306 128x32

  3. ESP32 de 30 pines

  4. Protoboard

CIRCUITO

El display es alimentado por el pin de 5V de la placa ESP32, el módulo BME280, como es de 3.3V, se alimenta con el pin 3.3V de la placa ESP32.

LIBRERÍAS NECESARIAS

Por lo regular, estás librerías se instalan cuando se instala el Arduino IDE, pero en caso de que no estén instaladas, hay que hacerlo de manera manual, de lo contrario, el Arduino IDE marcará error a la hora de compilar el sketch.

1. Adafruit BME280 Library by Adafruit

2. Adafruit Unified Sensor by Adafruit

3. Adafruit SSD1306 by Adafruit

4. Adafruit GFX Library by Adafruit




CÓDIGO

NOTA: Siempre es recomendable cargar el sketch con la placa desmontada del protoboard (es decir, desconectada del resto del circuito) para evitar posibles daños, ya que los GPIOs todavía no se encuentran configurados.

En el Arduino IDE debes seleccionar la placa DOIT ESP32 DEVKIT V1

El código que se usó para este proyecto es es siguiente:

/* 
Termómetro con display OLED

Sketch creado por Kish para
www.troncity.mx
26/02/2025

Este sketch sirve para mostrar en un display OLED SSD1306 los valores sensados
por el módulo BME280 de 3.3V, los cuales son:

  * temperatura
  * presión atmosférica
  * altitud
  * humedad
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SCREEN_WIDTH 128 // Ancho del display, en pixeles
#define SCREEN_HEIGHT 32 // Altura del display, en pixeles

#define OLED_RESET     -1 // Pin de reset (o -1 si comparte pin de reset con Arduino)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Define puertos de conexión para BME280
#define BME_SCL   15
#define BME_SDA   2
#define BME_CSB   4
#define BME_SDO   16



Adafruit_BME280 bme(BME_CSB, BME_SDA, BME_SDO, BME_SCL);

int textSize = 2; //Tamaño de fuente
float presionLocal = 0; //Presión atmosférica local en octopascal
uint16_t posicionX = 0;
uint16_t altoCaracter = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  if (!bme.begin()) {
    Serial.println("No se encontró ningún sensor BME280, revise cableado, dirección, sensor ID!");
    while (1) delay(10);
  } 

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("Asignación de SSD1306 fallida"));
    for(;;); // Don't proceed, loop forever
  }

  display.setTextSize(textSize); // Configura tamaño de fuente
  display.setTextColor(SSD1306_WHITE);
  presionLocal = bme.readPressure() / 100.0F;
}

void loop() {
  Temperatura();
}

void Temperatura(void) {
  float BME280[] = {bme.readTemperature(), bme.readPressure() / 100.0F, bme.readAltitude(presionLocal), bme.readHumidity()};
  const char *parametro[] = {"Temperatur", "Presion", "Altura", "Humedad"};
  char buffer[10]; // Para la función dtostrf
  for(int x = 0; x < 4; x++){
    display.clearDisplay(); //Borra Buffer de display

    // Imprime primera línea de texto
    calculaLongitud(parametro[x]); // Calcula longitud del texto para centrarlo en display
    display.setCursor(posicionX, 0);
    display.print(parametro[x]);

    // Imprime segunda línea de texto
    dtostrf(BME280[x], 0, 2, buffer); //Convierte valor de BME280[x] en texto
    calculaLongitud(buffer); // Calcula longitud del texto para centrarlo en display
    display.setCursor(posicionX, altoCaracter + 1);
    display.print(BME280[x]);

    display.display();
    delay(2000);
  }
}

void calculaLongitud(const char* texto) {
  int16_t x1, y1;
  uint16_t w, h;
  display.getTextBounds(texto, 0, 0, &x1, &y1, &w, &h); // Calcula recuadro delimitador del texto
  posicionX = (SCREEN_WIDTH - w) / 2; // Para saber dónde se empieza a dibujar el texto en el eje X
  altoCaracter = h; // Para saber dónde se empieza a dibujar la segunda línea de texto en el eje Y
}