محطة اردوينو كاتب بلوتوث الطقس

في هذه المقالة ، سأتحدث عن كيفية اتخاذ الخطوة الأولى في عالم Arduino وإنشاء محطة الطقس الخاصة بك. ستتألف محطة الطقس من وحدتين: واحدة ستقرأ المعلومات من أجهزة الاستشعار المتصلة ، والأخرى تعرض البيانات المقروءة على شاشة صغيرة. سنستخدم البلوتوث لنقل المعلومات.

سأقدم أيضًا معلومات حول إعداد وحدات BT للعمل مع بعضها البعض.

الصورة

لذا دعنا نذهب!

من أين تبدأ؟


بادئ ذي بدء ، من أجل بدء الحرف الأولى الخاصة بك على منصة Arduino ، لا تحتاج إلى معرفة واسعة. يمكن الحصول على جميع المعلومات من الإنترنت ، على وجه الخصوص ، ساعدت دروس التدريب من Amperka.ru الكثير .

تحضير


لتصنيع أجهزة النموذج الأولي ، ستحتاج إلى العناصر التالية:

  • 500 kΩ مقاوم ضوئي (x1)
  • البارومتر BMP085 (x1)
  • وحدة BT-HC-05 (x2)
  • LCD ، LCD LCM 1602 i2c (x1)
  • تعيين البريد الإلكتروني المكونات (اللوح ، المقاومات ، الثنائيات) (x1)
  • Arduino UNO R3 (x2)

بالنسبة إلى البرامج الثابتة ، سنستخدم برنامج Arduino IDE الأصلي.

أود أن ألفت الانتباه إلى حقيقة أن وحدة واحدة على الأقل يجب أن تكون HC-05 (وليس 06!) ، وهذا أمر مهم. والحقيقة هي أن HC-06 لا يدعم الوضع الرئيسي ، أي باستخدام كلتا الوحدتين 06 ، لن نتمكن من تكوينهم للعمل مع بعضهم البعض. قررت أن آخذ كلا النموذجين HC-05 في نفس الوقت لتجنب مشاكل التوافق ، إن وجدت.

سيتم وصف الفروق الدقيقة في إعداد وحدات BT أدناه.

الصورة

كلا الوحدتين مدمجتان في الدرع ، أي أنه يجب ألا تكون هناك مشاكل في الاتصال بلوحة Arduino.

ابدأ التجميع


نقوم بتوصيل مقاوم ضوئي


تعتمد مقاومة المقاوم الضوئي على حادثة الضوء عليه. باستخدام مقاوم ضوئي بالتزامن مع مقاوم تقليدي ، نحصل على مقسم جهد يتغير فيه الجهد الذي يمر عبر المقاوم الضوئي ، اعتمادًا على مستوى الإضاءة.

آلية الحصول على معلومات مفيدة من المستشعر بسيطة للغاية: ستعيد وظيفة analogRead (pin_number) قيمة تمثل درجة الإضاءة. يمكن التحكم في حساسية المستشعر من خلال اللعب بمقاومات من درجات مختلفة ؛ في رأيي ، 10 كيلو أوم هو التصنيف الأمثل.

الصورة

مثال على الرمز
int lightPin= 0; // ,    
void setup()
{
}
void loop()
{
  int light = analogRead(lightPin);
}


جهاز استشعار الضغط ودرجة الحرارة


لقياس درجة الحرارة والضغط والارتفاع ، سنستخدم مقياس BMP085.

الصورة

لربط BMP085 بـ Arduino ، نحتاج إلى 4 دبابيس:

  • VCC - الاتصال بالطاقة + 5 فولت
  • SDA - SDA على Arduino (A4)
  • SCL - SCL على لوحة Arduino (A5)
  • GND - الاتصال بالأرض

الصورة

لأخذ القيم من المستشعر ، يجب عليك توصيل مكتبة Adafruit.

مثال على الرمز

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


