Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Projet de station météo sans fil Arduino

Dans ce tutoriel, nous allons apprendre à créer une station météo sans fil basée sur Arduino. Vous pouvez regarder la vidéo suivante ou lire le didacticiel écrit ci-dessous.

Aperçu

La température et l'humidité extérieures sont mesurées à l'aide du capteur DHT22 et ces données sont envoyées sans fil à l'unité intérieure à l'aide des modules émetteurs-récepteurs NRF24L01. Au niveau de l'unité intérieure, il y a aussi un autre capteur DHT22 pour mesurer la température et l'humidité intérieures, ainsi qu'un module d'horloge en temps réel DS3231 qui peut garder une trace de l'heure même si l'Arduino perd de l'alimentation. Toutes ces données sont imprimées sur un écran OLED de 0,96".

Schéma du circuit de la station météo sans fil Arduino

Jetons un coup d'œil au schéma de circuit et au fonctionnement de ce projet. Notez que j'ai déjà des tutoriels détaillés sur le fonctionnement de chacun de ces modules, donc pour plus de détails vous pouvez les consulter :Tutoriel NRF24L01, Tutoriel DHT22, Tutoriel DS3231.

Vous pouvez obtenir les composants nécessaires à ce projet à partir des liens ci-dessous :

  • Module émetteur-récepteur NRF24L01……….
  • Capteur DHT22…………….……………………………
  • Horloge en temps réel DS3231………………….. Amazon / Banggood / AliExpress
  • Arduino Nano ………………………….…….. 

Le module d'horloge en temps réel et l'écran OLED utilisent le protocole I2C pour communiquer avec l'Arduino afin qu'ils soient connectés aux broches I2C ou aux broches analogiques numéro 4 et 5 sur la carte Arduino Nano. Juste à côté du module émetteur-récepteur NRF24L01, il y a un condensateur pour maintenir l'alimentation plus stable. Il y a aussi une résistance pull-up connectée à la broche de données DHT22 pour que le capteur fonctionne correctement.

En ce qui concerne l'alimentation, j'ai utilisé un adaptateur d'alimentation 12V DC pour l'unité intérieure, et de l'autre côté, pour alimenter l'unité extérieure, j'ai utilisé deux batteries Li-on produisant environ 7,5V. Avec cette configuration, l'unité extérieure pourrait fonctionner pendant environ 10 jours avant que les batteries ne se déchargent, car nous transmettons des données périodiquement et en attendant, nous mettons l'Arduino en mode veille, où la consommation électrique n'est que d'environ 7 mA.

Conception de circuits imprimés personnalisés

Afin de garder les composants électroniques organisés, selon le schéma de circuit, j'ai conçu un circuit imprimé personnalisé à l'aide du logiciel de conception de circuits en ligne gratuit EasyEDA. Nous pouvons noter que le même PCB peut être utilisé à la fois pour l'unité intérieure et l'unité extérieure, seule la carte Arduino doit être programmée différemment.

Une fois que nous avons terminé la conception ici, nous pouvons simplement exporter le fichier Gerber qui est utilisé pour fabriquer le PCB. Vous pouvez consulter les fichiers de projet EasyEDA de la station météo sans fil Arduino ici.

Ensuite, nous pouvons commander notre PCB auprès de JLCPCB, qui est en fait le sponsor de cette vidéo.

Ici, nous pouvons simplement faire glisser et déposer le fichier Gerber et une fois téléchargé, nous pouvons revoir notre PCB dans la visionneuse Gerber. Si tout va bien, nous pouvons continuer, sélectionner les propriétés que nous voulons pour notre PCB, puis nous pouvons commander notre PCB à un prix raisonnable. Notez que s'il s'agit de votre première commande auprès de JLCPCB, vous pouvez obtenir jusqu'à 10 PCB pour seulement 2 $.

Néanmoins, après plusieurs jours, les PCB sont arrivés. La qualité des PCB est excellente et tout est exactement comme dans la conception.

J'ai commencé à assembler les composants électroniques de ce projet en soudant des en-têtes de broches sur le PCB. De cette façon, nous pouvons facilement connecter et déconnecter les composants en cas de besoin.

Ensuite, j'ai également inséré et soudé le condensateur et la résistance de rappel. Une fois cette étape terminée, nous pouvons maintenant simplement attacher les composants sur les en-têtes de broches du PCB.

Ensuite, je suis passé à la fabrication des cas pour le projet. À cette fin, j'ai utilisé un panneau MDF de 8 mm et à l'aide d'une scie circulaire, j'ai coupé tous les morceaux à la bonne taille.

Afin d'avoir des mesures précises de température et d'humidité, les côtés des boîtiers doivent permettre à l'air d'entrer dans le boîtier. Ainsi, à l'aide d'une perceuse et d'une râpe, j'ai fait plusieurs fentes sur les panneaux latéraux des unités intérieure et extérieure.

J'ai également fait une fente pour l'écran OLED sur le panneau avant, ainsi que coupé un petit morceau d'aluminium à la taille que je fixerai plus tard sur le panneau avant comme décoration.

