Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Arduino Draadloos Weerstation Project

In deze tutorial leren we hoe je een op Arduino gebaseerd draadloos weerstation kunt maken. Je kunt de volgende video bekijken of de schriftelijke tutorial hieronder lezen.

Overzicht

De buitentemperatuur en -vochtigheid worden gemeten met behulp van de DHT22-sensor en deze gegevens worden draadloos verzonden naar de binnenunit met behulp van de NRF24L01-zendontvangermodules. Bij de binnenunit is er ook nog een DHT22-sensor voor het meten van de binnentemperatuur en vochtigheid, evenals een DS3231 Real Time Clock-module die de tijd kan bijhouden, zelfs als de Arduino stroom verliest. Al deze gegevens worden afgedrukt op een OLED-scherm van 0,96 inch.

Arduino draadloos weerstation schakelschema

Laten we eens kijken naar het schakelschema en hoe dit project werkt. Merk op dat ik al gedetailleerde tutorials heb over hoe elk van deze modules werkt, dus voor meer details kun je ze bekijken:NRF24L01 Tutorial, DHT22 Tutorial, DS3231 Tutorial.

U kunt de benodigde componenten voor dit project vinden via de onderstaande links:

  • NRF24L01 Zendontvangermodule………….
  • DHT22-sensor………….……………………
  • DS3231 Realtime-klok…………………….. Amazon / Banggood / AliExpress
  • Arduino Nano ……………………….…….. 

Zowel de realtimeklokmodule als het OLED-display gebruiken het I2C-protocol voor communicatie met de Arduino, zodat ze zijn verbonden met de I2C-pinnen of de analoge pinnen nummer 4 en 5 op het Arduino Nano-bord. Direct naast de NRF24L01 transceiver module zit een condensator om de voeding stabieler te houden. Er is ook een pull-up-weerstand aangesloten op de DHT22-gegevenspin om de sensor goed te laten werken.

Wat betreft de voeding heb ik een 12V DC-voedingsadapter voor de binnenunit gebruikt, en aan de andere kant, voor de voeding van de buitenunit, gebruikte ik twee Li-on-batterijen die ongeveer 7,5V produceerden. Met deze configuratie zou de buitenunit ongeveer 10 dagen kunnen werken voordat de batterijen leeg zijn, omdat we periodiek gegevens verzenden en in de tussentijd zetten we de Arduino in de slaapstand, waar het stroomverbruik slechts ongeveer 7mA is.

Aangepast ontwerp PCB

Om de elektronische componenten georganiseerd te houden, heb ik volgens het schakelschema een aangepaste PCB ontworpen met behulp van de gratis EasyEDA-software voor online circuitontwerp. We kunnen constateren dat dezelfde print voor zowel de binnen- als de buitenunit kan worden gebruikt, alleen het Arduino-bord moet anders worden geprogrammeerd.

Zodra we het ontwerp hier hebben voltooid, kunnen we eenvoudig het Gerber-bestand exporteren dat wordt gebruikt voor het vervaardigen van de PCB. U kunt de EasyEDA-projectbestanden van het draadloze Arduino-weerstation hier bekijken.

Dan kunnen we onze PCB bestellen bij JLCPCB, die eigenlijk de sponsor is van deze video.

Hier kunnen we eenvoudig het Gerber-bestand slepen en neerzetten en eenmaal geüpload kunnen we onze PCB bekijken in de Gerber-viewer. Als alles in orde is, kunnen we doorgaan, de eigenschappen selecteren die we voor onze PCB willen, en dan kunnen we onze PCB tegen een redelijke prijs bestellen. Houd er rekening mee dat als het uw eerste bestelling bij JLCPCB is, u tot 10 PCB's kunt krijgen voor slechts $ 2.

Toch zijn de PCB's na enkele dagen aangekomen. De kwaliteit van de PCB's is geweldig en alles is precies hetzelfde als in het ontwerp.

Ik begon met het monteren van de elektronische componenten van dit project door pin-headers op de PCB te solderen. Op deze manier kunnen we de componenten gemakkelijk aansluiten en loskoppelen wanneer dat nodig is.

Daarna heb ik ook de condensator en de pull-up-weerstand geplaatst en gesoldeerd. Nu deze stap is voltooid, kunnen we de componenten nu eenvoudig op de pin-headers van de PCB bevestigen.

Vervolgens ging ik verder met het maken van de cases voor het project. Ik heb daarvoor 8 mm tick MDF-plaat gebruikt en met een cirkelzaag heb ik alle stukken op maat gesneden.

Om nauwkeurige temperatuur- en vochtigheidsmetingen te hebben, moeten de zijkanten van de koffers lucht in de koffer laten komen. Dus met een boor en een rasp heb ik verschillende sleuven gemaakt in de zijpanelen van zowel de binnen- als buitenunits.

Ik heb ook een gleuf gemaakt voor het OLED-display op het voorpaneel en een klein stukje aluminium op maat gesneden dat ik later als decoratie op het voorpaneel zal bevestigen.

Voor het monteren van de koffers heb ik houtlijm en enkele klemmen gebruikt, evenals enkele schroeven.