اردوينو مع جميع أجهزة الاستشعار المتصلة
image

اتصال الشاشة


ترتبط دبابيس العرض LCD1602 بنفس طريقة توصيل BMP085:

  • LCD SDA -> Arduino SDA (A4)
  • LCD SCL -> Arduino SCL (A5)
  • LCD GND -> Arduino GND
  • LCD VCC -> اردوينو 5 فولت

الصورة

مثال على الرمز
/*     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


اتصال بلوتوث


والآن من أجل الجزء الممتع. نحن "نزرع" دروعنا مع وحدة bt على Arduino:

الصورة

سيتصل الجهاز الرئيسي بجهاز Slave ، الذي سينتظر الاتصال الوارد. في أحد الألواح قمنا بتعيين المفتاح إلى H ، سيكون هذا سيدنا. على اللوحة الأخرى - في L ، سيكون عبدا.

الصورة

من خلال إرفاق الوحدات بـ Arduino ، يمكنك بدء الإعداد. لتكوين الشريحة الرئيسية ، ستحتاج إلى إرسال مجموعة معينة من الأوامر إلى وحدة bt ، وسوف نقوم بذلك باستخدام الشاشة التسلسلية (Ctrl + Shift + M). عند المراسلة ، يوصى بتعيين معدل Baud -> 38400 & "Both NL&CR".

بعد إرسال الأمر AT والنقر فوق إرسال ، نتوقع استجابة جيدة. إذا كان الأمر كذلك - تم توصيل اللوحة بشكل صحيح ، يمكنك المتابعة. إذا لم يكن الأمر كذلك ، فمن الجدير الرجوع بضع خطوات والتحقق من اتصال وحدة البلوتوث.

بعض أوامر AT المهمة التي قد تكون مفيدة:

AT - فقط إرجاع "موافق" ، فهل كل شيء على ما يرام في
AT + NAME؟ - سيعيد اسم الوحدة النمطية. هل يمكننا أيضًا تعيين اسمنا الخاص ، عن طريق إرسال ، على سبيل المثال ، AT + NAME = WEATHER_MONITOR
AT + ROLE؟ - سيعيد أحد الأوامر الرئيسية دور الجهاز الرئيسي / العبد. يمكنك تعيين القيمة باستخدام AT + ROLE = 0 - التبديل إلى الوضع التابع ، أو AT + ROLE = 1 - الوضع الرئيسي.
AT + PSWD؟ - سيعيد الرمز السري المستخدم للتوصيل.
AT + ADDR؟ - سيتم إرجاع عنوان الجهاز ، على سبيل المثال ، "14: 2: 110007". تجدر الإشارة إلى أنه عند استخدام العنوان في أوامر AT المرسلة ، يجب استبدال النقطتين ":" بفواصل "،" أي "14: 2: 110007" -> "14،2،110007".

إعداد الرقيق


لا حاجة لتحركات الجسم هنا ، لذا فقط قم بتوصيل اللوحة بالطاقة.

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 = <address> - يوجد اتصال مباشر بجهاز تابع. قد يبدو أمر الاتصال ، على سبيل المثال ، كما يلي: AT + LINK = 14،2،110007.

بعد تنفيذ الأمر الأخير ، ستومض الثنائيات بتردد أقل ، مما يشير إلى اتصال ناجح.

خط النهاية


هذا كل شيء تقريبًا. يبقى أن نكتب الرسومات التي نقرأ فيها بيانات الطقس ونرسلها ونقبلها ونعرضها. إذا كنت ترغب في ذلك ، يمكنك التخلي عن اللوح وبدء اللحام ، ثم وضع الهيكل في العلبة.

نتيجة العمل
image
image
image
image

اسكتشات:

كود مراقبة الطقس
#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);
      }
}


كود مستشعر الطقس
#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();
}


هذا كل شيء. شكرا لكم على اهتمامكم!

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


All Articles