Pour assembler les caisses, j'ai utilisé une colle à bois et des pinces, ainsi que des vis.

J'ai peint les caisses à l'aide d'une bombe de peinture. J'ai utilisé de la peinture blanche pour l'unité extérieure et une noire pour l'unité intérieure. Une fois la peinture sèche, j'ai simplement inséré les PCB dans les boîtiers.

À l'arrière de l'unité intérieure, j'ai inséré une prise d'alimentation et un interrupteur d'alimentation, et à l'unité extérieure, j'ai utilisé un simple fil de raccordement comme interrupteur d'alimentation.

Et voilà, notre station météo sans fil Arduino fonctionne maintenant, mais ce qui reste dans cette vidéo est de jeter un œil au fonctionnement du programme.

Code de la station météo sans fil Arduino

Code de l'unité extérieure de la station météo 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)

Description : L'unité extérieure est l'émetteur de la communication sans fil, nous devons donc d'abord inclure la bibliothèque RF24, la bibliothèque DHT, ainsi que la bibliothèque LowPower qui est utilisée pour mettre l'Arduino en mode veille.

Après avoir défini leurs instances, les broches auxquelles les modules sont connectés et certaines variables, dans la section de configuration, nous devons initialiser l'adresse de communication sans fil. Ensuite, dans la section boucle, nous lisons d'abord les données du capteur DHT22 ou c'est la température et l'humidité. Initialement, ces valeurs sont des nombres entiers et séparés, donc je les convertis en une seule variable String, les mets dans le tableau de caractères, et en utilisant la fonction radio.write(), j'envoie ces données à l'unité intérieure. En utilisant la boucle for, nous envoyons les données 3 fois afin d'être sûr que le récepteur obtiendra les données au cas où le contrôleur serait occupé au moment de l'envoi.

À la fin, nous mettons l'Arduino en mode veille pendant une période donnée afin de minimiser la consommation d'énergie.

Code de l'unité intérieure de la station météo 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)

Description : De l'autre côté, au niveau de l'unité intérieure ou du récepteur, nous devons inclure deux bibliothèques supplémentaires, une pour le module d'horloge en temps réel DS3231 et une pour l'affichage OLED, la bibliothèque U8G2. De la même manière que précédemment, nous devons définir les instances, les broches et certaines variables nécessaires au programme ci-dessous. Ici aussi, nous devons définir les icônes de température et d'humidité sous forme de bitmaps.

Bitmap d'icône de température :

#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)

À cette fin, nous pouvons utiliser GIMP, un éditeur d'images open source, grâce auquel nous pouvons dessiner n'importe quoi, puis l'exporter au format bitmap (.xbm).

Ensuite, nous pouvons ouvrir ce fichier à l'aide d'un bloc-notes et à partir de là, nous pouvons copier le bitmap dans le code Arduino.

Notez qu'ici, nous pouvons définir le bitmap comme constant à l'aide du modificateur de variable PROGMEM, et ainsi le bitmap sera stocké dans la mémoire flash au lieu de la SRAM de la carte 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

Dans la section de configuration, nous devons initialiser la communication sans fil ainsi que l'affichage OLED et le module d'horloge en temps réel.

Ensuite, dans la section de boucle, nous vérifions constamment s'il existe des données entrantes disponibles pour être lues via les modules NRF24L01. Si vrai, en utilisant la fonction radio.read() nous le lisons et stockons les deux premiers caractères dans la variable String de température, et les deux caractères suivants dans la variable String d'humidité.

Ensuite, nous utilisons la fonction millis() afin d'afficher les différentes données sur l'écran à des intervalles définis avec la variable d'intervalle que je fixe à 3 secondes. Nous utilisons la fonction millis() car de cette façon le reste du code peut être exécuté de manière répétée, alors que dans le cas où nous utilisons la fonction delay(), le programme attend cette période donc de cette façon nous manquerions probablement les données entrantes de l'unité extérieure.

Ensuite, en utilisant les fonctions firstPage() et nextPage() de la bibliothèque U8G2, nous imprimons les cinq écrans différents qui sont définis avec les fonctions personnalisées.

La fonction personnalisée drawDate() obtient les informations de date et d'heure du module d'horloge en temps réel et les imprime de manière appropriée sur l'affichage. La fonction drawInTemperature() lit la température intérieure et l'imprime de manière appropriée sur l'écran. En fait, la même méthode est utilisée pour imprimer tous les écrans sur l'affichage.

Donc ce serait tout, j'espère que vous avez apprécié ce projet Arduino et appris quelque chose de nouveau. N'hésitez pas à poser des questions dans la section des commentaires ci-dessous.


Processus de fabrication

  1. Station météo basée sur Raspberry Pi
  2. Station météo Raspberry Pi 2
  3. Station météo Raspberry Pi
  4. Weather Station V 2.0
  5. Détecteur de fréquence audio
  6. Manipulateur d'interrupteur d'éclairage sans fil
  7. Tech-TicTacToe
  8. compte à rebours Arduino
  9. Station météo portable Arduino (AWS) à 10 $