Домашня метеостанція Ардуін вологість тиск. Метеостанція на Arduino з бездротовим датчиком температури

Як більшість працюючих людей, заняття власними проектамизабирає єдине, що залишилося вільний час. Тому вже давно не творив і «чухалися руки» щось зробити. Ця можливістьз'явилася хоч як дивно в університеті. За вікном вересень, 4 курс і курсовий по схемотехніці, що насувається. Нам сказали, що курсові можна буде робити у двох варіаціях: паперовому та «залізі».

Протягом 5 років паперовий курсовий у нашому університеті робився за принципом «візьми старі та збери їх докупи». Такий підхід мене не влаштовував своєю рутинністю, тому я одразу ж вибрав курсовий у «залізі». Як серце курсових був запропонований мікроконтролер Arduinoчерез свою легконавчаність. Після визначення з типом курсового залишалося ще одне питання: а що саме зробити. Так як досвіду в програмуванні мікроконтролерів не було, то відразу відкрив гугл і почав вивчати існуючі проекти. Проектів багато, деякі з них досить прості, деякі геніальні (3D сканер, наприклад), але переважна більшість не мала практичного застосування. А мені хотілося саме того, що не валялося б потім на полиці і не збирало там пилюку. Після півгодинного екскурсу у світ Arduino мене зацікавила тема домашніх метеостанцій, та й проекти здалися не дуже складними в реалізації (що в основному і підкупило новачка).

Ось так було обрано тему для курсового і згодом проблем начебто не намічалося.

Вибір компонентів

Переглядаючи різні проекти я розумів, що мені цілком достатньо буде Nano чи навіть Pro Mini, але все-таки вибрав Arduino Unoсподіваючись, що програмування для Arduino мені сподобається і надалі реалізую ще якісь проекти. Паяльник до цього в руках жодного разу не тримав, тому для легшої розробки вирішив також придбати Sensor Shield v4.

Детальніше

Плата сприяє швидкого підключеннядатчиків, модулів, серво моторів, інтерфейсів Serialі I2C, а також виводить усі порти контролера формфактора Duemilanova/Uno (також може бути підключена і в серію мега, але з обмеженнями та наслідками). Підтримує інші шилди поверх себе.


Як джерела для метеорологічних даних вибрав такі датчики:


Із датчиками визначився. Але що робити з даними, що надходять від датчиків. Вирішив виводити на екран. Картинку хотілося кольорову, тож монохромні рішення відкинув одразу. Після декількох хвилин пошуку було обрано TFT дисплей ST7735 розміром 1,8 дюйми.

Детальніше

Оскільки дисплей використовує 4-провідний SPI протокод для зв'язку і має власний пікселе-адресований буфер кадру, він може використовуватися з будь-якими видами мікроконтролерів. 1.8-дюймовий дисплей має 128x160 кольорових пікселів. Також є слот для картки пам'яті microSD, отже, можна легко завантажувати повнокольорові растрові зображенняіз FAT16 / FAT32 файлової системикартки microSD.

Характеристики:

  • Діагональ дисплея - 1.8 дюймів, роздільна здатність 128x160 пікселів, 18-бітовий колір (262 144 кольори)
  • Контролер із вбудованою піксельною адресацією буфера відеопам'яті
  • Вбудований слот для microSD - використовує понад 2 цифрові лінії.
  • Сумісний з 3.3 та 5V
  • Габарити: 34 мм х 56 мм х 6,5 м


Програмування контролера Arduino

Після того, як визначились із компонентами для метеостанції, почнемо програмування контролера. Для прошивки Arduinoвикористовувалося середовище розробки Arduino IDE. Також використав бібліотеки від Adafruit.

Перед тим, як перейти до скетчу, розглянемо функціонал:

  • Покази знімаються з датчиків кожні 10 секунд і оновлюються на екрані лише ті показники, які були змінені порівняно з минулим виміром
  • Реалізовано передачу даних по COM порту

Скетч

#include // library for communication with I2C devices #include // Core library for all sensors #include // library for BMP180 #include // Core graphics library #include // Hardware-specific library #include // library for communication with SPI devices #include "dht.h" // library for DHT #define DHT22_PIN 2 // connect data pin of DHT22 to 2 digital pin #define TFT_CS 10 // connect CS pin of TFT to 10 digital pin #define TFT_RST 9 // Connect RST pin of TFT до 9 цифровий pin // Ви можете також підключити це до Arduino reset // в якому випадку, налаштувати цей #define pin to 0! #define TFT_DC 8 // connect DC pin of TFT to 8 digital pin Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); //initialize TFT #define TFT_SCLK 13 // connect SCLK pin of TFT to 13 digital pin #define TFT_MOSI 11 // connect MOSI pin of TFT to 11 digital pin dht DHT; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); //Initialize BMP180 int bmpFlag = 0; struct (uint32_t total; uint32_t ok; uint32_t crc_error; uint32_t time_out; uint32_t connect; uint32_t ack_l; uint32_t ack_h; uint32_t unknown; )0 =, 0,0 // struct for dht status void setup(void) ( Serial.begin(9600); Serial.println("Meteo Test"); Serial.println(""); if(!bmp.begin()) // check connection для BMP180 ( Serial.print("Ooops, no BMP180 виявлено ... Опис вашого wiring або I2C ADDR!"); bmpFlag = 1; ) tft.initR(INITR_BLACKTAB); (ST7735_BLACK);tft.setRotation(tft.getRotation() + 1);tft.setTextSize(1.5);delay(500); , oldAltitude = 0, oldPressure = 0, oldDHTHumidity = 0, oldDHTTemperature; bool wasUpdate = false; void loop(void) ( if(Serial.available() > 0) // we have data is Serial port ( Serial.read(); // read byte from serial port and send last measured data printValue("Pressure", oldPressure , " hPa ", false); printValue("Temperature", oldTemperature, " C", false); false); printValue("DHT_temperature", oldDHTTemperature, "C", false); // get data from BMP180 if (event.pressure) ( bmp.getTemperature(&temperature); float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure, event.pressure). error"); ) ) uint32_t start = micros(); int chk = DHT.read22(DHT22_PIN);// get data from DHT22 uint32_t stop = micros(); (case DHTLIB_OK: stat.ok++; break; case DHTLIB_ERROR_CHECKSUM: stat.crc_error++; Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: stat.time_out++; Serial.print("Time out error,\t"); break; case DHTLIB_ERROR_CONNECT: stat.connect++; Serial.print("Connect error,\t"); break; case DHTLIB_ERROR_ACK_L: stat.ack_l++; Serial.print("Ack Low error,\t"); break; case DHTLIB_ERROR_ACK_H: stat.ack_h++; Serial.print("Ack High error,\t"); break; default: stat.unknown++; Serial.print("Unknown error,\t"); break; ) if(bmpFlag! = 0 | !event.pressure) // update data ( tft.fillRect(0, 30, 160, 6, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("ERROR BMP IN , "", true); ; printValue("Pressure", event.pressure, "hPa", true); oldPressure = event.pressure; wasUpdate = true; ), tft.setCursor(0, 38); tft.setTextColor(ST7735_WHITE); tft.fillRect(0, 46, 160, 7, ST7735_BLACK); tft.setCursor(0, 46); tft.setTextColor(ST7735_BLUE); wasUpdate = true; ) ) if(DHT.humidity != oldDHTHumidity) ( tft.fillRect(0, 54, 160, 7, ST7735_BLACK); tft.setCursor(0, 54); tft.setTextColor(ST7735_GREEN); printValue("Humidity", DHT.humidity, "%", true); oldDHTHumidity = DHT.humidity; wasUpdate = true; ) if(DHT.temperature != oldDHTTemperature) ( tft.fillRect(0, 80, 160, 7, ST7735_BLACK); tft.setCursor(0, 80); tft.setTextColor(STV7335_YELLOW); temperature, "C", true);oldDHTTemperature = DHT.temperature; wasUpdate = true; delay(10000); ) void printValue(char* title, double value, char* measure, bool tftPrint) ( if(tftPrint) // print data to TFT ( tft.print(title); tft.print(": "); tft.print( value);tft.println(measure); ) Serial.print(title); // send data to Serial port Serial.print(": ");

