Създаване на метеорологична станция на arduino с локален сървър. Безжична метеорологична станция

Направи си сам метеорологична станция.

Беше вечер, нямаше какво да се прави след нова година. Както обикновено, през зимните новогодишни празници искам да заема главата и ръцете си с нещо полезно и креативно. По време на тези новогодишни празници реших да направя метеорологична станция със собствените си ръце. Започнах да се подготвям предварително, купих и сглобих всички компоненти преди Нова година и направих основното програмиране през празниците.

(Много снимки под изрезката!)

Първо, ще прегледам компонентите, няма да давам връзки, тъй като стоките в eBay (в моя акаунт) са отишли ​​в архива. Купих много компоненти спокойно от eBay. Опитах търга за първи път, винаги купувах „купете го сега“. Какво мога да кажа, ако не бързате да купувате, тогава някои компоненти могат да бъдат закупени по-евтино (понякога разликата е два пъти).

Сензор за налягане BMP085
Това е основният сензор. Когато го видях в eBay, разбрах, че искам да построя домашна метеорологична станция.
Сензорът пристигна в обикновен плик, облепен с малко мехурче отвътре.

Вътре в плика имаше визитната картичка на продавача и сензорът, опаковани в антистатична торбичка и увити в друг слой балонче

Антистатичната торба беше запечатана, така че влагата по време на полета да не застрашава сензора

Получаваме сензора. От едната страна беше запоена линия от контакти, които бяха вкарани в дунапрена, за да не се огъват. От другата страна е самият датчик и маркировката на контактите.




Всичко би било наред, но маркировката на контактите се прилага в огледален образ.
Сензорът е свързан чрез I2C шина и се захранва от 3,3 V. Тоест за нормална работа са необходими 4 проводника (+, -, SDA, SCL)
Можете да разпитате сензора по 2 начина: или чрез библиотеката, или като използвате функциите директно в скицата.
Пример за програма:

#включи

#define BMP085_ADDRESS 0x77 // I2C адрес на BMP085

Const unsigned char OSS = 0; // Настройка за свръхсемплиране

// Стойности на калибриране
int ac1;
intac2;
intac3;
неподписан int ac4;
неподписан int ac5;
неподписан int ac6;
int b1;
intb2;
intmb;
int mc;
intmd;

ниска температура;
дълъг натиск;

Празни настройки ()
{
Serial.begin(9600);
Wire.begin();
bmp085Калибриране();
}

Void loop()
{
температура = bmp085GetTemperature(bmp085ReadUT());
налягане = bmp085GetPressure(bmp085ReadUP());
Serial.print("Температура: ");
Serial.print(temperature/10.0, DEC);
Serial.println("C");
Serial.print("Налягане: ");
Serial.print(pressure/133.322, DEC);
Serial.println("mm Hg");
Сериен println();
забавяне (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);
}

Кратко bmp085GetTemperature(unsigned int ut)
{
дълъг x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((дълъг)mc<< 11)/(x1 + md);
b5 = x1 + x2;

Връщане ((b5 + 8)>>4);
}

Дълъг bmp085GetPressure (неподписан дълго)
{
дълго x1, x2, x3, b3, b6, p;
без знак дълго b4, b7;
b6 = b5 - 4000;
// Изчислете B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<>2;
// Изчислете B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (беззнаков дълъг)(x3 + 32768))>>15;
b7 = ((неподписан дълъг)(нагоре - b3) * (50000>>OSS));
ако (b7< 0x80000000)
p = (b7<<1)/b4;
друго
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
връщане p;
}

// Прочетете 1 байт от BMP085 на "адрес"
char bmp085Read (неподписан char адрес)
{
неподписани char данни;

wire.write(адрес);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
докато (! Wire.available ())
;
връщане Wire.read();
}

