Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Proyecto de estación meteorológica inalámbrica Arduino

En este tutorial aprenderemos a hacer una Estación Meteorológica Inalámbrica basada en Arduino. Puede ver el siguiente video o leer el tutorial escrito a continuación.

Resumen

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. En la unidad interior, también hay otro sensor DHT22 para medir la temperatura y la humedad interior, así como un módulo de reloj en tiempo real DS3231 que puede realizar un seguimiento del tiempo incluso si el Arduino pierde energía. Todos estos datos están impresos en una pantalla OLED de 0,96”.

Diagrama del circuito de la estación meteorológica inalámbrica Arduino

Echemos un vistazo al diagrama del circuito y cómo funciona este proyecto. Tenga en cuenta que ya tengo tutoriales detallados sobre cómo funciona cada uno de estos módulos, así que para obtener más detalles, puede consultarlos:Tutorial NRF24L01, Tutorial DHT22, Tutorial DS3231 .

Puede obtener los componentes necesarios para este proyecto en los siguientes enlaces:

  • Módulo transceptor NRF24L01……….
  • Sensor DHT22……………….……………………
  • DS3231 Reloj en tiempo real………………….. Amazon / Banggood/AliExpress
  • Arduino Nano ………………………….…….. 

Tanto el módulo de reloj en tiempo real como la pantalla OLED utilizan el protocolo I2C para la comunicación con Arduino, por lo que están conectados a los pines I2C o los pines analógicos número 4 y 5 en la placa Arduino Nano. Justo al lado del módulo transceptor NRF24L01 hay un condensador para mantener la fuente de alimentación más estable. También hay una resistencia pull-up conectada al pin de datos DHT22 para que el sensor funcione correctamente.

En cuanto a la fuente de alimentación, usé un adaptador de corriente de 12 V CC para la unidad interior y, por otro lado, para alimentar la unidad exterior usé dos baterías de iones de litio que producían alrededor de 7,5 V. Con esta configuración, la unidad exterior podría funcionar durante unos 10 días antes de que se descarguen las baterías, porque transmitimos datos periódicamente y, mientras tanto, ponemos el Arduino en modo de suspensión, donde el consumo de energía es de solo unos 7 mA.

PCB de diseño personalizado

Para mantener los componentes electrónicos organizados, de acuerdo con el diagrama del circuito, diseñé una PCB personalizada utilizando el software gratuito de diseño de circuitos en línea EasyEDA. Podemos notar que el mismo PCB se puede usar tanto para la unidad interior como para la exterior, solo la placa Arduino debe programarse de manera diferente.

Una vez que terminemos el diseño aquí, simplemente podemos exportar el archivo Gerber que se usa para fabricar la PCB. Puede consultar los archivos de proyecto EasyEDA de la estación meteorológica inalámbrica Arduino aquí.

Entonces podemos pedir nuestro PCB de JLCPCB, que en realidad es el patrocinador de este video.

Aquí podemos simplemente arrastrar y soltar el archivo Gerber y, una vez cargado, podemos revisar nuestra PCB en el visor de Gerber. Si todo está bien, podemos continuar, seleccionar las propiedades que queremos para nuestra PCB y luego podemos pedir nuestra PCB a un precio razonable. Tenga en cuenta que si es su primer pedido de JLCPCB, puede obtener hasta 10 PCB por solo $2.

Sin embargo, después de varios días han llegado los PCB. La calidad de los PCB es excelente y todo es exactamente igual que en el diseño.

Comencé a ensamblar los componentes electrónicos de este proyecto soldando los cabezales de los pines en la PCB. De esta manera podemos conectar y desconectar fácilmente los componentes cuando sea necesario.

Luego también inserté y soldé el capacitor y la resistencia pull-up. Una vez realizado este paso, ahora podemos simplemente conectar los componentes a los cabezales de pines de la PCB.

A continuación, continué con la elaboración de los casos para el proyecto. Para ello utilicé tablero MDF de 8 mm y con una sierra circular corté todas las piezas a medida.

Para tener mediciones precisas de temperatura y humedad, los lados de las cajas deben permitir que entre aire en la caja. Entonces, usando un taladro y una escofina, hice varias ranuras en los paneles laterales de las unidades interior y exterior.

También hice una ranura para la pantalla OLED en el panel frontal y corté una pequeña pieza de aluminio a medida que luego colocaré en el panel frontal como decoración.

