Arduino Starter Bluetooth Wetterstation

In diesem Artikel werde ich darüber sprechen, wie Sie den ersten Schritt in die Welt von Arduino machen und Ihre eigene Wetterstation bauen können. Die Wetterstation besteht aus zwei Modulen: Ein Modul liest Informationen von den angeschlossenen Sensoren, das andere zeigt die gelesenen Daten auf einem kleinen Bildschirm an. Wir werden Bluetooth verwenden, um Informationen zu übertragen.

Ich werde auch Informationen zum Einrichten von BT-Modulen für die Zusammenarbeit bereitstellen.

Bild

Also lass uns gehen!

Wo soll ich anfangen?


Um Ihre ersten Bastelarbeiten auf der Arduino-Plattform zu beginnen, benötigen Sie zunächst keine umfassenden Kenntnisse. Alle Informationen können aus dem Internet bezogen werden, insbesondere die Schulungen bei Amperka.ru haben sehr geholfen .

Vorbereitung


Für die Herstellung von Prototypen benötigen Sie folgende Elemente:

  • 500 kΩ Fotowiderstand (x1)
  • Barometer BMP085 (x1)
  • BT-Modul HC-05 (x2)
  • LCD, LCD LCM 1602 i2c (x1)
  • E-Mail-Set Komponenten (Steckbrett, Widerstände, Dioden) (x1)
  • Arduino UNO R3 (x2)

Für die Firmware verwenden wir die native Arduino IDE.

Ich möchte darauf hinweisen, dass mindestens ein Modul HC-05 sein muss (nicht 06!). Dies ist wichtig. Tatsache ist, dass der HC-06 den Master- Modus nicht unterstützt , d. H. Wenn wir beide Module 06 nehmen, können wir sie nicht so konfigurieren, dass sie miteinander arbeiten. Ich habe mich entschieden, beide HC-05-Module gleichzeitig zu verwenden, um etwaige Kompatibilitätsprobleme zu vermeiden.

Die Nuancen beim Einrichten von BT-Modulen werden nachfolgend beschrieben.

Bild

Beide Module sind in die Abschirmung eingebaut, dh es sollte keine Probleme beim Anschließen an die Arduino-Platine geben.

Montage starten


Wir schließen einen Fotowiderstand an


Der Widerstand des Fotowiderstands hängt vom auf ihn einfallenden Licht ab. Unter Verwendung eines Fotowiderstands in Verbindung mit einem herkömmlichen Widerstand erhalten wir einen Spannungsteiler, bei dem sich die durch den Fotowiderstand fließende Spannung in Abhängigkeit von der Beleuchtungsstärke ändert.

Der Mechanismus zum Abrufen nützlicher Informationen vom Sensor ist sehr einfach: Die Funktion analogRead (pin_number) gibt einen Wert zurück, der den Beleuchtungsgrad darstellt. Die Empfindlichkeit des Sensors kann durch Spielen mit Widerständen unterschiedlicher Nennleistung gesteuert werden. Meiner Meinung nach ist 10 kOhm die optimale Bewertung.

Bild

Codebeispiel
int lightPin= 0; // ,    
void setup()
{
}
void loop()
{
  int light = analogRead(lightPin);
}


Druck- und Temperatursensor


Zur Messung von Temperatur, Druck und Höhe verwenden wir das Barometer BMP085.

Bild

Um den BMP085 mit Arduino zu verbinden, benötigen wir 4 Pins:

  • Vcc - an Strom + 5V anschließen
  • SDA - SDA auf Arduino (A4)
  • SCL - SCL auf dem Arduino-Board (A5)
  • GND - mit Masse verbinden

Bild

Um Werte vom Sensor zu übernehmen, müssen Sie die Adafruit-Bibliothek verbinden.

Codebeispiel

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
void setup(void)
{
/* Initialise the sensor */
  if(!bmp.begin())
  {
    /* There was a problem detecting the BMP085 ... check your connections */
    Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
}
void loop(void)
{
  sensors_event_t event;
  bmp.getEvent(&event);
  if (event.pressure)
  {
    float pressure = event.pressure;
    
    float temperature;
    bmp.getTemperature(&temperature);

    float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
    float altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure); 
  }
}


Arduino mit allen angeschlossenen Sensoren
image

Verbindung anzeigen


Die LCD1602-Anzeigestifte werden wie bei BMP085 angeschlossen:

  • LCD SDA -> Arduino SDA (A4)
  • LCD SCL -> Arduino SCL (A5)
  • LCD GND -> Arduino GND
  • LCD VCC -> Arduino 5V

Bild