Int bmp085ReadInt (неподписан char адрес)
{
неподписан символ msb, lsb;
Wire.beginTransmission(BMP085_ADDRESS);
wire.write(адрес);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
докато (Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
връщане (int) msb<<8 | lsb;
}

// Прочетете некомпенсираната стойност на температурата
unsigned int bmp085ReadUT()
{
unsigned int ut;
// Запишете 0x2E в регистър 0xF4
// Това изисква отчитане на температурата
Wire.beginTransmission(BMP085_ADDRESS);
wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
// Изчакайте поне 4,5 ms
забавяне (5);
// Прочетете два байта от регистри 0xF6 и 0xF7
ut = bmp085ReadInt(0xF6);
връщане ут;
}

// Прочетете стойността на некомпенсираното налягане
неподписан дълъг bmp085ReadUP()
{
неподписан символ msb, lsb, xlsb;
unsigned long up = 0;
// Напишете 0x34+(OSS<<6) into register 0xF4
// Поискайте отчитане на налягането с настройка за свръхсемплиране
Wire.beginTransmission(BMP085_ADDRESS);
wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
// Изчакайте преобразуването, времето на забавяне зависи от OSS
забавяне (2 + (3<// Четене на регистър 0xF6 (MSB), 0xF7 (LSB) и 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);
// Изчакайте данните да станат налични
докато (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);
връщане нагоре;
}


Освен това сензорът има собствен термичен сензор за компенсация на налягането и висотомер.

Arduino Nano v3.0
Това е сърцето на цялата метеорологична станция. С прости думи, контролерът е в миниатюрен размер.
Купени
Няма да говоря подробно за контролера, тъй като това вече е направено преди мен:


Опаковката с lightake беше сглобяема, контролерът дойде в опаковка с USB кабел и Arduino в запечатана антистатична торбичка.

За да оцените размера, до Arduino поставете монета с номинална стойност 1 рубла.

Контролна платка отблизо



USB кабелът е добър, с феритен пръстен. Захранва се от Arduino чрез USB кабел. Средата за разработка може да бъде изтеглена (страница за изтегляне). Езикът е подобен на „C“, нямаше проблеми с овладяването му, тъй като програмирах много на него на работа.

LCD екран
На работа в кошчетата намерих съвместим LCD 1602 екран. Трябваше да се занимавам с връзката, тъй като не намерих лист с данни за нея. В резултат на това LCD спечели.

Но след кратка операция забелязах, че този екран не ми е достатъчен и няма да мога да покажа повече данни, тъй като има само 2 реда по 16 знака всеки. Първоначално изглежда, че тези параметри са достатъчни, но когато започнете да програмирате, разбирате, че можете да натъпчете максимум 3-4 параметъра. И ако направиш меню (мислех да направя меню на този екран), тогава остават 1-2 свободни места за параметри.
В резултат на това започнах да търся друг екран. Първоначално погледнах графичния екран от Nokia 3310 и дори участвах в търга на eBay, за да го купя, но не се получи (за което много се радвам), така че трябваше да се откажа от този екран. Сега разбирам, че би било твърде малко за моите цели, тъй като има с какво да се сравнява.
Докато разглеждах щитовете на Arduino случайно, попаднах на графичния екран 12864 на контролера ST7920. Този екран има правилния размер и добра резолюция за моите нужди (128x64). Тоест можете спокойно да поставите 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). За да регулирате яркостта на подсветката, можете да използвате променлив резистор 10kΩ, свързан между захранващите шини и GND. Напрежението от неговия двигател се прилага към пин 19 на дисплея.
Според тази инструкция свързах всичко с изключение на подсветката. Използвах Arduino PWM като мощност на подсветката.
За програмно свързване на 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;
intv;
return (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
}

Void настройка (void) (
u8g.setFont(u8g_font_6x10); // шрифт
u8g.setRot180(); // Обърнете екрана
analogWrite(6, 115); // Задаване на яркост на екрана (анод за задно осветяване на 6 пина)
}

Void цикъл (void) (
u8g.firstPage();
правя(

u8g.setPrintPos(1, 12); // позиция
u8g.print("Здравей!!!"); // текстов изход
u8g.drawBox(0,22,128,9); // Запълване на правоъгълника с бяло
u8g.setColorIndex(0); // бяло мастило, черен фон
u8g.setPrintPos(1, 30); // позиция
u8g.print("Дума..."); // текстов изход

U8g.setColorIndex(1); // бяло мастило, черен фон
u8g.setPrintPos(1, 50); // позиция
u8g.print("След стартиране ="); // текстов изход
u8g.setPrintPos(85, 50); // позиция
u8g.print(milis() / 1000); // отпечатване на броя секунди след началото
u8g.setPrintPos(1, 64); // позиция
u8g.print(freeRam()); // изведе колко памет се използва
) докато (u8g.nextPage());

забавяне (200);
}

Часовник за реално време DS1307
Друг компонент за моята метеорологична станция. Този щит има часовник за реално време. Поръчах ги от eBay. Продавачът изпрати кърпичка за часовник в нереално голяма кутия


Вътре в кутията имаше два листа А4 с реклама и носна кърпичка за часовник, увити в целофан


Искам да отбележа, че таксата не надвишава размера на 2 рубли. монета, а кутията беше с размери 13х15х5см.
Платката беше опакована в антистатична торбичка

Шал отблизо



Трябваше да се занимавам с този модул. Първо, имаше трудности с връзката. И второ, на тази платка няма кварц. Ако знаех, че ще отделя толкова много време на модула, тогава най-вероятно щях да го сглобя сам, тъй като мрежата е пълна със схеми. Най-простата схема съдържа 4-5 компонента.
Относно връзката. Намерих библиотека, която казваше, че интерфейсът I2C може да бъде свързан не към обичайните аналогови входове на Arduino (A4 и A5), а към всякакви дискретни. Направи както е написано. Отначало нищо не работеше, след дълъг танц с тамбура часовникът се нави. Е, помислих си, това е, проблемите свършиха, но след като се опитах да свържа същия модул към друго 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

Байт decToBcd(байт стойност)
{
връщане ((val/10*16) + (val%10));
}

Байт bcdToDec(байтова стойност)
{
връщане ((val/16*10) + (val%16));
}

Void setDateDs1307(байт секунда, // 0-59
байт минута, // 0-59
байт час) // 0-99
{

Wire.write(0);
Wire.write(decToBcd(втори));
Wire.write(decToBcd(минута));
Wire.write(decToBcd(час));
Wire.endTransmission();
}

Void getDateDs1307(байт *втори,
байт*минута,
байт*час)
{

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

Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

*второ = bcdToDec(Wire.read());
*минута = bcdToDec(Wire.read());
*час = bcdToDec(Wire.read());
}

Празни настройки ()
{
байт секунда, минута, час;
Wire.begin();
Serial.begin(9600);

второ = 45;
минута = 5;
часа = 16;

SetDateDs1307(секунда, минута, час);
}

Void loop()
{
байт секунда, минута, час;

GetDateDs1307(&секунда, &минута, &час);
Serial.print(час, DEC);
сериен печат (":");
Serial.print(минута, DEC);
сериен печат (":");
Serial.println(второ, DEC);

забавяне (1000);
}


Библиотеката не се използва тук и функциите са съкратени за времето за четене и писане.

Сензор за температура и влажност DHT11
Няма много какво да се каже за този сензор. Дори не бих го използвала, ако нямах нужда от влага. За съжаление не го снимах, когато го получих, така че няма да има снимки. Снимките на сензора могат да се видят по-долу, където го свързах към Arduino. Свързването на сензора е лесно (+, цифров изход, -). Обикновено сензорите се правят с четири щифта. С този форм фактор третият контакт не е свързан с нищо.
За да се свържете с Arduino, можете да използвате библиотеката. Можете да изтеглите.
Малка тестова програма с извеждане на информация към LCD дисплей 1602:

// включва кода на библиотеката:
#включи
#включи

// Деклариране на обекти
dht11 DHT11;
LiquidCrystal lcd (12, 11, 6, 5, 4, 3);

#define DHT11PIN 7
int i;

Празни настройки ()
{
lcd.begin(16, 2);
lcd.print("Състояние: ");
i=0;
}

Void loop()
{
int chk = DHT11.read(DHT11PIN);
lcd.setCursor(8, 0);
превключвател (chk)
{
случай 0: lcd.print("OK"); прекъсване;// lcd.setCursor(11, 0); lcd.print(milis()/2000); прекъсване;
случай -1: lcd.print(“Грешка в контролната сума”); мерр(); прекъсване;
случай -2: lcd.print("Грешка при изчакване"); мерр(); прекъсване;
по подразбиране: lcd.print("Неизвестна грешка"); мерр(); прекъсване;
}
забавяне (500);
lcd.setCursor(15, 0);
превключвател (i)
{
случай 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" "); прекъсване;
случай 1: lcd.print("v"); lcd.setCursor(15, 1); lcd.print(" "); прекъсване;
по подразбиране: lcd.setCursor(15, 1); lcd.print("E"); прекъсване;
}
i=i+1;
ако (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 печат ("%");
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. Правилното деклариране на променливи също спестява място. Ако декларирате масив като дълъг, въпреки че е напълно възможно да се мине с байт, тогава преразходът на паметта достига 500 байта, в зависимост от размера на масива. Когато пишете програма, вие не мислите за нея и едва по-късно, когато анализирате програмата, разбирате, че сте направили някои неща грешно и започвате да оптимизирате кода. След като проблемите с размера на програмата бяха разрешени, се натъкнах на ограничение на RAM. Това се изразяваше във факта, че програмата започна да виси след зареждане. Трябваше да въведа подпрограма за изчисляване на свободната RAM памет. В резултат на това бях принуден да изоставя един алгоритъм за прогнозиране на времето, тъй като той трябва да показва икони на екрана. Самият алгоритъм работи, но изходът на иконите трябваше да бъде запазен. Все още имам идеи как да оптимизирам кода, но в близко бъдеще ще оставя устройството да работи така, както е, за да оценя производителността и да идентифицирам всички грешки.

Сега малко заключения
минуси
1) Цена. Оправданието за този минус е, че хобитата никога не са евтини.

професионалисти
1) Голяма функционалност на устройството
2) Разширяването на функциите е ограничено само от използвания контролер и вашето собствено желание
3) Естетическо удоволствие от съзерцанието и морално удовлетворение от факта, че въпреки това сглобих и завърших това устройство

