¿Te gustaría tener tu propia estación meteorológica en casa y además que sea inalámbrica? En este artículo te enseñaremos cómo llevar a cabo un proyecto de estación meteorológica utilizando la tecnología de Arduino. ¡Sigue leyendo para descubrir cómo hacerlo!
En este tutorial aprenderemos cómo construir una estación meteorológica inalámbrica basada en Arduino. Puede ver el vídeo a continuación o leer el tutorial escrito a continuación.
descripción general
La temperatura y la humedad exteriores se miden mediante el sensor DHT22 y estos datos se envían de forma inalámbrica a la unidad interior mediante los módulos transceptores NRF24L01. También hay otro sensor DHT22 en la unidad interior para medir la temperatura y la humedad interior, así como un módulo de reloj en tiempo real DS3231 que puede realizar un seguimiento de la hora incluso si el Arduino se queda sin energía. Todos estos datos están impresos en una pantalla OLED de 0,96 pulgadas.
Diagrama del circuito de la estación meteorológica inalámbrica Arduino
Echemos un vistazo al esquema y cómo funciona este proyecto. Tenga en cuenta que ya tengo tutoriales detallados sobre cómo funciona cada uno de estos módulos. Para obtener más información, consulte los siguientes tutoriales: tutorial NRF24L01, tutorial DHT22, tutorial DS3231.
Puede>
- Módulo transceptor NRF24L01………. Amazon / Banggood / AliExpress
- Sensor DHT22………….…………………… Amazon / Banggood / AliExpress
- Reloj en tiempo real DS3231…………………….. Amazon / Banggood / AliExpress
- Arduino Nano………………………….…….. Amazon / Banggood / AliExpress
Divulgación: estos son enlaces de afiliados. Como asociado de Amazon, gano con compras que califican.
Tanto el módulo de reloj en tiempo real como la pantalla OLED utilizan el protocolo I2C para comunicarse con el Arduino, por lo que se conectan a los pines I2C o pines analógicos número 4 y 5 de la placa Arduino Nano. Hay un condensador justo al lado del módulo transceptor NRF24L01 para mantener la fuente de alimentación más estable. Para que el sensor funcione correctamente, también se conecta una resistencia pull-up al pin de datos DHT22.
Para la alimentación, utilicé un adaptador de CC de 12 V para la unidad interior y para alimentar la unidad exterior, utilicé dos baterías de iones de litio con un voltaje de aproximadamente 7,5 V. Con esta configuración, la unidad exterior podría funcionar durante unos 10 días antes de que se agoten las baterías, ya que transferimos datos regularmente y mientras tanto ponemos el Arduino en modo de suspensión, donde el consumo actual es de sólo 7 mA.
PCB personalizado
Para mantener los componentes electrónicos organizados, diseñé una PCB personalizada según el esquema. FácilEDA Software gratuito de diseño de circuitos en línea. Podemos encontrar que se puede utilizar la misma placa tanto para la unidad interior como para la exterior, sólo que la placa Arduino debe programarse de forma diferente.
Una>Aquí.
Entonces podemos Solicite nuestra PCB de JLCPCBquien es en realidad el patrocinador de este video.
Aquí>
Sin embargo, las tablas llegaron al cabo de unos días. La calidad de las tablas es excelente y todo coincide exactamente con el diseño.
Comencé>
Luego>
A>
Para>
También hice una ranura para la pantalla OLED en el panel frontal y corté un pequeño trozo de aluminio que luego colocaré en el panel frontal como decoración.
Para>
Pinté las cajas con pintura en aerosol. Utilicé pintura blanca para la unidad exterior y negra para la unidad interior. Una vez seca la pintura, simplemente inserté las placas de circuito en las carcasas.
En la parte posterior de la unidad interior agregué un conector de alimentación y un interruptor de alimentación, y en la unidad exterior utilicé un cable de puente simple como interruptor de alimentación.
Y listo, nuestra estación meteorológica inalámbrica Arduino ya está funcionando, pero en este vídeo solo tenemos que ver cómo funciona el programa.
Código Arduino para estaciones meteorológicas inalámbricas
Código de la unidad exterior de la estación meteorológica Arduino:
/*
Arduino Wireless Communication Tutorial
Outdoor unit - Transmitter
by Dejan Nedelkovski, www.HowToMechatronics.com
Libraries:
NRF24L01 - TMRh20/RF24, https://github.com/tmrh20/RF24/
DHT22 - DHTlib, https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib
LowPower - https://github.com/rocketscream/Low-Power
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>
#include <LowPower.h>
#define dataPin 8 // DHT22 data pin
dht DHT; // Creates a DHT object
RF24 radio(10, 9); // CE, CSN
const byte address[6] = "00001";
char thChar[32] = "";
String thString = "";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
int readData = DHT.read22(dataPin); // Reads the data from the sensor
int t = DHT.temperature; // Gets the values of the temperature
int h = DHT.humidity; // Gets the values of the humidity
thString = String
thString.toCharArray(thChar, 12);
// Sent the data wirelessly to the indoor unit
for (int i = 0; i <= 3; i++) { // Send the data 3 times
radio.write(&thChar, sizeof(thChar));
delay(50);
}
// Sleep for 2 minutes, 15*8 = 120s
for (int sleepCounter = 15; sleepCounter > 0; sleepCounter--)
{
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
Code language: Arduino (arduino)
Descripción: El dispositivo exterior es el transmisor de comunicación inalámbrica, por lo que primero debemos incluir lo siguiente aquí biblioteca RF24El biblioteca DHTasí como Biblioteca de bajo consumo Esto se utiliza para poner el Arduino en modo de suspensión.
Luego de definir sus instancias, los pines a los que están conectados los módulos y algunas variables, en la sección de configuración necesitamos inicializar la dirección de comunicación inalámbrica. Luego, en la sección del bucle, primero leemos los datos del sensor DHT22, es decir, la temperatura y la humedad. Inicialmente estos valores son enteros y están separados, así que los convierto en una variable de cadena única, la inserto en la matriz de caracteres y envío estos datos a la unidad interior usando la función radio.write(). Usando el bucle for, enviamos los datos tres veces para asegurarnos de que el receptor reciba datos en caso de que el controlador esté ocupado en el momento del envío.
Al final, ponemos el Arduino en modo de suspensión durante un tiempo determinado para minimizar el consumo de energía.
Código de la unidad interior de la estación meteorológica Arduino:
/*
Arduino Wireless Communication Tutorial
Indoor unit - Receiver
by Dejan Nedelkovski, www.HowToMechatronics.com
Libraries:
DS3231 - http://www.rinkydinkelectronics.com/library.php?id=73
U8G2 - https://github.com/olikraus/u8g2
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>
#include <DS3231.h>
#include <U8g2lib.h>
#include <Wire.h>
#define dataPin 8 // DHT22 sensor
dht DHT; // Creats a DHT object
DS3231 rtc(SDA, SCL);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
RF24 radio(10, 9); // CE, CSN
const byte address[6] = "00001";
char text[6] = "";
int readDHT22, t, h;
String inTemp, inHum, outTemp, outHum;
String rtcTime, rtcDate;
int draw_state = 0;
unsigned long previousMillis = 0;
long interval = 3000;
#define Temperature_20Icon_width 27
#define Temperature_20Icon_height 47
static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00,
0xc0, 0xe1, 0x00, 0x00, 0xe0, 0xc0, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x79, 0x00,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x8c, 0x79, 0x00,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x79, 0x00,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00,
0x70, 0x9e, 0x03, 0x00, 0x38, 0x1e, 0x07, 0x00, 0x18, 0x3e, 0x0e, 0x00,
0x1c, 0x3f, 0x0c, 0x00, 0x0c, 0x7f, 0x18, 0x00, 0x8c, 0xff, 0x18, 0x00,
0x8e, 0xff, 0x38, 0x00, 0xc6, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x31, 0x00,
0xc6, 0xff, 0x31, 0x00, 0x8e, 0xff, 0x38, 0x00, 0x8c, 0xff, 0x18, 0x00,
0x0c, 0x7f, 0x1c, 0x00, 0x3c, 0x1c, 0x0e, 0x00, 0x78, 0x00, 0x06, 0x00,
0xe0, 0x80, 0x07, 0x00, 0xe0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#define Humidity_20Icon_width 27
#define Humidity_20Icon_height 47
static const unsigned char Humidity_20Icon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00,
0x00, 0xdc, 0x01, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x86, 0x03, 0x00,
0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x07, 0x00, 0x80, 0x03, 0x06, 0x00,
0x80, 0x01, 0x0c, 0x00, 0xc0, 0x01, 0x1c, 0x00, 0xc0, 0x00, 0x18, 0x00,
0xe0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x70, 0x00, 0x70, 0x00,
0x30, 0x00, 0xe0, 0x00, 0x38, 0x00, 0xc0, 0x00, 0x18, 0x00, 0xc0, 0x01,
0x1c, 0x00, 0x80, 0x01, 0x0c, 0x00, 0x80, 0x03, 0x0e, 0x00, 0x80, 0x03,
0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x07,
0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06,
0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06,
0xe3, 0x00, 0x00, 0x06, 0xc7, 0x00, 0x00, 0x06, 0xc6, 0x01, 0x00, 0x07,
0x86, 0x03, 0x00, 0x03, 0x0e, 0x1f, 0x00, 0x03, 0x0e, 0x1e, 0x80, 0x01,
0x1c, 0x00, 0xc0, 0x01, 0x38, 0x00, 0xe0, 0x00, 0x78, 0x00, 0x70, 0x00,
0xf0, 0x00, 0x38, 0x00, 0xe0, 0x07, 0x1f, 0x00, 0x80, 0xff, 0x0f, 0x00,
0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() {
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
u8g2.begin();
rtc.begin();
}
void loop() {
if (radio.available()) {
radio.read(&text, sizeof(text)); // Read incoming data
outTemp = String(text[0]) + String(text[1]) + char(176) + "C"; // Outdoor Temperature
outHum = String(text[2]) + String(text[3]) + "%"; // Outdoor Humidity
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
u8g2.firstPage();
do {
switch (draw_state ) {
case 0: drawDate(); break;
case 1: drawInTemperature(); break;
case 2: drawInHumidity(); break;
case 3: drawOutTemperature(); break;
case 4: drawOutHumidity(); break;
}
} while ( u8g2.nextPage() );
draw_state++;
if (draw_state > 4) {
draw_state = 0;
}
}
}
void drawDate() {
String dowa = rtc.getDOWStr();
dowa.remove(3);
rtcDate = dowa + " " + rtc.getDateStr();
u8g2.setFont(u8g2_font_timB14_tr);
u8g2.setCursor(0, 15);
rtcTime = rtc.getTimeStr(); // DS3231 RTC time
rtcTime.remove(5);
u8g2.print(rtcDate);
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(8, 58);
u8g2.print(rtcTime);
}
void drawInTemperature() {
readDHT22 = DHT.read22(dataPin); // Reads the data from the sensor
t = DHT.temperature; // Gets the values of the temperature
inTemp = String
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("INDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(inTemp);
u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
}
void drawInHumidity() {
h = DHT.humidity; // Gets the values of the humidity
inHum = String(h) + "%";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("INDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(inHum);
u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
}
void drawOutTemperature() {
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("OUTDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(outTemp);
u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
}
void drawOutHumidity() {
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("OUTDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(outHum);
u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
}
Code language: Arduino (arduino)
Descripción: Por otro lado, en la unidad interior o en el receptor, necesitamos integrar dos bibliotecas más, una para Módulo de reloj en tiempo real DS3231 y uno para la pantalla OLED, que biblioteca U8G2. De la misma forma que antes, necesitamos definir las instancias, los pines y algunas variables necesarias para el siguiente programa. Nuevamente, necesitamos definir los símbolos de temperatura y humedad como mapas de bits.
Mapa de bits del símbolo de temperatura:
#define Temperature_20Icon_width 27
#define Temperature_20Icon_height 47
static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00,
0xc0, 0xe1, 0x00, 0x00, 0xe0, 0xc0, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x79, 0x00,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x8c, 0x79, 0x00,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x79, 0x00,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00,
0x70, 0x9e, 0x03, 0x00, 0x38, 0x1e, 0x07, 0x00, 0x18, 0x3e, 0x0e, 0x00,
0x1c, 0x3f, 0x0c, 0x00, 0x0c, 0x7f, 0x18, 0x00, 0x8c, 0xff, 0x18, 0x00,
0x8e, 0xff, 0x38, 0x00, 0xc6, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x31, 0x00,
0xc6, 0xff, 0x31, 0x00, 0x8e, 0xff, 0x38, 0x00, 0x8c, 0xff, 0x18, 0x00,
0x0c, 0x7f, 0x1c, 0x00, 0x3c, 0x1c, 0x0e, 0x00, 0x78, 0x00, 0x06, 0x00,
0xe0, 0x80, 0x07, 0x00, 0xe0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
Code language: Arduino (arduino)
Para ello podemos utilizar CAÑUTILLOun editor de imágenes de código abierto que nos permite dibujar cualquier cosa y luego exportarlo como mapa de bits (.xbm).
Luego>
Tenga en cuenta que aquí podemos definir el mapa de bits como una constante usando el modificador de variable PROGMEM. De esta forma el mapa de bits se almacena en la memoria flash y no en la SRAM de la placa Arduino.
static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM // Save in the Flash memory static unsigned char Temperature_20Icon_bits[] // Save in the SRAM
En la sección de configuración, necesitamos inicializar la comunicación inalámbrica, así como la pantalla OLED y el módulo de reloj en tiempo real.
Luego, en la sección de bucle, verificamos constantemente si los datos entrantes a través de los módulos NRF24L01 están disponibles para lectura. Si esto es cierto, lo leemos usando la función radio.read() y almacenamos los dos primeros caracteres en la variable de cadena «temperatura» y los dos siguientes caracteres en la variable de cadena «humedad».
Luego usamos la función millis() para mostrar los diversos datos en la pantalla en intervalos definidos con la variable de intervalo que configuré en 3 segundos. Usamos la función millis() porque permite que el resto del código se ejecute repetidamente. Por otro lado, si utilizamos la función “delay()”, el programa esperará este periodo de tiempo, por lo que de esta forma probablemente perderíamos los datos entrantes de la unidad exterior.
A continuación, utilizando las funciones firstPage() y nextPage() de la biblioteca U8G2, imprimimos las cinco pantallas diferentes definidas con las funciones personalizadas.
La función personalizada drawDate() recupera la información de fecha y hora del módulo de reloj en tiempo real y la imprime en la pantalla en consecuencia. La función drawInTemperature() lee la temperatura interna y la muestra en consecuencia en la pantalla. De hecho, se utiliza el mismo método para imprimir todas las pantallas en la pantalla.
Eso es todo. Espero que hayas disfrutado este proyecto Arduino y hayas aprendido algo nuevo. No dude en hacer sus preguntas en la sección de comentarios a continuación.
Proyecto de estación meteorológica inalámbrica Arduino
En este tutorial vamos a aprender cómo hacer una estación meteorológica inalámbrica basada en Arduino. La temperatura y humedad exterior se miden utilizando el sensor DHT22 y estos datos se envían de forma inalámbrica a la unidad interior mediante módulos transceptores NRF24L01. En la unidad interior, también hay otro sensor DHT22 para medir la temperatura y humedad interior, así como un módulo DS3231 Real Time Clock que puede mantener el registro del tiempo incluso si Arduino pierde energía. Todos estos datos se imprimen en una pantalla OLED de 0.96”.
Diagrama de circuito de la estación meteorológica inalámbrica Arduino
Para mantener organizados los componentes electrónicos según el diagrama de circuito, diseñé una PCB personalizada utilizando el software de diseño de circuitos en línea EasyEDA. Luego pedí la PCB a JLCPCB, que es el patrocinador de este proyecto. Después de recibir las PCBs, comencé a ensamblar los componentes electrónicos del proyecto.
Código de la estación meteorológica inalámbrica Arduino
El código para la unidad exterior transmisora y la unidad interior receptora se presenta aquí. El código para la unidad exterior se encarga de leer los datos del sensor DHT22 y enviarlos de forma inalámbrica a la unidad interior. Por otro lado, el código para la unidad interior lee los datos recibidos y los muestra en la pantalla OLED junto con la hora del módulo DS3231.
Este proyecto Arduino es una excelente manera de aprender sobre comunicaciones inalámbricas y sensores de temperatura y humedad. Si estás interesado en replicar este proyecto, asegúrate de revisar el tutorial detallado en el artículo original y seguir los enlaces de los componentes necesarios.
Espero que hayas disfrutado de este proyecto y hayas aprendido algo nuevo. Si tienes alguna pregunta, no dudes en dejar un comentario.
Categorías: Tutoriales Arduino. Complementar este artículo con toda la información que te haya inspirado, sobre el contenido.
¡Qué genial este proyecto! Nunca pensé que con Arduino se podría hacer algo así. Definitivamente quiero intentarlo y probarlo. ¡Gracias por la inspiración!
¡Qué interesante! Me encantaría aprender a hacer mi propia estación meteorológica con Arduino. ¡Gracias por compartir!
¡Increíble lo que se puede lograr con Arduino! Definitivamente me inspiraste a intentar hacer mi propia estación meteorológica inalámbrica. ¡Gracias por compartir esta idea tan interesante!
¡Wow! No sabía que se podía hacer una estación meteorológica con Arduino. ¡Me has abierto un mundo de posibilidades! ¡Gracias por la idea!