Новости
- підготовка
- підключаємо фоторезистор
- Датчик тиску та температури
- підключення дисплея
- Налаштування Slave'a
- Налаштування Master'a
У даній статті я розповім про те, як зробити крок в світ Arduino і змайструвати особисту метеостанцію. Метеостанція буде складатися з двох модулів: один модуль буде зчитувати інформацію з підключених датчиків, інший - виводити лічені дані на невеликий дисплей. Для передачі повної інформації будемо застосовувати Bluetooth.
Також наведу інформацію з налаштування BT-модулів для видатної роботи один з одним.
Отже, поїхали!
Почнемо з того, що для того щоб почати свої перші вироби на платформі Arduino не потрібно великих знань. Всю інформацію можна отримати з інтернету, зокрема, дуже допомогли навчальні уроки від Amperka.ru .
підготовка
Для виготовлення прототипів пристроїв знадобляться наступні елементи:
Для прошивки будемо використовувати рідну Arduino IDE.
Хочу спочатку звернути увагу на те, що хоча б один модуль повинен бути HC-05 (НЕ 06!), Це важливо. Справа в тому, що HC-06 не підтримує режим master, таким чином взявши обидва модуля 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) {if (! bmp.begin ()) {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 з усіма підключеними датчиками
підключення дисплея
Контакти дисплея LCD1602 підключаються аналогічно, як і для BMP085:
- ЖК SDA -> Arduino SDA (A4)
- ЖК SCL -> Arduino SCL (А5)
- ЖК GND -> Arduino GND
- ЖК VCC -> Arduino 5V
приклад коду
# Include <Wire.h> # include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd (0x27, 16, 2); void setup () {lcd.init (); lcd.backlight (); lcd.print ( "Hello"); lcd.setCursor (0, 1); lcd.print ( "World!"); } Void loop () {}
А тепер найцікавіше. «Насаджуємо» наші Шілд з bt-модулем на нашу Arduino:
Master-пристрій буде підключатися до Slave-пристрою, який буде чекати вхідного підключення. На одній з плат встановлюємо перемикач в H, це і буде наш master. На іншій платі - в L, це буде slave.
Прикріпивши модулі до Arduino можна починати настройку. Для настройки master-a потрібно буде послати деякий набір команд в bt-модуль, будемо робити це за допомогою Serial Monitor (Ctrl + Shift + M). При обміні повідомленнями рекомендується виставити Baud rate -> 38400 & «Both NL & CR».
Надіславши команду «AT» і натиснувши відправити, ми очікуємо відповідь «OK». Якщо це так - плата підключена правильно, можна продовжувати. Якщо немає - варто повернутися на пару кроків назад і перевірити коректність підключення bluetooth-модуля.
Кілька важливих АТ-команд, які нам можу стати в нагоді:
AT - просто поверне «OK», значить все в порядку
AT + NAME? - поверне ім'я модуля. Ми також можемо поставити своє ім'я, пославши, наприклад, AT + NAME = WEATHER_MONITOR
AT + ROLE? - одна з ключових команд, поверне роль пристрою, master / slave. Задати значення можна за допомогою AT + ROLE = 0 - перевести в режим slave, або AT + ROLE = 1 - режим master.
AT + PSWD? - поверне пін-код, який використовується для підключення.
AT + ADDR? - поверне адресу пристрою, наприклад «14: 2: 110007». Варто зауважити, що при використанні адреси в посилаються AT-командах двокрапки «:» потрібно замінювати запитом «,», таким чином «14: 2: 110007» -> «14,2,110007».
Налаштування Slave'a
Тут ніяких рухів тіла не потрібно, тому просто підключаємо плату до харчування.
Налаштування Master'a
Етап перший. Конфігурація.
- Надсилаємо AT + ORGL, тим самим повертаючи модуль до його початкової конфігурації
- Ім'я модуля можна змінити, пославши AT + NAME = myname.
- AT + RMAAD - видаляємо інформацію про попередні «спарювання».
- AT + PSWD = 1234 - встановлюємо пароль
- AT + ROLE = 1 - говоримо пристрою, що воно буде працювати в master режимі.
- AT + CMODE = 1 - говоримо пристрою, що воно буде підключатися до будь-яких адресами.
Етап другий. Підключення.
- Відправляємо команду AT, щоб упевнитися, що модуль підключений і готовий до роботи.
- AT + INIT - ініціалізація. Якщо у відповідь отримуємо ERROR (17) - нічого страшного, значить команда ініціалізації вже посилалася, продовжуємо роботу.
- AT + INQ - починаємо пошук доступних BT-пристроїв, відповідь буде містити список з адрес
- AT + LINK = <адреса> - тут відбувається безпосередньо підключення до slave-пристрою. Команда на підключення може, наприклад, виглядати так: AT + LINK = 14,2,110007.
Після виконання останньої команди діоди почнуть мигати з меншою частотою, що говорить про успішне підключення.
На цьому майже все. Залишається написати скетчі, в яких ми зчитуємо-відправляємо-приймаємо-відображаємо погодні дані. При бажанні можна відмовитися від макетної плати і приступити до пайки, а потім помістити конструкції в корпусу.
Результат роботи
скетчі:
Код метео-монітора
#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 (); 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}; bool availible = Serial.available (); if (availible) {do {someChar [i ++] = Serial.read (); 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"); 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) {pinMode (rxPin, INPUT); pinMode (txPin, OUTPUT); btSerial.begin (38400); Serial.begin (9600); Serial.println ( "Pressure Sensor Test"); Serial.println ( ""); if (! bmp.begin ()) {Serial.print ( "Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!"); while (1); } DisplaySensorDetails (); } Int counter = 0; void loop (void) {sensors_event_t event; bmp.getEvent (& event); SensorData data; if (event.pressure) {data.Pressure = event.pressure; float temperature; bmp.getTemperature (& temperature); data.Temperature = temperature; 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; } Else {Serial.println ( "Sensor error"); } Serial.println ( ""); data.SendDataToRemote (); }
На цьому все. Дякую за увагу!
AT + PSWD?AT + ADDR?