Смятам да купя +86 Добави към любими Рецензията ми хареса +137 +304

Някак си, разхождайки се из града, видях нов магазин за радиоелектроника, който беше отворен. Влизайки в него, намерих голям брой щитове за Arduino. Имах Arduino Uno и Arduino Nano у дома и веднага ми хрумна идеята да си поиграя с предаватели на сигнал от разстояние. Реших да купя най-евтиния предавател и приемник на 433 MHz:

Предавател на сигнал.


приемник на сигнал.

След като записа най-простата скица на предаване на данни (пример е взет от тук), се оказа, че предавателните устройства могат да бъдат доста подходящи за предаване на прости данни, като температура, влажност.

Предавателят има следните характеристики:
1. Модел: MX-FS-03V
2. Радиус на действие (зависи от наличието на блокиращи обекти): 20-200 метра
3. Работно напрежение: 3.5 -12V
4. Размери на модула: 19*19 мм
5. Модулация на сигнала: AM
6. Мощност на предавателя: 10mW
7. Честота: 433MHz
8. Необходима дължина на външна антена: 25см
9. Лесен за свързване (само три проводника): DATA ; VCC ; Земята.

Характеристики на приемния модул:
1. Работно напрежение: DC 5V
2. Ток: 4mA
3. Работна честота: 433.92MHz
4. Чувствителност: - 105dB
5. Размери на модула: 30*14*7 мм
6. Необходима външна антена: 32 см.

В необятността на Интернет се казва, че обхватът на предаване на информация при 2Kb / s може да достигне до 150 m. Не съм го проверявал сам, но в двустаен апартамент приема навсякъде.

Хардуер за домашна метеорологична станция

След няколко експеримента реших да свържа сензор за температура, влажност и предавател към Arduino Nano.


Температурният сензор DS18D20 е свързан към arduino, както следва:

1) GND към минуса на микроконтролера.
2) DQ през издърпващ резистор към земята и към щифта D2 на Arduino
3) Vdd до +5V.

Предавателният модул MX -FS - 03V се захранва от 5 волта, изходът за данни (ADATA) е свързан към пин D13.

Свързах LCD дисплей и барометър BMP085 към Arduino Uno.


електрическа схема за arduino uno

Приемникът на сигнала е свързан към щифт D10.

Модулът BMP085 е цифров сензор за атмосферно налягане. Сензорът ви позволява да измервате температура, налягане и надморска височина. Интерфейс за свързване: I2C. Захранващо напрежение на сензора 1.8-3.6 V

Модулът е свързан към Arduino по същия начин като другите I2C устройства:

  • VCC - VCC (3.3V);
  • GND-GND;
  • SCL - към аналогов пин 5;
  • SDA - към аналогов пин 4.
  • Много ниска цена
  • Захранване и I/O 3-5V
  • Определяне на влажност 20-80% с 5% точност
  • Определяне на температура 0-50 градуса. с 2% точност
  • Честота на запитване не повече от 1 Hz (не повече от веднъж на 1 сек.)
  • Размери 15.5mm x 12mm x 5.5mm
  • 4 щифта с 0,1" разстояние между краката

DHT има 4 пина:

  1. Vcc (3-5V захранване)
  2. Data out - Извеждане на данни
  3. Не се използва
  4. Общ

Свързва се с D8 Arduino.

Софтуер за домашни метеорологични станции

Трансмитерният модул измерва и предава температурата на всеки 10 минути.

По-долу е програмата:

/* Версия на скица 1.0 Изпращайте температура на всеки 10 минути. */ #include #include #include #define ONE_WIRE_BUS 2 //Пин за свързване на датчик Dallas OneWire oneWire(ONE_WIRE_BUS); Далас Температурни сензори (&oneWire); DeviceAddress insideThermometer; void setup(void) ( //Serial.begin(9600); vw_set_ptt_inverted(true); // Изисква се за DR3100 vw_setup(2000); // Задайте скорост на предаване (bps) sensors.begin(); if (!sensors .getAddress (insideThermometer, 0)); printAddress(insideThermometer); sensors.setResolution(insideThermometer, 9); ) void printTemperature(DeviceAddress deviceAddress) ( float tempC = sensors.getTempC(deviceAddress); //Serial.print("Temp C: " ); //Serial.println(tempC); //Формиране на данни за изпращане int number = tempC; char symbol = "c"; //Сервисен символ за определяне, че това е сензор String strMsg = "z "; strMsg + = символ; strMsg += " "; strMsg += число; strMsg += " "; char msg; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); / / Изчакайте прехвърлянето да завърши delay(200); ) void loop(void) ( for (int j=0; j<= 6; j++) { sensors.requestTemperatures(); printTemperature(insideThermometer); delay(600000); } } //Определение адреса void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16); //Serial.print("0"); //Serial.print(deviceAddress[i], HEX); } }

Приемащото устройство получава данни, измерва налягането и температурата в помещението и ги предава на дисплея.