Codebeispiel
/*     LCD  1602. */  
#include <Wire.h>
#include <LiquidCrystal_I2C.h>  
LiquidCrystal_I2C lcd(0x27,16,2); // :  ,    
void setup()
{
    lcd.init();
    //  lcd
    lcd.backlight();
    //  
    //     1 
    lcd.print("Hello");
    //  
    lcd.setCursor(0, 1);
    //     2 
    lcd.print("World!");
    //  
}  
void loop()
{ }
// : http://xrobot.by/modules/lcd_4_4#ixzz3vQXoFKOj


Bluetooth-Verbindung


Und jetzt zum lustigen Teil. Wir "pflanzen" unsere Schilde mit einem BT-Modul auf unserem Arduino: Das

Bild

Master-Gerät stellt eine Verbindung zum Slave-Gerät her und wartet auf eine eingehende Verbindung. Auf einer der Karten stellen wir den Schalter auf H, dies wird unser Meister sein. Auf der anderen Seite - in L wird es ein Sklave sein.

Bild

Durch Anschließen der Module an das Arduino können Sie mit dem Setup beginnen. Um den Master zu konfigurieren, müssen Sie einen bestimmten Befehlssatz an das BT-Modul senden. Dies geschieht über den seriellen Monitor (Strg + Umschalt + M). Beim Messaging wird empfohlen, die Baudrate auf> 38400 und "Both NL & CR" einzustellen.

Nachdem Sie den AT-Befehl gesendet und auf Senden geklickt haben, erwarten wir eine OK-Antwort. Wenn ja - die Karte ist richtig angeschlossen, können Sie fortfahren. Wenn nicht, lohnt es sich, ein paar Schritte zurück zu gehen und die Verbindung des Bluetooth-Moduls zu überprüfen.

Einige wichtige AT-Befehle, die nützlich sein können:

AT - gibt nur "OK" zurück. Ist also alles in Ordnung
? AT + NAME? - gibt den Namen des Moduls zurück. Können wir auch unseren eigenen Namen festlegen, indem wir beispielsweise AT + NAME = WEATHER_MONITOR
AT + ROLE senden? - Einer der Schlüsselbefehle gibt die Rolle des Geräts, Master / Slave, zurück. Sie können den Wert mit AT + ROLE = 0 - Schalter in den Slave-Modus oder AT + ROLE = 1 - Master-Modus einstellen.
AT + PSWD? - gibt den für die Verbindung verwendeten PIN-Code zurück.
AT + ADDR? - gibt die Adresse des Geräts zurück, z. B. "14: 2: 110007". Es ist anzumerken, dass bei Verwendung der Adresse in den gesendeten AT-Befehlen der Doppelpunkt ":" durch Kommas ",", d. H. "14: 2: 110007" -> "14,2,110007".

Slave-Setup


Hier sind keine Körperbewegungen erforderlich. Schließen Sie das Board einfach an die Stromversorgung an.

Master'a


. .

  1. AT+ORGL,
  2. , AT+NAME=myname.
  3. AT+RMAAD — «».
  4. AT+PSWD=1234 —
  5. AT+ROLE=1 — , master .
  6. AT+CMODE=1 — , .

. .

  1. AT, , .
  2. AT+INIT — . ERROR(17) — , , .
  3. AT+INQ — BT-,
  4. AT + LINK = <Adresse> - Es besteht eine direkte Verbindung zum Slave-Gerät. Der Verbindungsbefehl kann beispielsweise folgendermaßen aussehen: AT + LINK = 14,2,110007.

Nachdem der letzte Befehl ausgeführt wurde, blinken die Dioden mit einer niedrigeren Frequenz, was auf eine erfolgreiche Verbindung hinweist.

Ziellinie


Das ist fast alles. Es bleiben Skizzen zu schreiben, in denen wir Wetterdaten lesen, senden, akzeptieren und anzeigen. Wenn Sie möchten, können Sie das Steckbrett verlassen und mit dem Löten beginnen und dann die Struktur in das Gehäuse legen.

Arbeitsergebnis
image
image
image
image

Skizzen:

Wetterüberwachungscode
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>  

LiquidCrystal_I2C lcd(0x27,16,2); // :  ,    

#define rxPin 2
#define txPin 3

SoftwareSerial btSerial(rxPin, txPin);

bool isDisplayingMode = true;
 
void setup()
{
   lcd.init();
   lcd.backlight();
   // define pin modes for tx, rx pins:
   pinMode(rxPin, INPUT);
   pinMode(txPin, OUTPUT);
   btSerial.begin(38400); 
   Serial.begin(38400);
   Serial.println("Serial started");
   
           
   lcd.print("    Waiting");
   lcd.setCursor(0, 1);
   lcd.print(" for connection");
   
   btSerial.println("AT");
   while (!btSerial.available());
   while (btSerial.available() > 0)
        char c = btSerial.read();
   btSerial.println("AT+INIT");
   while (!btSerial.available());
   while (btSerial.available() > 0)
        char c = btSerial.read();
   btSerial.println("AT+INQ");
   while (!btSerial.available());
   while (btSerial.available() > 0)
        char c = btSerial.read();
   btSerial.println("AT+LINK=2014,5,191146");  
   while (!btSerial.available());
   while (btSerial.available() > 0)
        char c = btSerial.read();   
}

