Барометр на Arduino
Хочу розповісти про процес розробки та створення простого, але в той же час дуже зручного і корисного приладу - барометра. Дане пристрій пригодиться, наприклад, рибалкам, метеочутливим людям, та й взагалі всім, кого з тих чи інших причин цікавить відстежування змін атмосферного тиску.
Також постараюся максимально детально описати логіку роботи ПЗ, щоб навіть початківці ардуинщики змогли не просто повторити пристрій, але й чомусь навчитися і зрозуміти сам принцип.
Трохи передісторії та актуалізації саморобки. Думаю, що таке "барометр" і "тиск" пояснювати не потрібно, перейду відразу до справи. У продажу на сьогоднішній день є багато моделей різних барометрів: електронних, механічних, або їх комбінацій. Але багато з них мають один суттєвий недолік. Справа в тому, що сама по собі абсолютна величина атмосферного тиску, на відміну від температури, наприклад, не так важлива і цікава, як напрямок і швидкість її зміни. Тому, говорячи про тиск, значно важливіше знати, наскільки воно змінилося за певний інтервал часу. У класичному барометрі-анероїді ця проблема вирішується за допомогою додаткової стрілки, за допомогою якої можна вручну зафіксувати попередні показання приладу і при наступному спостереженні вже робити висновки про їх зміну. Що не дуже зручно і не надто інформативно. В електронних та гібридних барометрах ця проблема вирішена побудовою графіка зміни тиску, і, здається, все добре, але є один нюанс - це їхня ціна. Ті, що я бачив у продажу, коштували від 5-6 тис. рублів, що на мій погляд необґрунтовано дорого. Ну і, звичайно, найголовніший аргумент на користь самостійного виготовлення - цей барометр буде зроблений власними руками, що безсумнівно буде гріти душу, заради чого ми, власне, тут всі і зібралися. Отже, поїхали!
Технічні характеристики:
- Вимірюване тиск: від 225 мм.рт.ст. до 825 мм.рт.ст. (Графік на екрані будується за замовчуванням від 730 до 760, можна змінити в скетчі)
- Буфер вимірювань: останні 24 години.
- Перемикаємий період відображення на екрані: 3 год, 6 год, 12 год, 24 год.
- Періодичність оновлення поточних даних: 11,25 хвилин.
- Збереження даних в пам'яті (запобігання втрати накопленого масиву у разі короткочасного відключення живлення пристрою) з можливістю скидання.
Для виготовлення нам знадобляться наступні компоненти:
- Екран LCD 2004 (з модулем I2C PCF8574)
- Плата Arduino Nano/Uno або щось подібне (ATmega 328, 168 буде замало)
- Датчик тиску BME280 (Можна BMP280)
- Кнопка тактова, 1 штука
- Провода, корпус, джерело живлення на 5 вольт (На смак, кому як зручніше, благо варіантів корпусів у продажу багато).
Схема підключення:
Коротко опишу словами. Я використовував текстовий дисплей 20*4 з припаяним перехідником на I2C (PCF8574). Перехідник дисплея та датчик BME280 підключаються до шини I2С, до тих же пінів відповідно (SDA - A4, SCL - A5). Програмно оброблювана кнопка підключена до піна 3 (D3) і до землі, вона відповідає за перемикання періоду часу вимірювань, що виводяться на екран. Друга кнопка вмикає підсвічування, за потреби, замикаючи безпосередньо її ланцюг.
Тепер трохи про логіку роботи програми. Сам код дуже детально прокоментований, тому розібратися при бажанні праці не складе, опишу загальні моменти.
Основна ідея полягає в наступному. На екрані після виведення текстової інформації у нас залишається 16 стовпців для відображення діаграми зміни тиску, від цієї цифри й будемо відштовхуватись. Мінімальний проміжок часу, що відображається на діаграмі, - це три години (спочатку хотів зробити годину, але так часто сенсу немає, тиск так швидко не змінюється). 3 години = 180 хвилин/16 стовпців, т.е. 1 стовпець при такому розширенні буде відповідати 11,25 хвилин або 675000 мілісекунд. Це буде базовий інтервал, саме через такі проміжки часу будемо отримувати показання з датчика. Кожні 11,25 хвилин ми знімаємо показання атмосферного тиску і записуємо їх у масив розміром 128 елементів (що відповідає рівно добі, т.е. максимальному інтервалу вимірювань).
Далі діємо наступним чином: якщо вибрано інтервал три години, то для побудови діаграми просто використовуємо 16 останніх значень. Якщо вибрано інтервал 6 годин, то з вихідного масиву беремо так само 16 значень, але вибираємо їх уже через одне (1,3,5 і т.д.), те ж саме для 12 годин - кожне четверте значення, і для 24 - кожне восьме відповідно. Для прикладу намагався відобразити це в таблиці в Excel:
Зміна тиску (дельта) розраховується для кожного вибраного інтервалу часу як різниця першого і останнього відображеного елемента і виводиться на екран зі знаком плюс або мінус відповідно.
Пробіжимося по самому коду:
#define MIN_VAL 730 //Мінімально значення, що відображається на графіку #define MAX_VAL 760 //Максимальне значення, що відображається на графіку
Тут можна задати межі відображення тиску на графіку. За моїми спостереженнями, в нашій місцевості тиск рідко опускається нижче 730 і підвищується вище 760, тому такий діапазон і був обраний. К тому ж, від верхнього до нижнього краю екрана - 32 рядки (8 точок в знаковому місці * 4 рядки), тому зміна тиску на 1 мм.рт.ст. вже буде видно на діаграмі.
Логіка роботи основного циклу програми не складна. Обробляємо натискання кнопки (воно обробляється в перериванні, але і в основному циклі теж має бути присутнім), яка циклічно перемикає інтервал відображення. Далі йдуть два таймера. Перший кожні 11,25 хвилин зсуває основний масив на один елемент, дописує в нього нове значення атмосферного тиску і зберігає масив у пам'яті. Другий таймер, згідно з установленим інтервалом відображення даних, оновлює інформацію на екрані, отримуючи дані з основного масиву.
Використовувані функції.
void initPlot()
Дисплей у пам'яті може зберігати до 8 користувацьких символів, ця функція якраз створює і записує в пам'ять дисплея символи, необхідні для малювання діаграми (стовпчика різної висоти від 1 до 8). У даному випадку використані всі вісім вільних осередків.
void get_data ()
Ця функція передає 16 вибраних значень з базового масиву у функцію малювання діаграми (drawPlot), розраховує дельту тиску за вибраний період і викликає функцію виведення текстової інформації на екран (screen_data).
void screen_data (int value, int delta, byte interval)
Функція приймає поточне значення атмосферного тиску, різницю тисків і період, що відображається на екрані, і виводить все це на дисплей.
void drawPlot(byte pos, byte row, byte width, byte height, int min_val, int max_val, int fill_val)
Функція малювання стовпцевої діаграми. Приймає кількість стовпців, позицію початку діаграми, висоту, ширину, мінімум і максимум і теперішнє значення. За більш детальним описом краще сходити на сайт автора (AlexGyver , посилання буде в кінці статті).
void update_all () void read_all ()
Функції запису (оновлення) і читання даних у/з пам'яті EEPROM. Не те щоб це було обов'язково для цього проекту, але, як я вже говорив, на випадок відключення живлення пристрою мені здалося корисним можливість зберегти накоплений за добу масив даних. Якщо відключення було тривалим, через що дані в пам'яті стали неактуальними, або просто хочеться почати відлік з нуля, є можливість обнулити інформацію. Для цього треба вимкнути пристрій, затиснути кнопку перемикання діапазону і подати живлення. Після цього масив у пам'яті буде обнулено, і на екрані з'явиться повідомлення про це: "Reset data OK".
При написанні прошивки були використані матеріали цієї статті і бібліотеки авторства AlexGyver, за що йому вкотре велика подяка!
На цьому, здається, все, наостанок кілька фотографій готового пристрою:
Запитання, зауваження і т.д. прошу в коментарі. Дякую за увагу!
Прикреплені файли:
- Barometr.zip (591 Кб)