#include #include LiquidCrystal lcd(12, 10, 5, 4, 3, 2); #включете сензор dht11; #define DHT11PIN 8 #include #include BMP085 dps = BMP085(); дълга температура = 0, налягане = 0, надморска височина = 0; void setup() ( Serial.begin(9600); vw_set_ptt_inverted(true); // Изисква се за DR3100 vw_setup(2000); // Задаване на скорост на получаване vw_rx_start(); // Стартиране на наблюдение на въздуха lcd.begin(16, 2); Wire.begin(); delay(1000); dps.init(); //lcd.setCursor(14,0); //lcd.write(byte(0)); //lcd.home(); ) void loop() ( uint8_t buf; // Буфер за съобщения uint8_t buflen = VW_MAX_MESSAGE_LEN; // Дължина на буфера if (vw_get_message(buf, &buflen)) // Ако е получено съобщение ( // Стартиране на анализиране на int i; // Ако съобщението е не е адресирано до нас, излезте ако (buf != "z") ( return; ) char команда = buf; // Командата е с индекс 2 // Числовият параметър започва с индекс 4 i = 4; int number = 0; // Тъй като предаването е символ по знак, тогава трябва да преобразувате набора от знаци в число, докато (buf[i] != " ") ( число *= 10; число += buf[i] - "0"; i++; ) dps.getPressure(&Налягане); dps.getAltitude (&Надморска височина); dps.getTemperature(&Температура); //Serial.print(команда); Serial.print(" "); Сериен println(номер); lcd.print("T="); lcd.setCursor(2,0); LCD печат (номер); lcd.setCursor(5,0); lcd.print("P="); lcd.print(Налягане/133,3); lcd.print("mmH"); lcd.setCursor(0,1); lcd.print("T="); lcd.print(температура*0,1); lcd.print("H="); lcd.print(sensor.humidity); lcd.home(); // забавяне (2000); int chk = sensor.read(DHT11PIN); switch (chk) ( case DHTLIB_OK: //Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: //Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: //Serial.println("Time out" грешка"); прекъсване; по подразбиране: //Serial.println("Неизвестна грешка"); прекъсване; ) ) )

P.S. В бъдеще смятам да добавя следното:
- сензор за влажност към предавателя, преработете алгоритъма за предаване на данни
- сензор за измерване на скоростта и посоката на вятъра.
- добавяне на друг дисплей към приемника.
- прехвърлете приемника и предавателя на отделен микроконтролер.

По-долу има снимка на случилото се:

Списък на радио елементи

Обозначаване Тип Деноминация Количество ЗабележкарезултатМоят бележник
предавателна част.
Ардуино платка

Arduino Nano 3.0

1 Към бележника
температурен сензор

DS18B20

1 Към бележника
Резистор

220 ома

1 Към бележника
предавателен модулMX-FS-03V (433 MHz)1 Към бележника
радио приемна част.
Ардуино платка

Ардуино Уно

1 Към бележника
Тример резистор 1 Към бележника
Резистор

Препоръчително е да изтеглите фърмуера, преди да свържете компонентите, за да сте сигурни, че платката работи. След сглобяването можете да мигате отново, дъската трябва да мига спокойно. При проекти с консуматори с висока мощност в 5V захранващата верига на платката (адресируема LED лента, серво, мотори и т.н.), е необходимо да се приложи външно 5V захранване към веригата, преди да свържете Arduino към компютъра, тъй като USB няма да осигури необходим ток, ако например лентата го изисква. Това може да изгори защитния диод на платката Arduino. Ръководство за изтегляне и качване на фърмуера може да се намери под спойлера на следващия ред.

Съдържанието на папките в архива

  • библиотеки– проектни библиотеки. Заменете съществуващите версии
  • фърмуер- Firmware за Arduino
  • схеми– схеми на свързване на компоненти

Допълнително

  • Както показа експериментът, извън кутията сензорът за температура показва 0,5 градуса по-малко, отколкото вътре! Необходимо е по-успешно да се подреди електрониката, да се отстрани и екранира топлината от нагревателните елементи ...

  • Ако дисплеят е твърде тъмен/бял
    На платката на драйвера на дисплея (към който са свързани проводниците) има копче за контраст, с негова помощ можете да регулирате контраста до желания. Освен това контрастът зависи от ъгъла на видимост на дисплея (това е LCD) и можете да настроите дисплея да показва ясно дори под ъгъл „дисплеят е на нивото на пъпа, гледаме отгоре“. А контрастът силно зависи от захранването: от 5V дисплеят показва възможно най-ясно и ярко, докато при захранване от USB през Arduino напрежението ще бъде около 4.5V (част от него пада върху защитния диод по USB линия), а дисплеят не показва толкова ярко. Регулирайте мощността с копче с външно захранване от 5V!

  • Ако сензорът за CO2 не работи правилно (информация от Евгений Иванов)
    Е, има скици за калибриране в папката на библиотеката на сензора в примери. може също да се стартира без работа чрез късо свързване на "HD" конектора към земята за 7+ секунди.
    Разбира се, точно на улицата в студа, не е необходимо да правите това ... можете просто да напълните бутилката с чист въздух със сензор вътре и да я запечатате. калибрирането отнема поне 20 минути.
    По подразбиране сензорът се доставя с активирано автоматично калибриране, което се случва всеки ден и ако сензорът се използва в непроветрено помещение, тогава това калибриране бързо отнема стойностите от нормата отвъд хоризонта, така че трябва да бъде деактивирано .
    Документация.

  • Автоматично калибриране на сензора CO2 е деактивиран в скицата!

  • Ако имате Сензорът BME280 не работи, най-вероятно е с друг адрес. Проектът използва библиотеката Adafruit_BME280, която няма отделна функция за промяна на адреса, така че адресът се задава ръчно във файла на библиотеката Adafruit_BME280.h почти в самото начало на файла ( е в папката Adafruit_BME280 в папката на вашите библиотеки, трябва да сте го инсталирали там), моят модул имаше адрес 0x76. Как мога да разбера адреса на моя модул BME280? Има специална скица, наречена i2c скенер. Можете да го търсите в Google, можете. Flash тази скица, отворете порта и вземете списък с адреси на устройства, свързани към i2c шината. За да не ви пречат другите модули, можете да ги изключите и да оставите само BME280. Посочваме получения адрес в библиотеката, запазваме файла и зареждаме фърмуера на часовника за времето. Всичко!

  • Ако часовникът изостава, проблемът най-вероятно е в захранващата верига. Ако проблемът продължава, когато смените захранването с по-добро, закачете кондензатор за захранване на RTC модула (запоете директно върху платката към VCC и GND): задължително керамичен, 0,1-1 uF (маркировка 103 или 104, вижте таблицата за маркиране ). Може да сложите и електролит (6.3V, 47-100 uF)

