Station météo Bluetooth Arduino Starter

Dans cet article, je vais vous expliquer comment faire le premier pas dans le monde d'Arduino et créer votre propre station météo. La station météo comprendra deux modules: un module lira les informations des capteurs connectés, l'autre affichera les données lues sur un petit écran. Nous utiliserons Bluetooth pour transmettre des informations.

Je fournirai également des informations sur la configuration des modules BT pour travailler ensemble.

image

Alors allons-y!

Par où commencer?


Pour commencer, afin de commencer vos premiers bricolages sur la plateforme Arduino, vous n'avez pas besoin de connaissances approfondies. Toutes les informations peuvent être obtenues sur Internet, en particulier, les cours de formation d' Amperka.ru ont beaucoup aidé .

La préparation


Pour la fabrication de prototypes d'appareils, vous aurez besoin des éléments suivants:

  • Photorésistance 500 kΩ (x1)
  • Baromètre BMP085 (x1)
  • Module BT HC-05 (x2)
  • LCD, LCD LCM 1602 i2c (x1)
  • Ensemble d'e-mails composants (planche à pain, résistances, diodes) (x1)
  • Arduino UNO R3 (x2)

Pour le firmware, nous utiliserons l'IDE Arduino natif.

Je veux attirer l'attention sur le fait qu'au moins un module doit être HC-05 (pas 06!), C'est important. Le fait est que le HC-06 ne prend pas en charge le mode maître , c'est-à-dire en prenant les deux modules 06, nous ne pourrons pas les configurer pour qu'ils fonctionnent ensemble. J'ai décidé de prendre les deux modules HC-05 en même temps pour éviter les problèmes de compatibilité, le cas échéant.

Les nuances de la configuration des modules BT seront décrites ci-dessous.

image

Les deux modules sont intégrés dans le blindage, c'est-à-dire qu'il ne devrait y avoir aucun problème de connexion à la carte Arduino.

Commencer l'assemblage


Nous connectons une photorésistance


La résistance de la photorésistance dépend de la lumière incidente sur elle. En utilisant une photorésistance en conjonction avec une résistance conventionnelle, nous obtenons un diviseur de tension dans lequel la tension passant à travers la photorésistance change, en fonction du niveau d'éclairage.

Le mécanisme permettant d'obtenir des informations utiles du capteur est très simple: la fonction analogRead (pin_number) renverra une valeur qui représentera le degré d'éclairage. La sensibilité du capteur peut être contrôlée en jouant avec des résistances de différentes valeurs; à mon avis, 10kOhm est la note optimale.

image

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


Capteur de pression et de température


Pour mesurer la température, la pression et l'altitude, nous utiliserons le baromètre BMP085.

image

Pour connecter le BMP085 à Arduino, nous avons besoin de 4 broches:

  • Vcc - se connecter à l'alimentation + 5v
  • SDA - SDA sur Arduino (A4)
  • SCL - SCL sur la carte Arduino (A5)
  • GND - connectez-vous au sol

image

Pour prendre des valeurs du capteur, vous devez connecter la bibliothèque Adafruit.

Exemple de code

#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 avec tous les capteurs connectés
image

Connexion d'affichage


Les broches d'affichage LCD1602 sont connectées de la même manière que pour BMP085:

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

image

Exemple de code
/*     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


Connexion Bluetooth


Et maintenant pour la partie amusante. Nous "plantons" nos boucliers avec un module bt sur notre Arduino: l'

image

appareil maître se connectera à l'appareil esclave, qui attendra une connexion entrante. Sur l'une des cartes, nous avons mis le commutateur sur H, ce sera notre maître. Sur l'autre carte - en L, ce sera un esclave.

image

En connectant les modules à l'Arduino, vous pouvez commencer la configuration. Pour configurer le maître, vous devrez envoyer un certain ensemble de commandes au module bt, nous le ferons en utilisant le moniteur série (Ctrl + Shift + M). Lors de la messagerie, il est recommandé de définir le débit en bauds -> 38400 et «Both NL&CR».

Après avoir envoyé la commande AT et cliqué sur envoyer, nous attendons une réponse OK. Si c'est le cas - la carte est connectée correctement, vous pouvez continuer. Sinon, cela vaut la peine de revenir en arrière de quelques étapes et de vérifier la connexion du module Bluetooth.

Quelques commandes AT importantes qui peuvent être utiles:

AT - renvoie simplement "OK", donc tout va bien
AT + NAME? - renverra le nom du module. Pouvons-nous également définir notre propre nom en envoyant, par exemple, AT + NAME = WEATHER_MONITOR
AT + ROLE? - l'un des raccourcis clavier renverra le rôle de l'appareil, maître / esclave. Vous pouvez définir la valeur en utilisant AT + ROLE = 0 - passer en mode esclave, ou AT + ROLE = 1 - mode maître.
AT + PSWD? - renverra le code PIN utilisé pour se connecter.
AT + ADDR? - renverra l'adresse de l'appareil, par exemple, «14: 2: 110007». Il est à noter que lors de l'utilisation de l'adresse dans les commandes AT envoyées, les deux points ":" doivent être remplacés par des virgules ",", c'est-à-dire «14: 2: 110007» -> «14,2,110007».

Configuration esclave


Aucun mouvement du corps n'est nécessaire ici, alors branchez simplement la carte au pouvoir.

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> - il existe une connexion directe avec le périphérique esclave. La commande de connexion peut, par exemple, ressembler à ceci: AT + LINK = 14,2,110007.

Une fois la dernière commande exécutée, les diodes clignotent à une fréquence inférieure, ce qui indique une connexion réussie.

Ligne d'arrivée


C’est presque tout. Il reste à écrire des croquis dans lesquels nous lisons-envoyons-acceptons-affichons les données météorologiques. Si vous le souhaitez, vous pouvez abandonner la planche à pain et commencer à souder, puis placer la structure dans le boîtier.

Résultat du travail
image
image
image
image

Croquis:

Code du moniteur météo
#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);
      }
}


Code du capteur météo
#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();
}


C’est tout. Merci de votre attention!

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


All Articles