Ik schilderde de gevallen met behulp van een spuitbus. Ik gebruikte witte verf voor de buitenunit en zwarte voor de binnenunit. Nadat de verf was opgedroogd, heb ik de PCB's gewoon in de behuizingen gestoken.

Aan de achterkant van de binnenunit heb ik een stroomaansluiting en een stroomschakelaar geplaatst, en bij de buiteneenheid heb ik een eenvoudige jumperdraad als stroomschakelaar gebruikt.

En dat is alles, ons Arduino draadloze weerstation werkt nu, maar wat er in deze video overblijft, is om te kijken hoe het programma werkt.

Arduino draadloze weerstationcode

Arduino weerstation code buitenunit:

/*
  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)

Beschrijving: De buitenunit is de zender van de draadloze communicatie, dus hier moeten we eerst de RF24-bibliotheek, de DHT-bibliotheek en de LowPower-bibliotheek opnemen die wordt gebruikt om de Arduino in de slaapstand te zetten.

Na het definiëren van hun instanties, de pinnen waarop de modules zijn aangesloten en enkele variabelen, moeten we in de setup-sectie het draadloze communicatie-adres initialiseren. Dan lezen we in het lusgedeelte eerst de gegevens van de DHT22-sensor of dat is de temperatuur en vochtigheid. Aanvankelijk zijn deze waarden gehele getallen en gescheiden, dus ik converteer ze naar een enkele String-variabele, plaats ze in de tekenreeks en gebruik de radio.write()-functie om deze gegevens naar de binnenunit te sturen. Met behulp van de for-lus verzenden we de gegevens 3 keer om er zeker van te zijn dat de ontvanger gegevens ontvangt voor het geval de controller bezig is op het moment van verzenden.

Aan het einde zetten we de Arduino voor een bepaalde tijd in de slaapstand om het stroomverbruik te minimaliseren.

Arduino weerstation binnenunit code:

/*
  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)

Beschrijving: Aan de andere kant, bij de binnenunit of de ontvanger, moeten we nog twee bibliotheken toevoegen, één voor de DS3231 real-time klokmodule en één voor het OLED-display, de U8G2-bibliotheek. Op dezelfde manier als eerder, moeten we de instanties, de pinnen en enkele variabelen definiëren die nodig zijn voor het onderstaande programma. Ook hier moeten we de temperatuur- en vochtigheidspictogrammen definiëren als bitmaps.

Temperatuurpictogram bitmap:

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

Voor dit doel kunnen we GIMP gebruiken, een open source afbeeldingseditor, waarmee we alles kunnen tekenen en vervolgens exporteren als bitmap(.xbm).

Dan kunnen we dit bestand openen met een kladblok en van daaruit kunnen we de bitmap kopiëren naar de Arduino-code.

Merk op dat we hier de bitmap als constant kunnen definiëren met behulp van de PROGMEM variabele modifier, en op die manier wordt de bitmap opgeslagen in het flashgeheugen in plaats van in de SRAM van het Arduino-bord.

static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM // Save in the Flash memory 
static unsigned char Temperature_20Icon_bits[] // Save in the SRAM

In het setup-gedeelte moeten we de draadloze communicatie initialiseren en het OLED-display en de realtimeklokmodule initialiseren.

Vervolgens controleren we in de lussectie constant of er binnenkomende data beschikbaar is om via de NRF24L01-modules te worden uitgelezen. Indien waar, met behulp van de radio.read() functie lezen we het, en slaan de eerste twee karakters op in de temperatuur String variabele, en de volgende twee karakters in de vochtigheid String variabele.

Vervolgens gebruiken we de millis()-functie om de verschillende gegevens op het display weer te geven met intervallen die zijn gedefinieerd met de intervalvariabele die ik heb ingesteld op 3 seconden. We gebruiken de millis()-functie omdat op deze manier de rest van de code herhaaldelijk kan worden uitgevoerd, terwijl in het geval dat we de delay()-functie gebruiken, het programma op die periode wacht, dus op die manier zouden we waarschijnlijk de binnenkomende gegevens missen van de buitenunit.

Vervolgens drukken we met behulp van de functies firstPage() en nextPage() van de U8G2-bibliotheek de vijf verschillende schermen af ​​die zijn gedefinieerd met de aangepaste functies.

De aangepaste functie drawDate() haalt de datum- en tijdinformatie uit de realtimeklokmodule en drukt deze op de juiste manier af op het display. De functie drawInTemperature() leest de binnentemperatuur en drukt deze op de juiste manier af op het display. In feite wordt dezelfde methode gebruikt voor het afdrukken van alle schermen op het scherm.

Dus dat zou alles zijn, ik hoop dat je genoten hebt van dit Arduino-project en iets nieuws hebt geleerd. Stel gerust een vraag in de opmerkingen hieronder.


Productieproces

  1. Weerstation gebaseerd op Raspberry Pi
  2. Raspberry Pi 2 weerstation
  3. Raspberry Pi-weerstation
  4. Weerstation V 2.0
  5. Audiofrequentiedetector
  6. Draadloze lichtschakelaarmanipulator
  7. Tech-TicTacToe
  8. Arduino Countdown Timer
  9. $10 draagbaar Arduino-weerstation (AWS)
  10. eDOT - op Arduino gebaseerde precisieklok en weerstation
  11. ThingSpeak Arduino-weerstation