Настройки на фърмуера

#define RESET_CLOCK 0 // нулиране на часовника, докато фърмуерът се зарежда (за модул с несменяема батерия). Не забравяйте да поставите 0 и да мигате отново! #define SENS_TIME 30000 // време за опресняване на показанията на сензора на екрана, милисекунди #define LED_MODE 0 // RGB LED тип: 0 - основен катод, 1 - основен анод #define LED_BRIGHT 255 // CO2 LED яркост (0 - 255) # define BLUE_YELLOW 1 // жълт цвят вместо син (1 да, 0 не), но поради характеристиките на връзката жълтото не е толкова ярко #define DISP_MODE 1 // показване в горния десен ъгъл: 0 - година, 1 - ден от седмицата , 2 - секунди #define WEEK_LANG 1 // език на деня от седмицата: 0 - английски, 1 - руски (транслитериран) #define DEBUG 0 // показване на регистрационния файл за инициализация на сензора при стартиране #define PRESSURE 1 // 0 - налягане графика, 1 - графика за прогноза за дъжд (вместо налягане). Не забравяйте да коригирате границите на диаграмата // ограниченията за показване на графиките #define TEMP_MIN 15 #define TEMP_MAX 35 #define HUM_MIN 0 #define HUM_MAX 100 #define PRESS_MIN -100 #define PRESS_MAX 100 #define CO2_MIN 300 #define CO2_MAX 2000

Един мой колега наскоро беше домакин на малък научен панаир.
Моят учител ме помоли да представя проект по електроника пред студенти. Имах два дни, за да измисля нещо интересно и достатъчно просто.



Тъй като климатичните условия тук са доста променливи и температурата варира в диапазона 30-40 ° C, реших да направя домашна метеорологична станция.

Какви са функциите на домашната метеорологична станция?
Метеорологичната станция Arduino с дисплей е устройство, което събира данни за времето и условията на околната среда с помощта на различни сензори.

Обикновено това са следните сензори:

  • вятър
  • влажност
  • дъжд
  • температура
  • налягане
  • височини

Целта ми е да направя преносима настолна метеорологична станция със собствените си ръце.

Той трябва да може да дефинира следните параметри:

  • температура
  • влажност
  • налягане
  • височина

Стъпка 1: Купете правилните компоненти







  • DHT22, сензор за температура и влажност.
  • BMP180, датчик за налягане.
  • Спойка
  • Едноредов конектор 40 изхода

От оборудването ще ви трябва:

  • поялник
  • клещи за подложки за нос
  • жици

Стъпка 2: DHT22 сензор за температура и влажност







За измерване на температурата се използват различни сензори. DHT22, DHT11, SHT1x са популярни

Ще обясня как се различават един от друг и защо използвах DHT22.

Сензорът AM2302 използва цифров сигнал. Този сензор работи с уникална система за кодиране и сензорна технология, така че данните му са надеждни. Неговият сензорен елемент е свързан към 8-битов едночипов компютър.

Всеки сензор от този модел е термично компенсиран и прецизно калибриран, коефициентът на калибриране се съхранява в еднократно програмируема памет (OTP памет). Когато чете показание, сензорът ще извика коефициента от паметта.

Малък размер, ниска консумация на енергия, голямо разстояние на предаване (100 м) правят AM2302 подходящ за почти всички приложения, а 4 изхода в един ред правят инсталирането много лесно.

Нека да разгледаме плюсовете и минусите на трите модела сензори.

DHT11

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

DHT22

Плюсове: не изисква запояване, ниска цена, плавни криви, малки грешки при измерване, голям обхват на измерване, обхват над 20 m, силни смущения.
Минуси: чувствителността може да бъде по-висока, бавно проследяване на температурните промени, необходима е библиотека.
Приложения: екологични изследвания.

SHT1x

Плюсове: не е необходимо запояване, плавни криви, малки грешки при измерване, бърза реакция, ниска консумация на енергия, автоматичен режим на заспиване, висока стабилност и последователност на данните.
Минуси: два цифрови интерфейса, грешка при измерване на нивото на влажност, диапазонът на измерваните температури е 0-50°C, необходима е библиотека.
Приложения: работа в тежки среди и при дългосрочни инсталации. И трите сензора са сравнително евтини.

Съединение

  • Vcc - 5V или 3.3V
  • Gnd - с Gnd
  • Данни - към втория щифт на Arduino

Стъпка 3: Сензор за налягане BMP180



BMP180 е барометричен сензор за атмосферно налягане с I2C интерфейс.
Сензорите за барометрично налягане измерват абсолютната стойност на околния въздух. Този показател зависи от конкретните метеорологични условия и от надморската височина.

Модулът BMP180 имаше регулатор 3.3V 662k ohm, който аз по моя собствена глупост случайно гръмнах. Трябваше да направя мощен удар директно към чипа.

Поради липсата на стабилизатор съм ограничен в избора на източник на захранване - напрежение над 3.3V ще унищожи сензора.
Други модели може да нямат стабилизатор, не забравяйте да го проверите.

Схема на свързване на сензора и I2C шина с Arduino (nano или uno)

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

Нека поговорим малко за налягането и как то се свързва с температурата и надморската височина.

Атмосферното налягане във всяка точка не е постоянно. Сложното взаимодействие между въртенето на Земята и наклона на земната ос води до много области с високо и ниско налягане, което от своя страна води до ежедневна промяна на времето. Като наблюдавате промяната в налягането, можете да направите краткосрочна прогноза за времето.

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

Атмосферното налягане също се променя с надморската височина. Абсолютното налягане в базовия лагер на Еверест (5400 m над морското равнище) е по-ниско от абсолютното налягане в Делхи (216 m над морското равнище).

Тъй като показанията за абсолютно налягане варират на всяко място, ние ще говорим за относително налягане или налягане на морското равнище.

Измерване на височина

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

Ако вземете налягането на морското равнище от 1013,25 GPa като p0, решението на уравнението е вашата текуща надморска височина.

Предпазни мерки

Имайте предвид, че сензорът BMP180 се нуждае от достъп до атмосферата, за да може да отчита въздушното налягане, не поставяйте сензора в затворен калъф. Малък вентилационен отвор ще бъде достатъчен. Но не го оставяйте твърде отворен - вятърът ще събори показанията за налягане и надморска височина. Помислете за защита от вятър.

