Estação Meteorológica Bluetooth Arduino Starter

Neste artigo, falarei sobre como dar o primeiro passo no mundo do Arduino e criar sua própria estação meteorológica. A estação meteorológica consistirá em dois módulos: um módulo lerá as informações dos sensores conectados e o outro exibirá os dados lidos em uma tela pequena. Usaremos o Bluetooth para transmitir informações.

Também fornecerei informações sobre como configurar os módulos BT para trabalharem uns com os outros.

imagem

Então vamos lá!

Por onde começar?


Para começar, para iniciar seu primeiro trabalho na plataforma Arduino, você não precisa de amplo conhecimento. Todas as informações podem ser obtidas na Internet, em particular as lições de treinamento do Amperka.ru ajudaram bastante .

Preparação


Para a fabricação de dispositivos protótipos, você precisará dos seguintes elementos:

  • Fotoresistor de 500 kΩ (x1)
  • Barômetro BMP085 (x1)
  • Módulo BT HC-05 (x2)
  • LCD, LCD LCM 1602 i2c (x1)
  • Conjunto de E-mail componentes (tábua de pão, resistências, diodos) (x1)
  • Arduino UNO R3 (x2)

Para o firmware, usaremos o IDE nativo do Arduino.

Quero chamar a atenção para o fato de que pelo menos um módulo deve ser o HC-05 (não 06!), Isso é importante. O fato é que o HC-06 não suporta o modo mestre , ou seja, tomando os dois módulos 06, não seremos capazes de configurá-los para trabalhar uns com os outros. Decidi usar os dois módulos HC-05 ao mesmo tempo para evitar problemas de compatibilidade, se houver.

As nuances da configuração dos módulos BT serão descritas abaixo.

imagem

Ambos os módulos estão embutidos na blindagem, ou seja, não deve haver problemas na conexão com a placa Arduino.

Iniciar montagem


Nós conectamos um fotorresistor


A resistência do fotorresistor depende da incidência de luz nele. Usando um fotorresistor em conjunto com um resistor convencional, obtemos um divisor de tensão no qual a tensão que passa pelo fotorresistor muda, dependendo do nível de iluminação.

O mecanismo para obter informações úteis do sensor é muito simples: a função analogRead (pin_number) retornará um valor que representará o grau de iluminação. A sensibilidade do sensor pode ser controlada jogando com resistores de diferentes classificações; na minha opinião, 10kOhm é a classificação ideal.

imagem

Exemplo de código
int lightPin= 0; // ,    
void setup()
{
}
void loop()
{
  int light = analogRead(lightPin);
}


Sensor de pressão e temperatura


Para medir temperatura, pressão e altitude, usaremos o barômetro BMP085.

imagem

Para conectar o BMP085 ao Arduino, precisamos de 4 pinos:

  • Vcc - conectar à alimentação + 5v
  • SDA - SDA no Arduino (A4)
  • SCL - SCL na placa Arduino (A5)
  • GND - conecte ao terra

imagem

Para obter valores do sensor, você deve conectar a biblioteca Adafruit.

Exemplo de código

#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 com todos os sensores conectados
image

Conexão de exibição


Os pinos do visor LCD1602 são conectados da mesma maneira que no BMP085:

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

imagem

Exemplo de código
/*     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


Conexão Bluetooth


E agora a parte divertida. Nós "plantamos" nossos escudos com um módulo bt no nosso Arduino: o

imagem

dispositivo mestre será conectado ao dispositivo escravo, que aguardará a conexão de entrada. Em uma das placas, colocamos o interruptor em H, este será o nosso mestre. Por outro lado - em L, será um escravo.

imagem

Ao anexar os módulos ao Arduino, você pode iniciar a instalação. Para configurar o mestre, você precisará enviar um determinado conjunto de comandos para o módulo bt, faremos isso usando o Monitor Serial (Ctrl + Shift + M). Ao enviar mensagens, é recomendável definir a taxa de transmissão -> 38400 e "Both NL&CR".

Depois de enviar o comando AT e clicar em enviar, esperamos uma resposta OK. Nesse caso - a placa está conectada corretamente, você pode continuar. Caso contrário, vale a pena voltar algumas etapas e verificar a conexão do módulo bluetooth.

Alguns comandos AT importantes que podem ser úteis:

AT - retorna "OK", então está tudo bem
AT + NAME? - retornará o nome do módulo. Também podemos definir nosso próprio nome enviando, por exemplo, AT + NAME = WEATHER_MONITOR
AT + ROLE? - um dos comandos principais retornará a função do dispositivo, mestre / escravo. Você pode definir o valor usando AT + ROLE = 0 - alterne para o modo escravo ou AT + ROLE = 1 - modo mestre.
AT + PSWD? - retornará o código PIN usado para conectar.
AT + ADDR? - retornará o endereço do dispositivo, por exemplo, "14: 2: 110007". Vale ressaltar que, ao usar o endereço nos comandos AT enviados, os dois pontos ":" devem ser substituídos por vírgulas ",", ou seja, "14: 2: 110007" -> "14,2,110007".

Configuração do escravo


Nenhum movimento do corpo é necessário aqui, então basta conectar a placa à energia.

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 = <endereço> - existe uma conexão direta com o dispositivo escravo. O comando de conexão pode, por exemplo, ter esta aparência: AT + LINK = 14,2,110007.

Após a execução do último comando, os diodos piscarão em uma frequência mais baixa, o que indica uma conexão bem-sucedida.

Linha de chegada


Isso é quase tudo. Resta escrever esboços nos quais lemos, enviamos, aceitamos, exibimos dados meteorológicos. Se desejar, você pode abandonar a tábua de pão e começar a soldar e, em seguida, colocar a estrutura no estojo.

Resultado do trabalho
image
image
image
image

Esboços:

Código do Monitor Meteorológico
#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);
      }
}


Código do sensor climático
#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();
}


Só isso. Obrigado pela atenção!

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


All Articles