Саме час зібрати корпус

Головною умовою курсового було робочий прототип у презентабельному вигляді. Тому довелося купити корпус і, озброївшись напилком, у будь-який спосіб засунути метеостанцію в корпус.

У місцевому магазині радіоелектроніки було придбано корпус.

Корпус

(На фото корпус трохи не такий. У мене кришка прозора)



Потім, орудуючи напилком, були виконані отвори для виведення датчиків та подачі живлення. Датчики вирішив вивести назовні, тому що під час тестування системи без корпусу помітив, що задня частина екрану сильно нагрівається, що позначиться на температурі всередині корпусу.

Корпус з отворами для датчиків та живлення



Так як довелося припаювати ніжки до 2 датчиків і в одного з них я спалив доріжку, то вирішив не випробовувати долю і не припаювати проводи до датчиків (потренуюсь на чомусь іншому), а для того щоб з'єднання було більш-менш надійним, вирішив перемотати ізолентою.

Система перед "запиханням" у корпус



Так як корпус набагато більший за Arduino (менше не було), довелося вигадувати підпірку, щоб плата не їздила всередині корпусу. Також з паралону була вирізана фігура, а в ній прямокутник для екрану з метою приховати нутрощі корпусу. Суперклею під рукою не було, тож довелося садити на двосторонній скотч.

Чудо-юда риба-кит



Прикручуємо кришку, підключаємо живлення та чекаємо.

Закінчена метеостанція у корпусі



Після виведення результатів на екран виявляємо неприємну помилку вимірювання вологості: DHT22 старанно видає цифру 99,90% (вкрай рідко буває 1,00%). Починаємо розбиратися у чому проблема. Перше, що робимо - дивимося виведення значень COM порт. Начебто все нормально. Після нексольких перезаливок, розбирань і складання корпусу в голову спадає на думку пошукати відповідь у гугле. Як і очікувалося, російський гугл нічого ділового не сказав. Окей. Починаємо шукати англійською та на одному з форумів натикаємося на хлопців зі схожою проблемою. Перші чотири сторінки обговорення нічого ділового не дають, а на п'ятій сторінці знаходимо відповідь на наше запитання:
Humidity sensors може бути легко впливати на нескінченні гасів або дуже тривалий експрес до високої humidity IIRC. У термінах, які ви збираєтеся, є відповідь, як вибрати sensor, ви можете зробити це.

Залишалося питання тільки в тому, коли і як я встиг нашкодити DHT22. Але настав час здавати курсовий і тому я залишив вирішення цієї проблеми на потім.

Післямова