Пазете от топлина. За измерване на налягането са необходими точни показания на температурата. Опитайте се да предпазите сензора от температурни колебания и не го оставяйте близо до източници на високи температури.

Пазете от влага. Сензорът BMP180 е чувствителен към нивата на влага, опитайте се да предотвратите евентуално проникване на вода върху сензора.

Не заслепявайте сензора. Изненадата беше чувствителността на силикона в сензора към светлина, която може да попадне върху него през отвор в капака на чипа. За най-точни измервания се опитайте да защитите сензора от околната светлина.

Стъпка 4: Сглобяване на устройството







Инсталиране на едноредови конектори за Arduino Nano. По принцип ги нарязахме по размер и ги шлайфахме малко, така че да изглеждат така, както са били. След това ги запояваме. След това инсталираме едноредови конектори за сензора DHT22.

Инсталирайте резистор от 10 kΩ от изхода за данни към земята (Gnd). Запояваме всичко.
След това по същия начин инсталираме едноредов конектор за сензора BMP180, правим захранването 3.3V. Свързваме всичко с I2C шината.

И накрая, свързваме LCD дисплея към същата I2C шина като сензора BMP180.
(Планирам по-късно да свържа RTC модул (часовник за реално време) към четвъртия конектор, така че устройството също да показва часа).

Стъпка 5: Кодиране




Изтегляне на библиотеки

За да инсталирате библиотеки на Arduino, следвайте връзката

#включи
#include #include #include "DHT.h" #include

SFE_BMP180 налягане;

#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 // към какъв цифров щифт сме свързани

// Разкоментирайте какъвто и тип да използвате! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin, 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 (статус != 0) ( Serial.print("1"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Баро температура: "); lcd.setCursor(0,1 ); lcd.print(T,2); lcd.print(" deg C "); t1=T; забавяне (3000);

статус = натиск.startPressure(3); if (status != 0) ( // Изчакайте измерването да завърши: delay(status);

състояние = pressure.getPressure(P,T); if (статус != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("абсолютно налягане: "); lcd.setCursor(0,1); lcd.print(P,2 ); lcd.print(" mb "); забавяне (3000);

p0 = pressure.sealevel(P,надморска височина); // ние сме на 1655 метра (Боулдър, Колорадо)

a = налягане.надморска височина(P,p0); lcd.clear(); lcd.setCursor(0,0); lcd.print("Надморска височина: "); lcd.setCursor(0,1); lcd.print(a,0); lcd.print("метри"); забавяне (3000); ) ) ) float h = dht.readHumidity(); // Прочетете температурата като Целзий (по подразбиране) float t = dht.readTemperature(); t2=t; lcd.clear(); lcd.setCursor(0,0); // отидете в началото на 2-ри ред lcd.print("Влажност: "); lcd.setCursor(0,1);lcd.print(h); lcd.print("%"); забавяне (3000); lcd.clear(); lcd.setCursor(0,0); // отидете в началото на 2-ри ред LCD print("DHT Tempurature: "); lcd.setCursor(0,1); LCD печат (t); lcd.print("degC"); забавяне (3000); lcd.clear(); lcd.setCursor(0,0); // отидете в началото на 2-ри ред lcd.print("Средна температура: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print("degC"); забавяне (3000); )

Използвах Arduino версия 1.6.5, кодът му пасва точно, по-късните също могат да работят. Ако кодът не пасва по някаква причина, използвайте версия 1.6.5 като базова.

Гледането на времето е много вълнуващо занимание. Реших да изградя моята метеорологична станция въз основа на популярната .

Прототипът на метеорологичната станция изглежда така:

Функции на моята метеорологична станция:

  • измерване и показване на стайни и външни температури;
  • показване на текущото време (часове и минути);
  • показване на текущите фази на луната и лунния ден;
  • прехвърляне на резултатите от измерването към компютър чрез серийна връзка;
  • предаване на резултатите от измерването по протокол MQTTизползване на приложение на компютър.


шестнадесетичен
-файл
фърмуер за (версия от 9 май 2018 г.) - .
Как се флашва шестнадесетичен-файл към борда АрдуиноОписал съм.

Микроконтролер Arduino Nano 3.0

„Сърцето“ на моята метеорологична станция е микроконтролерът eBay):

За да контролирам индикацията и запитването на сензори, използвам таймер 1 Ардуино, предизвикващи прекъсвания с честота 200 Hz (период - 5 ms).

Индикатор

За показване на измерените показания на сензорите и текущото време, свързах се с Ардуиночетирицифрен LED индикатор Foryard FYQ-5643BHс общи аноди (анодите на еднакви сегменти от всички разряди се комбинират).
Индикаторът съдържа четири седемсегментни цифри и две разделителни (часови) точки:

Анодите на индикатора са свързани чрез токоограничаващи резистори към клемите Ардуино:

освобождаване от отговорност 1 2 3 4
заключение A3 A2 D3 D9

Сегментни катоди, свързани към щифтове Ардуино:

сегмент а b ° С д д f ж стр
заключение D7 D12 D4 D5 D6 D11 D8 D13

Сегментът на индикатора светва, ако анодът на съответния разряд има висок потенциал (1) и нисък потенциал (0) на катода.

Използвам динамична индикация за показване на информация на индикатора - само една цифра е активна в даден момент. Активните разряди се редуват с честота 200 Hz (период на показване 5 ms). В същото време трептенето на сегментите е незабележимо за очите.

Датчик за температура DS18x20

За възможността за дистанционно измерване на температурата свързах сензор , който предоставя широк спектър от измервания на външна температура. Сензорът е свързан към шината 1 проводники има три изхода - мощност ( VCC), данни ( DAT), Земята ( GND):

сензорен изход VCC DAT GND
заключение Ардуино 5V A1 GND

Между щифтове VCCи DATВключих 4.7k ома издърпващ резистор.

За да конвертирате между градуси по Целзий и Фаренхайт, можете да използвате следната плоча:

Поставих сензора извън прозореца на къщата в пластмасов калъф от химикал:

\

Професионалните метеорологични станции използват екран на Stevenson, за да предпазят термометъра от пряка слънчева светлина и да позволят на въздуха да циркулира. екран на Стивънсън):

Сензор за налягане и температура BMP280

Живачните и анероидните барометри традиционно се използват за измерване на атмосферното налягане.

AT живачен барометъратмосферното налягане се балансира от теглото на живачен стълб, чиято височина се използва за измерване на налягането:

AT анероиден барометъризползва се компресия и разтягане на кутията под атмосферно налягане:

За измерване на атмосферното налягане и стайната температура в моята домашна метеорологична станция използвам сензор - малък smd- 2 x 2,5 мм сензор, базиран на пиезорезистивна технология:

Носна кърпичка със сензор е закупена от пазара eBay:

Сензорът е свързан към шината I2C(данни за контакт - SDA/SDI, щифт за синхронизиране - SCL/SCK):

сензорен изход VCC GND SDI SCK
заключение Ардуино 3 на 3 GND A4 A5

адафрут- файлове Adafruit_Sensor.h, Adafruit_BMP280.h, Adafruit_BMP280.cpp.

Единици за атмосферно налягане

Сензор чрез функция readPressureдава стойността на атмосферното налягане в паскали. Основната единица за измерване на атмосферното налягане е хектопаскал(hPa) (1 hPa = 100 Pa), чийто аналог е извънсистемната единица " милибар" (mbar) (1 mbar = 100Pa = 1hPa). За преобразуване между често използвани единици за несистемно налягане " милиметър живачен стълб" (mm Hg) и хектопаскали се използват следните съотношения:
1 hPa = 0,75006 mmHg Изкуство. ≈ 3/4 mm Hg; 1 mmHg =1,3332 hPa ≈ 4/3 hPa.

Зависимостта на атмосферното налягане от надморската височина

Атмосферното налягане може да бъде представено както в абсолютна, така и в относителна форма.
Абсолютно налягане QFE(Английски) абсолютно налягане) е действителното атмосферно налягане, без да се взема предвид корекцията над морското равнище.
Атмосферното налягане намалява с около 1 hPa с увеличаване на надморската височина от 1 m:

Барометричната формула ви позволява да определите корекцията на показанията на барометъра, за да получите относително налягане (в mmHg):
$\Delta P = 760 \cdot (1 - (1 \over (10^ ( (0.0081350 \cdot H) \over (T + 0.00178308 \cdot H) ))))$ ,
където $T$ е средната температура на въздуха по скалата на Ранкин, ° Ра, $H$ - височина над морското равнище, футове.
Преобразуване на градуси Целзий в градуси Ранкин:
$^(\circ)Ra = (^(\circ)C \cdot 1.8) + 491,67$
Барометричната формула се използва за барометрична нивелация - определяне на височини (с грешка 0,1 - 0,5%). Формулата не отчита влажността на въздуха и изменението на ускорението на свободното падане с височина. При малки разлики във височината тази експоненциална зависимост може да се апроксимира с достатъчна точност чрез линейна зависимост.
Относително налягане QNH(Английски) относително налягане, Морска височина с Q-код) е атмосферното налягане, коригирано спрямо средното морско ниво. Средно морско ниво, MSL) (за Еи температура 15 градуса по Целзий) и първоначално се настройва, като се вземе предвид надморската височина, на която се намира метеостанцията. Може да се намери от данните на метеорологичната служба, показанията на калибрирани инструменти на обществени места, летището (от доклади METAR), от интернет.
Например за близкото летище Гомел ( UMGG) Мога да видя действителния доклад за времето METARна ru.allmetsat.com/metar-taf/russia.php?icao=UMGG :
UMGG 191800Z 16003MPS CAVOK M06/M15 Q1014 R28/CLRD//NOSIG ,
където Q1014- налягане QNHна летището е 1014 hPa.
История на бюлетините METARдостъпен от aviationwxchartsarchive.com/product/metar.
За нормално относително атмосферно налягане QNHприема се налягане от 760 mm Hg. Изкуство. или 1013.25 hPa (при температура 0ºС, под географска ширина 45º на северното или южното полукълбо).
Настроих налягането за анероидния барометър QNHс винта за настройка на чувствителността:

Прогноза за времето

Анализът на промените в налягането ви позволява да изградите прогноза за времето и нейната точност е толкова по-висока, колкото по-рязко се променя налягането. Например, едно старо правило на навигатор е, че спад на налягането от 10 hPa (7,5 mmHg) за период от 8 часа означава, че ви очакват силни ветрове.

Откъде идва вятърът? Въздухът тече към центъра на зоната с ниско налягане, вятър- хоризонтално движение на въздуха от области с високо налягане към области с ниско налягане (високото атмосферно налягане изтласква въздушни маси в области с ниско атмосферно налягане). Ако налягането е много ниско, вятърът може да достигне буря. В същото време в района намаленаналягане (барична депресия или циклон), топлият въздух се издига и образува облаци, които често носят дъждили сняг.

Посоката на вятъра в метеорологията е посоката, от която духа вятърът:

Тази посока е намалена до осем точки.

Често се използва алгоритъм за прогнозиране на времето въз основа на атмосферното налягане и посоката на вятъра. Замбрети.

Сензор за влажност

За определяне на относителната влажност на въздуха използвам модула DHT11(закупен от пазара eBay):

Сензор за влажност DHT11има три изхода - мощност ( + ), данни ( навън), Земята ( - ):

сензорен изход + навън -
заключение Ардуино 5V D10 GND

За да работя със сензора, използвам библиотеката от адафрут- файлове DHT.h, DHT.cpp.

Влажността характеризира количеството водни пари, съдържащи се във въздуха. Относителна влажностпоказва съотношението на влага във въздуха (като процент) по отношение на максимално възможното количество при текущата температура. Използва се за измерване на относителна влажност :

За човек оптималният диапазон на влажност на въздуха е 40 ... 60%.

Часовник за реално време

Като часовник за реално време приложих модула RTC DS1302(носна кърпичка с часовник е закупена на пазара eBay):

Модул DS1302свързан към автобуса 3 проводник. За да използвате този модул с Ардуиноразработена библиотека arduino_RTC(от arduino.ru).

Табло с модул DS1302има пет пина, които свързах към щифтовете на платката Ардуино Нано:

заключение RTC VCC GND RST CLK DAT
заключение Ардуино 5V GND D2 D1 D0

За да поддържам правилните показания на часовника, когато захранването е изключено, поставих батерия в гнездото на платката. CR2032.

Точността на моя часовников модул не беше много висока - часовникът е по-бърз с около една минута за четири дни. Затова нулирам минутите до „нула“ и часа до най-близкия, като задържам бутона, свързан към A0 щифта на Arduino, след включване на захранването на метеорологичната станция. След инициализацията щифт A0 се използва за прехвърляне на данни през серийната връзка.