Para montar las cajas utilicé cola para madera y unas abrazaderas, además de unos tornillos.

Pinté las cajas usando una pintura en aerosol. Usé pintura blanca para la unidad exterior y negra para la unidad interior. Después de que la pintura se secara, simplemente inserté los PCB en las cajas.

En la parte posterior de la unidad interior, inserté un conector de alimentación y un interruptor de alimentación, y en la unidad exterior usé un cable de puente simple como interruptor de alimentación.

Y eso es todo, nuestra estación meteorológica inalámbrica Arduino ya está funcionando, pero lo que queda en este video es ver cómo funciona el programa.

Código de estación meteorológica inalámbrica Arduino

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(t) + String(h);
  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: La unidad exterior es el transmisor de la comunicación inalámbrica, por lo que aquí primero debemos incluir la biblioteca RF24, la biblioteca DHT, así como la biblioteca LowPower que se utiliza para poner el Arduino en modo de suspensión.

Después de definir sus instancias, los pines a los que se conectan 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 de bucle, primero leemos los datos del sensor DHT22 o esa es la temperatura y la humedad. Inicialmente, estos valores son enteros y están separados, así que los convierto en una sola variable de cadena, los coloco en la matriz de caracteres y, usando la función radio.write(), envío estos datos a la unidad interior. Usando el bucle for, enviamos los datos 3 veces para asegurarnos de que el receptor obtendrá 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 período de 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(t) + char(176) + "C";
  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 el receptor, necesitamos incluir dos bibliotecas más, una para el módulo de reloj en tiempo real DS3231 y otra para la pantalla OLED, la biblioteca U8G2. De la misma manera que anteriormente, necesitamos definir las instancias, los pines y algunas variables necesarias para el programa a continuación. También aquí necesitamos definir los íconos de temperatura y humedad como mapas de bits.

Mapa de bits del icono 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 GIMP, un editor de imágenes de código abierto, a través del cual podemos dibujar cualquier cosa y luego exportarlo como mapa de bits (.xbm).

Luego, podemos abrir este archivo usando un bloc de notas y desde allí podemos copiar el mapa de bits en el código de Arduino.

Tenga en cuenta que aquí podemos definir el mapa de bits como constante usando el modificador de variable PROGMEM, y de esa manera el mapa de bits se almacenará en la memoria flash en lugar de 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, debemos inicializar la comunicación inalámbrica, así como inicializar la pantalla OLED y el módulo de reloj en tiempo real.

Luego, en la sección de bucle, comprobamos constantemente si hay datos entrantes disponibles para leer a través de los módulos NRF24L01. Si es cierto, usando la función radio.read() lo leemos y almacenamos los dos primeros caracteres en la variable de cadena de temperatura y los dos caracteres siguientes en la variable de cadena de humedad.

Luego usamos la función millis() para mostrar los diversos datos en la pantalla a intervalos definidos con la variable de intervalo que configuré en 3 segundos. Estamos usando la función millis() porque de esta manera el resto del código se puede ejecutar repetidamente, mientras que en caso de que usemos la función delay(), el programa espera ese período, por lo que 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 que se definen con las funciones personalizadas.

La función personalizada drawDate() obtiene la información de fecha y hora del módulo de reloj en tiempo real y la imprime en la pantalla de manera adecuada. La función drawInTemperature() lee la temperatura interior y la imprime apropiadamente en la pantalla. De hecho, se utiliza el mismo método para imprimir todas las pantallas en la pantalla.

Eso sería todo, espero que hayas disfrutado este proyecto Arduino y hayas aprendido algo nuevo. No dude en hacer cualquier pregunta en la sección de comentarios a continuación.


Proceso de manufactura

  1. Estación meteorológica basada en Raspberry Pi
  2. Estación meteorológica Raspberry Pi 2
  3. Estación meteorológica Raspberry Pi
  4. Weather Station V 2.0
  5. Detector de frecuencia de audio
  6. Manipulador de interruptor de luz inalámbrico
  7. Tech-TicTacToe
  8. Temporizador de cuenta atrás de Arduino
  9. $ 10 Estación meteorológica portátil Arduino (AWS)
  10. eDOT - Reloj de precisión y estación meteorológica basados ​​en Arduino
  11. Estación meteorológica ThingSpeak Arduino