Курсовий був зданий. Метеостанцію відкладено на невизначений час до закриття всіх хвостів в університеті. Однак, до метеостанції довелося повернутися раніше, ніж я думав. Так склалося, що в середині листопада я змінив робоче місце і в новій команді я познайомився з людьми, які цікавляться платформою Arduino та подібними до них. Тому мій інтерес до цієї платформи не встигнувши охолонути, розгорівся знову. Я дістав свою метеостанцію, підключив до комп'ютера і згадав, що реалізував передачу даних з Arduino по COM порту. І тут мені спала на думку ідея, написати програму, що приймає дані через COM порт від Arduino і передавати ці дані на народний моніторинг
  • Arduino
  • Додати теги

    Метеостанція своїми руками.

    Справа була ввечері, робити нічого після нового року. Як завжди, під час зимових новорічних канікул хочеться зайняти голову та й руки теж чимось корисним, творчим. У ці новорічні канікули вирішив зробити метеостанцію своїми руками. Готуватись почав заздалегідь, всі компоненти закуповував та збирав перед новим роком, а основне програмування робив на канікулах.

    (Під катом багато фотографій!)

    Спочатку пробігу по компонентах, посилання давати не буду, тому що на eBay (у особистому кабінеті) товари пішли до архіву. Багато компонентів купував повільно на аукціоні eBay. Вперше випробував аукціон, який раніше завжди купував «buy it now». Що можу сказати, якщо не поспішати з покупками, деякі компоненти можна купити дешевше (різниця іноді буває в два рази).

    Датчик тиску ВМР085
    Це головний датчик. Коли я побачив його на eBay, зрозумів, що хочу зібрати саме домашню метеостанцію.
    Прилетів датчик у звичайному конверті, всередині обклеєному пухирцем.

    Усередині конверта була візитка продавця і датчик, запакований в антистатичний пакет і загорнутий ще один шар пухирці

    Антистатичний пакет був запаяний, щоб вода під час перельоту не загрожувала датчику

    Дістаємо датчик. З одного боку припаяна лінійка контактів, які були вставлені в пінопласт, щоби не погнулися. З іншого боку розташовується сам датчик та маркування контактів.




    Все б добре, але маркування контактів нанесене у дзеркальному вигляді.
    Підключається датчик по шині I2C і живиться від 3,3 В. Тобто для нормального функціонування потрібно 4 дроти (+, -, SDA, SCL)
    Опитувати датчик можна двома способами: або через бібліотеку, або використовуючи функції прямо скетче.
    Приклад програми:

    #include

    #define BMP085_ADDRESS 0x77 // I2C address of BMP085

    Const unsigned char OSS = 0; // Oversampling Setting

    // Calibration values
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;

    Short temperature;
    long pressure;

    Void setup()
    {
    Serial.begin(9600);
    Wire.begin();
    bmp085Calibration();
    }

    Void loop()
    {
    temperature = bmp085GetTemperature(bmp085ReadUT());
    pressure = bmp085GetPressure(bmp085ReadUP());
    Serial.print(«Temperature: „);
    Serial.print(temperature/10.0, DEC);
    Serial.println(“C”);
    Serial.print(«Pressure: „);
    Serial.print(pressure/133.322, DEC);
    Serial.println("mm Hg");
    Serial.println();
    delay(1000);
    }

    Void bmp085Calibration()
    {
    ac1 = bmp085ReadInt(0xAA);
    ac2 = bmp085ReadInt(0xAC);
    ac3 = bmp085ReadInt(0xAE);
    ac4 = bmp085ReadInt(0xB0);
    ac5 = bmp085ReadInt(0xB2);
    ac6 = bmp085ReadInt(0xB4);
    b1 = bmp085ReadInt(0xB6);
    b2 = bmp085ReadInt(0xB8);
    mb = bmp085ReadInt(0xBA);
    mc = bmp085ReadInt(0xBC);
    md = bmp085ReadInt(0xBE);
    }

    Short bmp085GetTemperature(unsigned int ut)
    {
    long x1, x2;
    x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
    x2 = ((long)mc<< 11)/(x1 + md);
    b5 = x1 + x2;

    Return ((b5 + 8)>>4);
    }

    Long bmp085GetPressure(unsigned long up)
    {
    long x1, x2, x3, b3, b6, p;
    unsigned long b4, b7;
    b6 = b5 – 4000;
    // Calculate B3
    x1 = (b2 * (b6 * b6)>>12)>>11;
    x2 = (ac2 * b6)>>11;
    x3 = x1 + x2;
    b3 = (((((long)ac1)*4 + x3)<>2;
    // Calculate B4
    x1 = (ac3 * b6)>>13;
    x2 = (b1 * ((b6 * b6)>>12))>>16;
    x3 = ((x1 + x2) + 2)>>2;
    b4 = (ac4 * (unsigned long) (x3 + 32768))>>15;
    b7 = ((unsigned long)(up - b3) * (50000>>OSS));
    if (b7< 0x80000000)
    p = (b7<<1)/b4;
    else
    p = (b7/b4)<<1;
    x1 = (p>>8) * (p>>8);
    x1 = (x1 * 3038)>>16;
    x2 = (-7357 * p)>>16;
    p + = (x1 + x2 + 3791)>>4;
    return p;
    }

    // Read 1 byte from the BMP085 at "address"
    char bmp085Read(unsigned char address)
    {
    unsigned char data;

    Wire.write(address);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 1);
    while(!Wire.available())
    ;
    return Wire.read();
    }

    Int bmp085ReadInt(unsigned char address)
    {
    unsigned char msb, lsb;
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(address);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 2);
    while(Wire.available()<2)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    return (int) msb<<8 | lsb;
    }

    // Read the uncompensated temperature value
    unsigned int bmp085ReadUT()
    {
    unsigned int ut;
    // Write 0x2E в Register 0xF4
    // Це запитання, а також temperature reading
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x2E);
    Wire.endTransmission();
    // Wait at least 4.5ms
    delay(5);
    // Read two bytes from registers 0xF6 and 0xF7
    ut = bmp085ReadInt(0xF6);
    return ut;
    }

    // Read the uncompensated pressure value
    unsigned long bmp085ReadUP()
    {
    unsigned char msb, lsb, xlsb;
    unsigned long up = 0;
    // Write 0x34 + (OSS<<6) into register 0xF4
    // Request a pressure reading w/ oversampling setting
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x34 + (OSS)<<6));
    Wire.endTransmission();
    // Wait for conversion, delay time dependent on OSS
    delay(2 + (3<// Read register 0xF6 (MSB), 0xF7 (LSB), і 0xF8 (XLSB)
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF6);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 3);
    // Wait for data to become available
    while(Wire.available()< 3)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    xlsb = Wire.read();
    up = (((unsigned long) msb<< 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
    return up;
    }


    Крім цього в датчику є власний термо-сенсор для компенсації тиску та альтиметр

    Arduino Nano v3.0
    Це серце усієї метеостанції. Просто кажучи, контролер у мініатюрному розмірі.
    Купував
    Розповідати докладно про контролера не буду, бо до мене це вже зробили:


    Посилка з lightake була збірна, контролер прийшов у пакеті, де був USB-кабель та Arduino у запаяному антистатичному пакеті.

    Щоб оцінити розміри, поруч із Arduino поклав монетку номіналом 1 руб.

    Плата контролера поблизу



    USB-кабель хороший, з феритовим кільцем. Харчується Arduino USB кабелем. Середовище розробки можна завантажити (сторінка для скачування). Мова «С»-подібна, з освоєнням проблем не було, тому що на ній дуже багато програмую на роботі.

    LCD екран
    На роботі у засіках знайшов сумісний LCD 1602 екран. З підключенням довелося повозитись, бо даташита на нього не знайшов. В результаті LCD запрацював.

    Але після недовгої експлуатації помітив, що мені цього екрану мало і вивести більше даних не вийде, тому що він має лише 2 рядки по 16 символів у кожному. Спочатку здається, що цих параметрів вистачить, але коли починаєш програмувати, то розумієш, що максимум можна впхнути 3-4 параметри. А якщо робити меню (адже я подумував зробити меню на цьому екрані), то вільного місця залишається на 1-2 параметри.
    У результаті почав шукати собі інший екран. Спочатку придивлявся до графічного екрану від Nokia 3310 і навіть в аукціоні eBay брав участь, щоб його купити, але не склалося (чому дуже радий), тому мені довелося відмовитися від цього екрану. Зараз я розумію, що він був би занадто малий для моїх цілей, оскільки є з чим порівнювати.
    Випадково переглядаючи шилди на Arduino, я натрапив на графічний екран 12864 на контролері ST7920. У цього екрану і розмір підходящий, і гарна роздільна здатність для моїх потреб (128х64). Тобто можна спокійно розмістити 6-7 рядків по 20 символів шрифту, що нормально читається. Оскільки екран графічний, то окрім тексту різними шрифтами можна розмістити і графіку. Коротше, це саме те, що мені потрібно було, все було в цьому екрані, тому я не витримав і замовив.
    Посилка прийшла швидко і була упакована стандартно: конверт-пухирка, всередині ще шар пухирці та екран в антистатичному пакеті:






    Щоб оцінити розміри, поруч із LCD поклав монетку номіналом 1 руб.




    Щоб швидко підключити екран Arduino, до контактів LCD припаяв лінійку контактів. Підключати LCD можна по послідовній шині та паралельній. Я вибрав перший варіант, тому що вільні контакти Arduino і так мало.
    Підключення (взято з мережі):

    - Контакт 1 (GND) підключається до загальної шини
    - Контакт 2 (VCC) підключається до шини живлення +5V, причому струм, що споживається, порівняно невеликий і дисплей можна живити від вбудованого стабілізатора Arduino.
    - Контакти 4, 5 та 6 підключаються до цифрових виходів Arduino, утворюючи послідовний інтерфейс SPI:
    контакт 4 – (RS) – відповідає лінії CS (наприклад 7)
    контакт 5 – (RW) – відповідає лінії MOSI (наприклад 8)
    контакт 6 – (E) – відповідає лінії SCK (наприклад 3)
    номери контактів Arduino можуть бути будь-якими, головне не забути потім правильно вказати їх у тексті програми під час ініціалізації дисплея.
    - Контакт 15 (PSB) з'єднується із загальною шиною.
    - Контакти 19 (A) та 20 (K) – це живлення підсвічування (+5V та GND відповідно). Для регулювання яскравості підсвічування можна використовувати змінний резистор 10кОм, увімкнений між шинами живлення та GND. Напруга з його двигуна подається на контакт 19 дисплея.
    За цією інструкцією я підключив все, окрім підсвічування. Як живлення підсвічування я використовував ШІМ Arduino.
    Для того щоб програмно підключити LCD до Arduino, використовується бібліотека u8glib. Завантажити можна. Якщо є проблеми скачування, можу бібліотеку залити на narod.ru.
    Сама бібліотека не складна і дозволяє виводити текст різним шрифтом, малювати лінію, малювати найпростіші геометричні фігури (прямокутник, коло), виводити свої зображення, підготовлені спеціальним чином. В принципі, цього інструменту достатньо більшості завдань.
    Ось результат простенької програми:

    Сама програма:

    #include «U8glib.h»

    U8GLIB_ST7920_128X64 u8g(3, 9, 8, U8G_PIN_NONE); // SPI E = 3, RW = 9, RS = 8

    // Підпрограма визначення вільної пам'яті
    int freeRam () (
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
    }

    Void setup(void) (
    u8g.setFont(u8g_font_6x10); // шрифт
    u8g.setRot180(); //Перевернув екран
    analogWrite(6, 115); // Встановлюємо яскравість екрана (анод підсвічування на 6 pin)
    }

    Void loop(void) (
    u8g.firstPage();
    do (

    u8g.setPrintPos(1, 12); // позиція
    u8g.print(«Hello!»); // Висновок тексту
    u8g.drawBox(0,22,128,9); // Зафарбовуємо прямокутник білим
    u8g.setColorIndex(0); // біле чорнило, чорний фон
    u8g.setPrintPos(1, 30); // позиція
    u8g.print(«Word...»); // Висновок тексту

    U8g.setColorIndex(1); // біле чорнило, чорний фон
    u8g.setPrintPos(1, 50); // позиція
    u8g.print("After start ="); // Висновок тексту
    u8g.setPrintPos(85, 50); // позиція
    u8g.print(millis() / 1000); // виведення число секунд після старту
    u8g.setPrintPos(1, 64); // позиція
    u8g.print(freeRam()); // Висновок скільки пам'яті зайнято
    ) while(u8g.nextPage());

    Delay (200);
    }

    Годинник реального часу DS1307
    Ще один компонент для моєї метеостанції. На даному шилді реалізований годинник реального часу. Замовляв їх на аукціоні eBay. Продавець надіслав хустку годинника в нереально великій коробці


    Усередині коробки було два листки А4 з рекламою та хустка годинника, обмотана целофаном


    Хочу зауважити, що плата вбирається у розміром 2 крб. монету, а коробка була розміром 13х15х5 см.
    Плата була упакована в антистатичний пакет

    Хустка поблизу



    З цим модулем мені довелося повозитися. По-перше, були проблеми підключення. А по-друге, кварц на цій платі ніякий. Якби знав, що на модуль витрачу стільки часу, то, швидше за все, зібрав би його сам, добре, що в мережі повно схем. Найпростіша схема містить 4-5 компонентів.
    Щодо підключення. Я знайшов бібліотеку, де було сказано, що інтерфейс I2C можна підключати не на звичні аналогові входи Arduino (А4 і А5), а на будь-які дискретні. Як написано, так і вчинив. Спочатку нічого не працювало, після довгого танцю з бубном годинник завевся. Ну, подумав, все проблеми закінчилися, але після того, як я спробував цей же модуль підключити до іншої Arduino, танці з бубном продовжилися. Багато часу витратив на пошуки вирішення цієї проблеми і практично скрізь вказувалося або на неправильне підключення, або відсутність підтягуючих резисторів на контактах SCL і SDA. Я вже хотів з паяльником у плату лізти, але на одному форумі випадково натрапив на код, де було сказано, щоб SCL та SDA підключати до стандартних портів I2C на Arduino. Після стандартного підключення все відразу запрацювало.
    Тепер із приводу кварцу. Не знаю, що там за кварц ставлять китайці, але годинник із таким кварцем тікав на добу на 10-11 сек. У місяць ця похибка становить 5 хвилин, а рік 1 годину. Нафіг такий годинник не потрібний. Довелося знову лізти в мережу та шукати, як виправити цей баг. Перше рішення, що потрапило, говорить про те, що потрібно заземлити кварц. Зробив – результат нульовий. Ще десь знайшов, що треба знайти стару материнку і випаяти звідти вартовий кварц. Зробив – результат є. Тепер годинник тікає не на 10-11 секунд, а на 1,5 секунди на добу. Скажімо, стало краще, але до ідеалу далеко. Так як більше з паяльником возиться небажання, то було вирішено підводити годинник програмно, тобто раз на добу підводити годинник на потрібну величину. Після 10 діб, годинник пішов не більше, ніж на секунду. Метод хороший, але тільки тоді, коли пристрій синхронізації Arduino підключений до живлення, інакше годинник працює від батарейки і все одно тікає.
    Невелика тестова програма:

    #include «Wire.h»
    #define DS1307_I2C_ADDRESS 0x68 // SDA A4, SCL A5

    Byte decToBcd(byte val)
    {
    return ((val/10*16) + (val%10));
    }

    Byte bcdToDec(byte val)
    {
    return ((val/16*10) + (val%16));
    }

    Void setDateDs1307(byte second, // 0-59
    byte minute, // 0-59
    byte hour) // 0-99
    {

    Wire.write(0);
    Wire.write(decToBcd(second));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.endTransmission();
    }

    Void getDateDs1307(byte *second,
    byte *minute,
    byte *hour)
    {

    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.endTransmission();

    Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

    *second = bcdToDec(Wire.read());
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read());
    }

    Void setup()
    {
    byte second, minute, hour;
    Wire.begin();
    Serial.begin(9600);

    Second = 45;
    minute = 5;
    hour = 16;

    SetDateDs1307(second, minute, hour);
    }

    Void loop()
    {
    byte second, minute, hour;

    GetDateDs1307(&second, &minute, &hour);
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.println(second, DEC);

    Delay (1000);
    }


    Тут не використана бібліотека, та й функції усічені, для читання та запису часу.

    Датчик температури та вологості DHT11
    Про цей датчик говорити нічого. Я б його навіть не став використовувати, якби не потрібна була вологість. На жаль, я його не сфотографував, коли отримав, тож фотографій не буде. Фотографії датчика можна буде переглянути нижче, де я його підключив до Arduino. Підключення датчика просте (+, цифровий вихід, -). Зазвичай датчики роблять чотири контактні. При такому форм-факторі третій контакт нічого не підключають.
    Для підключення до Arduino можна використовувати бібліотеку. Завантажити можна.
    Невелика тестова програма з виведенням інформації на LCD дисплей 1602:

    // include the library code:
    #include
    #include

    // Declare objects
    dht11 DHT11;
    LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

    #define DHT11PIN 7
    int i;

    Void setup()
    {
    lcd.begin(16, 2);
    lcd.print(«Status: „);
    i=0;
    }

    Void loop()
    {
    int chk = DHT11.read(DHT11PIN);
    lcd.setCursor(8, 0);
    switch (chk)
    {
    case 0: lcd.print(“OK“); break;// lcd.setCursor(11, 0); lcd.print(millis()/2000); break;
    case -1: lcd.print("Checksum error"); mErr(); break;
    case -2: lcd.print(«Time out error»); mErr(); break;
    default: lcd.print("Unknown error"); mErr(); break;
    }
    delay(500);
    lcd.setCursor(15, 0);
    switch (i)
    {
    case 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");break;
    case 1: lcd.print(«v»); lcd.setCursor(15, 1); lcd.print(" ");break;
    default: lcd.setCursor(15, 1); lcd.print(«E»); break;
    }
    i=i+1;
    if (i>1) i=0;
    lcd.setCursor(0, 1);
    lcd.print(«H=»);
    lcd.setCursor(2, 1);
    lcd.print((float)DHT11.humidity, 0);
    lcd.setCursor(4, 1);
    lcd.print("%");
    lcd.setCursor(8, 1);
    lcd.print(«T=»);
    lcd.setCursor(10, 1);
    lcd.print((float)DHT11.temperature, 0);
    lcd.setCursor(12, 1);
    lcd.print(«C»);

    Void mErr()
    {
    lcd.setCursor(2, 1);
    lcd.print("**");
    lcd.setCursor(10, 1);
    lcd.print("**");
    i=5;
    }


    Мінуси у датчика є - дані з датчика йдуть тільки в цілих числах, та й діапазон слабкий.

    Начебто, про всі компоненти написав. Залишилось зібрати все в єдине ціле.
    Упс, мало не забув! Для того щоб все зібрати пристрій, потрібен корпус. Корпус також замовляв на Ebay. Продавець виявився з Англії. Посилка дійшла швидко, але фотографувати її не став. Усі фотографії корпусу нижчі.

    Спершу зібрав усе на столі за допомогою спеціальних проводків. Написав тестову програму та залив її в контролер.



    Насправді синій колір підсвічування набагато яскравіший. Навіть за мінімальної яскравості (Bright=5) відбувається засвітлення кадру.

    Щоб усе зібрати без проводів, було вирішено зробити міні материнську плату, а хустки Arduino та шилди вдягалися на роз'єми. У разі чого їх з легкістю можна швидко витягти. LCD екран і кнопки для керування я вирішив також чіпляти на роз'ємах, тільки датчик температури впаяти на дротах.
    Ось така вийшла хустка



    На останній фотографії я ще до кінця флюсу не змив. Під шилди поруч із роз'ємами приклеїв пористу гуму, щоб була хоч якась опора. Хоча насправді шилди у роз'ємах на контактах і так чудово тримаються.

    Материнська плата із встановленими шилдами та платою Arduino.

    Ось так виглядає повне підключення до материнської плати


    Замість кнопок використовував саморобний шилд, спаяний на макетній платі. Як кнопки використовував кнопки зі старих мишок.
    Як видно, кількість дротів зменшилася.

    Основна проблема розміщення в корпусі - це рівно випиляти паз під LCD екран. Як я не намагався, все одно ідеально не вийшло. Щілини в деяких місцях були трохи більше 1 мм. Щоб все виглядало акуратно, я взяв чорний герметик для акваріума і залив усі щілини, заразом екран кріпив саме на цей герметик. Після висихання герметика зовні обрізав надлишки. При яскравому освітленні герметик видно, а при звичайному – все зливається з корпусом.
    Ось так виглядає корпус зсередини із встановленим LCD екраном та материнською платою.

    Ось так виглядає зовні при яскравому освітленні (перепрошую за відбитки пальців, побачив їх, коли розбирав фотографії).

    Довго думав, як приладнати кнопки в корпус і, найголовніше, які використовувати кнопки.
    У радіоелектронних магазинах сподобалися кнопка з довгим шпиньком і наконечники, які одягаються на цей шпиньок. Ці кнопки використовуються для паяння на плату. Все було б добре, але у них є мінус – хід натискання дуже маленький і гучний.
    Розміщувати кнопки довелося у два етапи: перший – розмістити кнопки на платі, другий – цю плату кріпити ще на одній платі. І все це потім засовувати у корпус на напрямні.

    Ось так виглядає хустка з кнопками:



    Ось так виглядає плата-утримувач:


    Тут видно напрямні, до яких вставляється плата з кнопками. Деякі елементи паяв для того, щоб надати жорсткості плати.

    Тепер все засовуємо в корпус
    Без підключення кнопок:


    З підключенням кнопок:

    Закриваємо корпус і вмикаємо. Все чудово працює, кнопки відпрацьовують, як треба.

    Наприкінці розміщую невелике відео роботи пристрою у різних режимах:
    http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be
    У кого відео тут не відображається, ось посилання на

    Настав час закінчувати огляд.
    Небагато напишу про програму, а потім короткі висновки. Коли писав програму, не думав, що дуже швидко упрусь в обмеження 30720 байт.


    Довелося оптимізувати код. Багато шматків коду виносив у підпрограми. Ніколи не подумав би, що оператор switch… case у компільованому вигляді займає більше місця, ніж кілька if… else. Ще заощаджує місце правильне оголошення змінних. Якщо оголошувати масив long, хоча можна обійтися byte, то перевитрата пам'яті досягає 500 байт залежно від розмірності масиву. Коли пишеш програму, про це не думаєш, а вже потім, коли аналізуєш програму, то розумієш, що деякі речі зробив неправильно, і починаєш оптимізувати код. Після того, як проблеми з розміром програми було вирішено, я вперся в обмеження оперативної пам'яті. Це виражалося в тому, що програма починала виснути після завантаження. Довелося вводити підпрограму підрахунку вільної оперативної пам'яті. У результаті був змушений відмовитися від одного алгоритму прогнозування погоди, оскільки він повинен виводити піктограми на екран. Сам алгоритм працює, а ось виведення піктограм довелося зареміювати. У мене є ще задуми, як оптимізувати код, але в найближчому майбутньому залишаю працювати пристрій, щоб оцінити працездатність і виявити всі баги.

    Тепер невеликі висновки
    Мінуси
    1) Ціна. Виправдання цього мінусу – хобі ніколи не буває дешевим.

    Плюси
    1) Великий функціонал устрою
    2) Нарощування функцій обмежується лише використовуваним контролером та власним бажанням
    3) Естетичне задоволення від споглядання та моральне задоволення від того, що я таки зібрав і доробив цей пристрій

    Планую купити +85 Додати в обране Огляд сподобався +137 +304

    Нещодавно мій колега влаштовував невелику виставку.
    Мій учитель попросив мене представити якийсь проект з електроніки студентам у коледжі. У мене було два дні, щоб придумати щось цікаве та досить просте.



    Так як погодні умови тут досить мінливі, а температура коливається в діапазоні 30-40 ° С, вирішив зробити домашню метеостанцію.

    У чому полягає функція погодної станції для будинку?
    Метеостанція на Ардуїно з дисплеєм – пристрій, що збирає дані про погоду та умови навколишнього середовища за допомогою безлічі датчиків.

    Зазвичай це такі датчики:

    • вітру
    • вологості
    • дощу
    • температури
    • тиску
    • висоти

    Моя мета – зробити портативну настільну метеостанцію своїми руками.

    Вона має вміти визначати такі параметри:

    • температуру
    • вологість
    • тиск
    • висоту

    Крок 1: Купуємо необхідні компоненти







    • DHT22, датчик температури та вологості.
    • BMP180, датчик тиску.
    • Припій
    • Однорядний роз'єм на 40 виходів

    З обладнання вам знадобляться:

    • Паяльник
    • Плоскогубці для носоупорів
    • Провід

    Крок 2: Датчик температури та вологості DHT22







    Для вимірювання температури використовуються різні датчики. Популярністю користуються DHT22, DHT11, SHT1x

    Я поясню, чим вони відрізняються один від одного і чому я використовував саме DHT22.

    Датчик AM2302 використовує цифровий сигнал. Цей датчик працює на унікальній системі кодування та сенсорної технології, тому його дані надійні. Його сенсорний елемент з'єднаний із 8-бітним однокристальним комп'ютером.

    Кожен сенсор цієї моделі термокомпенсований і точно калібрований, коефіцієнт калібрування знаходиться в одноразово програмованої пам'яті (ОТР-пам'ять). Під час читання показань сенсор викликатиме коефіцієнт з пам'яті.

    Маленький розмір, низьке споживання енергії, велика відстань передачі (100 м) дозволяють AM2302 підходити майже до всіх додатків, а 4 виходи в один ряд роблять монтаж дуже простим.

    Давайте розглянемо плюси та мінуси трьох моделей датчиків.

    DHT11

    Плюси: не вимагає паяння, найдешевший із трьох моделей, швидкий стабільний сигнал, дальність понад 20 м, сильна інтерференція.
    Мінуси: Бібліотека! Немає варіантів роздільної здатності, похибка вимірювань температури +/- 2°С, похибка вимірювання рівня відносної вологості +/- 5%, неадекватний діапазон вимірюваних температур (0-50°С).
    Області застосування: садівництво, сільське господарство.

    DHT22

    Плюси: не вимагає паяння, невисока вартість, згладжені криві, малі похибки вимірів, великий діапазон вимірів, дальність більше 20 м, сильна інтерференція.
    Мінуси: чутливість могла бути вищою, повільне відстеження температурних змін, потрібна бібліотека.
    Області застосування: вивчення довкілля.

    SHT1x

    Плюси: не вимагає паяння, згладжені криві, малі похибки вимірювань, швидке спрацьовування, низьке споживання енергії, автоматичний режим сну, висока стабільність та узгодженість даних.
    Мінуси: два цифрові інтерфейси, похибка у вимірі рівня вологості, діапазон вимірюваних температур 0-50°С, потрібна бібліотека.
    Області застосування: експлуатація в суворих умовах та довгострокових установках. Усі три датчики відносно недорогі.

    З'єднання

    • Vcc - 5В або 3,3В
    • Gnd – з Gnd
    • Data – на другий висновок Arduino

    Крок 3: Датчик тиску BMP180



    BMP180 – барометричний датчик атмосферного тиску із I2C-інтерфейсом.
    Барометричні датчики атмосферного тиску вимірюють абсолютне значення навколишнього повітря. Цей показник залежить від конкретних погодних умов та від висоти над рівнем моря.

    У модуля BMP180 був 3,3В стабілізатор на 662кОм, який я, за своєю дурістю, випадково підірвав. Довелося робити обведення живлення безпосередньо до чіпа.

    Через відсутність стабілізатора, я обмежений у виборі джерела живлення – напруга вище 3,3В зруйнує датчик.
    В інших моделей може бути стабілізатора, обов'язково перевіряйте його наявність.

    Схема з'єднання датчика та шини I2C з Arduino (nano або uno)

    • SDA - A4
    • SCL - A5
    • VCC - 3.3V
    • GND – GND

    Давайте трохи поговоримо про тиск і його зв'язок з температурою і висотою.

    Атмосферний тиск у будь-якій точці непостійний. Складна взаємодія між обертанням Землі, нахилом Земної осі, призводить до появи багатьох областей високого та низького тиску, що, у свою чергу, призводить до щоденної зміни погодних умов. Спостерігаючи за зміною тиску, можна зробити короткостроковий прогноз погоди.

    Наприклад, зниження тиску зазвичай означає дощову погоду або наближення грози (наближення області низького тиску, циклону). Піднімається тиск зазвичай означає суху ясну погоду (над вами проходить область високого тиску, антициклон).

    Атмосферний тиск змінюється з висотою. Абсолютний тиск у базовому таборі на Евересті (5400 м над рівнем моря) нижчий, ніж абсолютний тиск у Делі (216 м над рівнем моря).

    Так як показники абсолютного тиску змінюються в кожній локації, ми звертатимемося до відносного тиску, або тиску на рівні моря.

    Вимір висоти

    Середній тиск на рівні моря 1013,25 гПа (або мілібар). Якщо піднятися над атмосферою, це значення впаде нанівець. Крива цього падіння цілком зрозуміла, тому ви можете самі вирахувати висоту над рівнем моря, використовуючи наступне рівняння: alti = 44330 *

    Якщо ви приймете тиск на рівні моря 1013,25 ГПа як р0, розв'язуванням рівняння буде ваша поточна висота над рівнем моря.

    Запобіжні заходи

    Не забувайте, що датчику BMP180 потрібен доступ до навколишньої атмосфери, щоб мати змогу зчитувати тиск повітря, не поміщайте датчик у закритий корпус. Невеликого вентиляційного отвору буде цілком достатньо. Але й надто відкритим його не залишайте – вітер збиватиме показання тиску та висоти. Продумайте захист від вітру.

    Захистіть від нагрівання. Для вимірювання тиску потрібні точні температурні показання. Спробуйте захистити датчик від перепадів температури та не залишайте його поблизу джерел високої температури.

    Захистіть від вологи. Датчик BMP180 чутливий до рівня вологості, постарайтеся запобігти можливому попаданню води на датчик.

    Не засліплюйте датчик. Несподіванкою стала чутливість силікону в датчику до світла, який може потрапити на нього через отвір кришки чіпа. Для максимально точних вимірів постарайтеся захистити датчик від навколишнього світла.

    Крок 4: Збираємо прилад







    Встановлюємо однорядні роз'єми для Arduino Nano. Взагалі, ми обрізали їх до потрібного розміру і трохи зашкурили, тому вони виглядають, наче такими і були. Потім припаюємо їх. Після цього встановлюємо однорядні роз'єми для датчика DHT22.

    Встановлюємо 10ком резистор від виведення даних до землі (Gnd). Усі паяємо.
    Потім точно також встановлюємо однорядний роз'єм для датчика BMP180, робимо живлення 3,3В. З'єднуємо все із шиною I2C.

    В останню чергу підключаємо LCD-дисплей на ту ж I2C шину, що і датчик BMP180.
    (У четвертий роз'єм я планую пізніше підключити RTC-модуль (годинник реального часу), щоб прилад ще й час показував).

    Крок 5: Кодування




    Завантажте бібліотеки

    Щоб встановити бібліотеки на Arduino, перейдіть за посиланням

    #include
    #include #include #include "DHT.h" #include

    SFE_BMP180 pressure;

    #define ALTITUDE 20.56 #define I2C_ADDR 0x27 //<<- Add your address here. #define Rs_pin 0 #define Rw_pin 1 #define En_pin 2 #define BACKLIGHT_PIN 3 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7

    #define DHTPIN 2 // what digital pin we"re connected to

    // Uncomment whatever type you"re using! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal_I2Cpin, lcd Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);float t1,t2;

    void setup() ( Serial.begin(9600); lcd.begin (16,2); //<<-- our LCD is a 20x4, change for your LCD if needed // LCD Backlight ON lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); lcd.home (); // go home on LCD lcd.print("Weather Station"); delay(5000); dht.begin(); pressure.begin(); } void loop() { char status; double T,P,p0,a; status = pressure.startTemperature(); if (status != 0) { delay(status);

    status = pressure.getTemperature(T); if (status != 0) ( Serial.print("1"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Baro Temperature: "); lcd.setCursor(0,1) ); lcd.print(T,2); lcd.print("deg C "); t1=T; delay(3000);

    status = pressure.startPressure(3); if (status! = 0) (// Wait for measurement to complete: delay (status);

    status = pressure.getPressure(P,T); if (status != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("abslt pressure: "); lcd.setCursor(0,1); lcd.print(P,2) );lcd.print("mb");delay(3000);

    p0 = pressure.sealevel(P,ALTITUDE); // we"re at 1655 meters (Boulder, CO)

    a = pressure.altitude (P, p0); lcd.clear(); lcd.setCursor(0,0); lcd.print("Altitude: "); lcd.setCursor(0,1); lcd.print(a,0); lcd.print("meters"); delay(3000); ) ) ) ) float h = dht.readHumidity(); // Read temperature як Celsius (the default) float t = dht.readTemperature(); t2=t; lcd.clear(); lcd.setCursor (0,0); // go to start of 2nd line lcd.print("Humidity: "); lcd.setCursor(0,1);lcd.print(h); lcd.print("%"); delay(3000); lcd.clear(); lcd.setCursor (0,0); // go to start of 2nd line lcd.print("DHT Tempurature: "); lcd.setCursor(0,1); lcd.print(t); lcd.print("deg C"); delay(3000); lcd.clear(); lcd.setCursor (0,0); // go to start of 2nd line lcd.print("Mean Tempurature: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print("deg C"); delay(3000); )

    Я використав версію Arduino 1.6.5, код точно до неї підходить, до пізніших так само може підійти. Якщо код не підходить, використовуйте версію 1.6.5 як базову.

    За основу взято проект метеостанції з книги В. Петіна "Проекти з використанням контролера Arduino" 2-е видання (проект 5 додатка 2). Використовувалося середовище Arduino IDE 1.8.5 у Windows 10.
    При запуску скетчу видавалась помилка

    В інтернеті можна завантажити бібліотеки для Arduino, які мають однакові назви, але різний вміст. Скетч може не працювати, якщо ви використовуєте "не ту бібліотеку". Мабуть, мені потрапили не ті бібліотеки. У проект додав датчик BMP180 для вимірювання атмосферного тиску та переробив скетч.

    Схема з'єднань

    Сканування адрес

    Спочатку підключіть до датчика Arduino BMP180 та індикатор LCD1602. Скомпілюйте скетч I2C scanner і запустіть його, щоб визначити адреси пристроїв на шині I2C.

    Кожні 5 секунд програма сканує пристрої та видає адреси на COM порт. У мене знайдено два пристрої з адресами 0x3F та 0x77. BMP180 за замовчуванням має адресу 0x77, отже LCD індикатор має адресу 0x3F.
    У деяких схемах книги переплутані місцями підключення сигналів SDA та SCL до плати Arduino. Має бути: SDA - до A4, SCL - до A5. Якщо у модуля BMP180 п'ять висновків, то висновок VIN подається +5 Вольт .

    Монтажна схема

    Тепер зберіть схему повністю. Я використовував RGB світлодіод із загальним катодом, змонтований на платі разом із резисторами 150 Ом. Загальний катод підключається до контакту GND, решта висновків – за схемою. Вносити зміни до скетчу не потрібно, оскільки яскравість світлодіодів змінюється за циклічним законом.
    На схемі показано підключення RGB світлодіода із загальним анодом, як у книзі .
    Якщо на екрані LCD1602 не видно символів, покрутіть регулятор яскравості. Підсвічування індикатора споживає великий струм, тому використовуйте блок живлення на струм не менше 2 А. Я використовував USB хаб із зовнішнім блоком живлення на 2 А.
    У схемі використав п'єзодзвінок ЗП-22. Резистор, підключений до дзвінка, на 100 Ом. Частоту звуку можна змінити у програмі. Вибрав частоту 1000 Гц. Якщо вам попався зумер з фіксованою частотою звуку, то вмикати та вимикати його можна просто подачею та зняттям напруги, як звичайний світлодіод. Під час запуску скетчу подається короткий звуковий сигнал. Можна включити періодичну подачу сигналів під час роботи програми, коментуючи рядок //bzz(100); у скетчі.
    У проекті використав датчик DHT11 у вигляді модуля з уже змонтованим резистором 4.7 кОм. Опір може бути від 4.7 до 10 ком.
    Підключіть контакт Vcc модуля годинника DS1302 до шини +5 Вольт. Таким чином, ви зменшите розряд батареї, по суті вона буде працювати тільки тоді, коли відключиться живлення Arduino.

    Програма (скетч)

    Для обслуговування BMP180 використано бібліотеку bmp085. Значення тиску залежить від висоти місцевості. Для коректного значення атмосферного тиску треба вибрати висоту. Для цього редагуйте рядок dps.init(MODE_STANDARD, 10000, true); У мене висота дорівнює 100 м (10 000 см). Фрагмент розрахунку тиску взято з прикладу бібліотеки BMP085_test2.ino bmp085.

    Скетч meteo_P

    #include
    #include
    #include
    #include "DHT.h"
    #include
    BMP085 dps = BMP085();
    long Pressure = 0, Altitude = 0;
    unsigned long time1 = 0;

    #define DHTPIN 10
    #define DHTTYPE 11 // 11 - DHT11, 22 - DHT22
    DHT dht(DHTPIN, DHTTYPE);

    int kCePin = 4; // RST DS1302
    int kIoPin = 3; // Data DS1302
    int kSclkPin = 2; // CLK DS1302
    DS1302 rtc(kCePin, kIoPin, kSclkPin);

    int REDpin = 9;
    int GREENpin = 6;
    int BLUEpin = 11;

    LiquidCrystal_I2C lcd(0x3f, 16, 2); // вкажіть свою адресу 0x20...0xff address
    unsigned long memTime;
    int bzzPin = 8;

    void HumTempRead() (
    float hum = dht.readHumidity();
    float temp = dht.readTemperature();
    if (isnan(hum) || isnan(temp)) (
    Serial.println("Failed to read from DHT sensor!");
    lcd.setCursor(0, 1);
    lcd.print("H=--% T=---");
    lcd.setCursor(11, 1);
    lcd.print((char)223);
    lcd.setCursor(12, 1);
    lcd.print("C");
    ) else (
    lcd.setCursor(0, 1);
    lcd.print("H=");
    lcd.setCursor(2, 1);
    lcd.print(hum);
    lcd.setCursor(4, 1);
    lcd.print("% T=+");
    lcd.setCursor(9, 1);
    lcd.print(temp);
    lcd.setCursor(11, 1);
    lcd.print((char)223);
    lcd.setCursor(12, 1);
    lcd.print("C");
    }
    }

    void setup_bzz() (
    pinMode (bzzPin, OUTPUT);
    }

    void bzz (int _bzzTime) (
    tone (bzzPin, 1000, _bzzTime); //Частота 1000 Гц
    }

    void setup() (
    Serial.begin(9600);
    Wire.begin();
    delay(1000);

    dps.init(MODE_STANDARD, 10000, true); // 100 meters (висота над рівнем моря в см)

    dht.begin();
    setup_bzz();
    bzz(100);

    Lcd.init();
    lcd.backlight();
    lcd.home();
    // lcd.setCursor(0, 0);

    rtc.halt(false);
    rtc.writeProtect(false);

    //rtc.setDOW(FRIDAY); // Set Day-of-Week to FRIDAY встановіть день тижня
    //rtc.setTime(4, 58, 0); // Set the time to 12:00:00 (24hr format) встановіть час
    //rtc.setDate(6, 8, 2010); // Set the date to August 6th, 2010 встановіть дату (число, місяць, рік)
    }

    lcd.setCursor(8, 0);
    lcd.print(rtc.getTimeStr());

    if ((millis() - memTime > 2000) or (millis()< memTime)) { // DHT11/22 1 time each 2 seconds
    HumTempRead();
    memTime = millis();
    }
    delay(100);

    if (((millis() - time1) / 1000.0) >= 1.0) (
    dps.calcTrueTemperature();
    time1 = millis();
    }
    dps.getPressure(&Pressure);
    Serial.print("Pressure(Pa):");
    Serial.println(Pressure);

    long p2;
    int pi;
    p2 = (Pressure/133.3224); // Па мм рт.ст.
    pi = trunc (p2); // відкидання дробової частини числа

    lcd.setCursor(0, 0);
    lcd.print("P=");
    lcd.setCursor(2, 0);
    lcd.print(pi); // Висновок атм. тиск. на LCD
    lcd.setCursor(5, 0);
    lcd.print("mm");
    // Delay (3000);
    // bzz (100); // Розкоментуйте, якщо хочете слухати сигнали
    {
    for (int value = 0; value<= 255; value += 1) {
    analogWrite(REDpin, value);
    analogWrite(GREENpin, 255 - value);
    analogWrite(BLUEpin, 255);
    delay(5);
    }

    for (int value = 0; value<= 255; value += 1) {
    analogWrite(REDpin, 255);
    analogWrite(GREENpin, value);
    analogWrite(BLUEpin, 255 - value);
    delay(5);
    }

    for (int value = 0; value<= 255; value += 1) {
    analogWrite(REDpin, 255 - value);
    analogWrite(GREENpin, 255);
    analogWrite(BLUEpin, value);
    delay(5);
    }
    }
    }

    У каталозі файлів ви можете завантажити скетч та бібліотеки, які використовувалися у проекті.

    Імпортуйте в середу Arduino IDE бібліотеки LiquidCrystal_I2C.zip, bmp085.zip, DS1302.zip та DHT.zip зі скачаного архіву. У меню пройдіть Скетч Підключити бібліотеку Додати.ZIP бібліотеку...та у вікні виберіть zip-архів бібліотеки.
    Завантажте скетч meteo_P. Замініть у скетчі адресу LCD1602 на значення, отримане під час сканування шини I2C. Скомпілюйте та запустіть скетч.
    Якщо скетч запрацював, відкрийте монітор порту і перегляньте повідомлення. Підберіть висоту оператора dps.init(MODE_STANDARD, 10000 , true); отримати реальні значення тиску.
    Налаштуйте годинник. Розкоментуйте рядок //rtc.setTime(4, 58, 0); і в дужках вкажіть поточний час (годину, хвилини та секунди через кому) і перезавантажте скетч у контролер. Після встановлення часу знову закоментуйте цей рядок і знову перезапустіть скетч.
    Якщо вас дратує ілюмінація нічника, ви можете її налаштувати, змінивши тривалість затримки в циклах for наприкінці скетча. При delay(2); цикл триває 2-3 секунди при delay(5); - Від 4 до 5 секунд, при delay (30); - До 15-16 секунд. З таким же інтервалом оновлюватиметься інформація на індикаторі.
    За автономного використання метеостанції, тобто. без підключення до USB порту комп'ютера, закоментуйте у скетчі рядки зі словами Serial ..., щоб вимкнути виведення інформації в монітор COM порту.

    PS. У скетчі книги та в прикладах до бібліотеки DHT зазначений рядок визначення #define DHTTYPE DHT 11. Скетч запускається, але вилітає за кілька годин. Годинник зупиняється, індикація не змінюється. У моніторі порту з'являється невиразне повідомлення, в якому є посилання на dht.
    У цьому рядку прибрав літери DHT, тобто. зробив #define DHTTYPE 11. Після цього скетч почав працювати стабільно.

    Статтю оновлено 25.06.2018 р.

    Використані ресурси
    1. Петін В.А. Проекти з використанням контролера Arduino (Електроніка) 2-е видання, Спб. БХВ-Петербург, 2015 464 с.
    2. Петін В. А., Біняковський А. А. Практична енциклопедія Arduino. – М., ДМК Прес, 2017. – 152 с.
    3. http://arduinolearning.com/code/i2c-scanner.php
    4. http://arduino.ru/forum/programmirovanie/ds1302lcd1602
    5. http://роботехніка18.рф/як-підключити-lcd-1602-к-arduino-по-i2c/
    6. приклад BMP085_test2.ino із бібліотеки bmp085.zip
    7. http://proginfo.ru/round/
    8. http://homes-smart.ru/index.php?id=14&Itemid=149&option=com_content&view=article
    9. http://iarduino.ru/lib/datasheet%20bmp180.pdf
    10. http://it-donnet.ru/hd44780_dht11_arduino/