Прехвърляне на данни към компютър и работа по MQTT протокол

За прехвърляне на данни чрез серийна връзка към Ардуиносвързва USB-UARTконвертор:

Заключение Ардуиноизползва се за прехвърляне на данни във формат 8N1(8 бита данни, без паритет, 1 стоп бит) при 9600 bps. Данните се предават на пакети, като дължината на пакета е 4 знака. Прехвърлянето на данни се извършва в " малко взрив" режим, без да използвате хардуерния сериен порт Ардуино.

Формат на предаваните данни:

Параметър 1-ви байт 2-ри байт 3-ти байт 4-ти байт
външна температура о интервал или минус десетки градуси или пространство единици градуси
стайна температура аз интервал или минус десетки градуси или пространство единици градуси
Атмосферно налягане стр стотици mm Изкуство. десетки mm Hg единици mmHg с.
относителна влажност ч пространство десетки процента или интервал единици проценти
текущо време десетки часове часове единици десетки минути единици минути

MQTT

golangприложение - клиент на протокола MQTT, който изпраща информацията, получена от метеорологичната станция към сървъра ( MQTT-брокер) :

Обслужване ви позволява да създадете акаунт с безплатен план " " (ограничения: 10 връзки, 10 Kbps):

За да следите показанията на метеорологичната станция, можете да използвате Android-Приложение :

Храна

За захранване на метеорологичната станция използвам зарядно от стар мобилен телефон. Motorola, извеждащ напрежение 5 V с ток до 0,55 A и свързан към контактите 5V(+) и GND (-):

Можете да използвате и 9 V батерия за захранване, свързана към контактите VIN номер(+) и GND (-).

Работа на метеорологичната станция

При стартиране сензорите се инициализират и проверяват.

При липса на сензор DS18x20издава се грешка "E1", ако няма датчик - грешка "E3".

След това започва работният цикъл на метеорологичната станция:

  • измерване и показване на външна температура;
  • измерване и показване на стайна температура;
  • измерване и показване на атмосферното налягане и тенденцията на неговото изменение;
  • измерване и показване на относителна влажност на въздуха;
  • показване на текущото време;
  • показване на фазата на луната и лунния ден.


Видеоклип на моята метеорологична станция е достъпен на моя -канал: https://youtu.be/vVLbirO-FVU

Температурен дисплей

При измерване на температура се показват две цифри за температурата, а за отрицателна температура знак минус (със символ за градус в най-дясната цифра);
за външна температура знакът за градус се показва в горната част:


за стайна температура - по-долу:

Дисплей за налягане

При измерване на налягането се показват три цифри на налягането в mmHg (със символа " П" в най-дясната цифра):

Ако налягането падне рязко, тогава вместо символа " П"символът" се показва в крайната дясна цифра Л"ако е нараснал рязко - тогава" з". Критерият за остротата на промяната е 8 mm Hg за 8 часа:

Тъй като метеорологичната ми станция показва абсолютно налягане ( QFE), тогава показанията се оказват малко подценени в сравнение с информацията в резюмето METAR(който осигурява QNH) (14 UTC, 28 март 2018 г.):

Коефициентът на налягане (според АТИС) беше $(1015 \над 998) = $1,017. Надморска височина на летище Gomel (ICAO код UMGG) над морското равнище е 143,6 м. Температурата според ATIS е 1 ° ° С.

Показанията на моята метеостанция почти съвпаднаха с абсолютното налягане QFEСпоред АТИС!

Макс./мин. налягане ( QFE), записани от моята метеорологична станция за целия период на наблюдение:

Показване на относителна влажност

Относителната влажност на въздуха се показва като процент (символът за процент се показва в двете десни цифри):

Дисплей за текущо време

Текущият час се показва на индикатора във формат "ЧЧ:ММ", като разделителното двоеточие мига веднъж в секунда:

Показване на фазите на луната и лунния ден

Първите две цифри на индикатора показват текущата лунна фаза, а следващите две - текущия лунен ден:

Луната има осем фази (дадени са английски и руски (сини - неточни) имена):

На фазовия индикатор се показват с пиктограми:

фаза пиктограма
нарастващ сърп (полумесец)
намаляващ полумесец (полумесец)

Прехвърляне на данни към компютър

Ако свържете метеорологичната станция с USB-UARTпреобразувател (например, базиран на микросхема CP2102) свързан с USB-порт на компютъра, тогава можете да използвате терминалната програма, за да наблюдавате данните, предавани от метеорологичната станция:

Разработих на език за програмиране golangпрограма, която води дневник на метеорологичните наблюдения и изпраща данни към услугата и може да се гледа на Android-смартфон с помощта на приложението :

Според дневника на метеорологичните наблюдения можете например да изградите графика на промените в атмосферното налягане:
пример за графика със забележим минимум на налягането


пример за графика с леко повишаване на налягането

Планирани подобрения:

  • добавяне на сензори за посока и скорост на вятъра

В метеорологичните станции анемометър с три чаши (1) се използва за измерване на скоростта на вятъра, а ветропоказател (2) се използва за определяне на посоката на вятъра:

Използва се и за измерване на скоростта на вятъра. анемометри с нажежена жица(Английски) анемометър с гореща тел). Като нагрята жица можете да използвате волфрамова жичка от електрическа крушка със счупено стъкло. В индустриалните анемометри с горещ проводник сензорът обикновено се намира върху телескопична тръба:

Принципът на работа на това устройство е, че топлината се отстранява от нагревателния елемент поради конвекция от въздушен поток - вятър. В този случай съпротивлението на нишката се определя от температурата на нишката. Законът за промяна на съпротивлението на нишката $R_T$ от температурата $T$ има формата:
$R_T = R_0 \cdot (1 + (\alpha \cdot (T - T_0)))$,
където $R_0$ е съпротивлението на нишката при температура $T_0$, $\alpha$ е температурният коефициент на съпротивление (за волфрам $\alpha = 4,5\cdot(10^(-3) (^(\circ)(C^ ( -1))))$).

При промяна на скоростта на въздушния поток температурата се променя при постоянен ток на нажежаемата жичка (анемометър с постоянен ток, англ. CCA). Ако температурата на нагревателния елемент се поддържа постоянна, тогава токът през елемента ще бъде пропорционален на скоростта на въздушния поток (анемометър с постоянна температура, англ. CTA).

Следва продължение

КАТЕГОРИИ

ПОПУЛЯРНИ СТАТИИ

2022 "kingad.ru" - ултразвуково изследване на човешки органи