void loop()
{   
  int i = 0;
  char someChar[32] = {0};
  // when characters arrive over the serial port...
  bool availible = Serial.available();
  if(availible) {
    do{
        someChar[i++] = Serial.read();
      //As data trickles in from your serial port you are grabbing as much as you can, 
      //but then when it runs out (as it will after a few bytes because the processor 
      //is much faster than a 9600 baud device) you exit loop, which then restarts, 
      //and resets i to zero, and someChar to an empty array.So please be sure to keep this delay 
      delay(3);                  
 
    }while (Serial.available() > 0);

    lcd.clear();
    Serial.println(i);
    btSerial.println(someChar);
    Serial.println(someChar);
  }
 
  lcd.setCursor(0, 0);
  while(btSerial.available()) 
      {
        if (isDisplayingMode)
        {
          lcd.clear();
          isDisplayingMode = false;
        }
        char c = (char)btSerial.read();
        Serial.print(c);          
        if (c != 13 && c != 10)
          lcd.print(c);
        if (c == '\n')
          lcd.setCursor(0, 1);
      }
}


Wettersensorcode
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
int lightSensorPin = 0;

#define rxPin 2
#define txPin 3

SoftwareSerial btSerial(rxPin, txPin);

struct SensorData
{
  float Pressure;
  float Temperature;
  float Altitude;
  float Lightness;
  void DisplaySensorData()
{
    Serial.print("Light:       ");
    Serial.print(this->Lightness, 2);
    Serial.println("%");
    Serial.print("Altitude:    "); 
    Serial.print(this->Altitude); 
    Serial.println(" m");
    Serial.print("Temperature: ");
    Serial.print(this->Temperature);
    Serial.println(" C");
    /* Display atmospheric pressue in hPa */
    Serial.print("Pressure:    ");
    Serial.print(this->Pressure);
    Serial.println(" hPa");
    Serial.println("");
}

void DisplaySensorDataInTwoRows()
{
    Serial.print("Temp: "); Serial.print(this->Temperature); Serial.println(" C");
    Serial.print("Pr: "); Serial.print(this->Pressure); Serial.println(" Pa");
    delay(1000);    
    Serial.print("Alt: "); Serial.print(this->Altitude); Serial.println(" m");
    Serial.print("Light: "); Serial.print(this->Lightness); Serial.println(" %");
    delay(1000);
}
void SendDataToRemote()
{
    btSerial.print("Temp: "); btSerial.print(this->Temperature); btSerial.print(" C\n");
    btSerial.print("Pr:   "); btSerial.print(this->Pressure); btSerial.print(" hPa\n");
    delay(5000);    
    btSerial.print("Alt:   "); btSerial.print(this->Altitude); btSerial.print(" m\n");
    btSerial.print("Light: "); btSerial.print(this->Lightness); btSerial.print(" %  \n");
    delay(5000);
}
};



void displaySensorDetails(void)
{
  sensor_t sensor;
  bmp.getSensor(&sensor);
  
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" hPa");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" hPa");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" hPa");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void setup(void) 
{
   // define pin modes for tx, rx pins:
   pinMode(rxPin, INPUT);
   pinMode(txPin, OUTPUT);
   btSerial.begin(38400);
   
  Serial.begin(9600);
  Serial.println("Pressure Sensor Test"); Serial.println("");
  
   
  /* Initialise the sensor */
  if(!bmp.begin())
  {
    /* There was a problem detecting the BMP085 ... check your connections */
    Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
    
  /* Display some basic information on this sensor */
  displaySensorDetails();
}
int counter = 0;
void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event;
  bmp.getEvent(&event);
  SensorData data;
  /* Display the results (barometric pressure is measure in hPa) */
  if (event.pressure)
  {
    data.Pressure = event.pressure;
    
    float temperature;
    bmp.getTemperature(&temperature);
    data.Temperature = temperature;

    /* Then convert the atmospheric pressure, and SLP to altitude         */
    /* Update this next line with the current SLP for better results      */
    float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
    float altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure);
    data.Altitude = altitude;  
    
    int lightValue = analogRead(lightSensorPin);
    float lightValueInPercent = 1.0 * lightValue / 1024 * 100;
    data.Lightness = lightValueInPercent;
    
    //data.DisplaySensorDataInTwoRows();    
  }
  else
  {
    Serial.println("Sensor error");
  }
  Serial.println("");
  data.SendDataToRemote();
}


Das ist alles. Vielen Dank für Ihre Aufmerksamkeit!

Source: https://habr.com/ru/post/de388605/


All Articles