В статье описан путь от идеи до создания домашнего портативного анализатора качества воздуха (CO2, влажность, температура, давление).
В сети много гуляет разных кошмаров про безжалостную черную плесень, которая убивает людей, а плесень любит влажные помещения. Бороться с плесенью тяжело, но самое первое, за чем нужно следить – это влажность воздуха. Еще о влажности стоит вспомнить с наступлением зимы, так как нагревая холодный воздух мы тем самым понижаем его влажность, а слишком сухой воздух негативно сказывается на слизистых оболочках, резко снижая иммунитет.
Рассуждая таким образом я пришел к выводу, что не плохо было бы соорудить на базе Ардуины такой себе показометр влажности. Пользуясь случаем и дешевизной цифровых датчиков, грех было не добавить еще и функцию барометра, термометра и, что немаловажно, функцию измерения количества углекислого газа в воздухе (в старых многоэтажках зачастую плохая вентиляция в квартирах, а сами квартиры на зиму плотно герметизируются). По углекислому газу тоже много страшилок, снижение работоспособности, головная боль, это могут быть симптомы высокой концентрации СО2 в воздухе.
В интернетах так же была найдена такая табличка допустимых концентраций СО2 в воздухе:

Итак, нам понадобится:
Итого: 71.48$ (промышленные приборы с похожим набором датчиков стоят от 300$)

На датчике углекислого газа следует остановиться отдельно. В то время как датчик давления и влажности выдают показания уже в цифре, имеют какие-никакие цепи стабилизации по питанию, то стоимость полностью цифрового датчика СО2 начинается от 120$, многовато как «для поиграться». Самый дешевый в виде модуля к Ардуине китайцы предлагают на базе MG811 за 36$. Посмотрел я на его характеристики, а там дикая зависимость от влажности, наличия посторонних газов в воздухе и решил, что нужно поискать что-то более точное и таким оказался TGS4161, привожу его характеристики:

Успокоившись на счет стабильности показаний, оформил покупку и датчик приехал через две недели.
Когда модуль ко мне приехал, у меня уже все было собрано на макетной плате, не хватало только его. Вооружившись паяльником я обратил свой взор к рекламной картинке (см. выше), мол как его подключать? Вот тут пришлось немного опешить, надежда, что Dout это цифровой выход, не оправдалась, документации на этот модуль вообще нет никакой и нигде, модуль делают китайцы штучно. Что же делать? Пришлось тыкать в ноги модуля тестером, дуть на датчик, привлекать такую-то мать, писать кролику… Методом тыка установлено что модуль содержит два операционных усилителя. Первый из них имеет входное сопротивление 1,5 ТОм (Вы не ошиблись именно тера-Ом, т.е. 1500 гиг-Ом, тогда как обычный цифровой мультиметр имеет входное сопротивление не более 20 мега-Ом), второй сдвоенный ОУ работает как компаратор и повторитель. Aout некий аналоговый сигнал с повторителя, Dout – сигнал с компаратора (активен если СО2 зашкаливает). Назначение вывода TCM установить не удалось.
Датчик представляет собой электрохимическую ячейку для работы которой нужна высокая температура. Температура обеспечивается встроенным в датчик нагревателем мощностью примерно 0,2Вт. Напряжение на ячейке при концентрации СО2 350ppm и ниже имеет некое стабильное значение, а когда концентрация СО2 растет, напряжение на ячейке тоже изменяется (падает). Для согласования высокого выходного сопротивления ячейки и с целью усиления напряжения применены ОУ.
Чтобы воспользоваться датчиком нужно перевести вольты в концентрацию СО2. Документация на сенсор утверждает, что начальное напряжение на сенсоре может быть любым а вот абсолютное изменение этого напряжения строго по даташиту. Значит нужно как минимум замерить нулевую начальную точку на свежем воздухе, дальше, построить модель сенсора на основе графика его чувствительности задав в качестве точки отсчета измеренное значение. В общем худо-бедно, модель была построена, датчик откалиброван и можно было все собирать вместе в какой-нибудь корпус:


Чувствительность свеже-откалиброванного датчика была такой что он мог достоверно отличать более свежий воздух в парку от загазованного проспекта за 300 метров.
По остальным датчикам: влажность меряет отлично, взяв в руки прибор сразу можно заметить рост влажности, прям таки скачек (еще бы, когда в квартире сейчас влажность всего 29%); давление тоже меряет отлично, как абсолютное так и относительное, подняв и опустив прибор можно заметить разницу в давлении.
На этом история не закончилась, а все только начиналось, потому что когда прибор перешел на автономное питание ему резко поплохело и история его лечения заслуживает отдельного топика, вот осциллограмма из истории болезни:

UPD:
Схема подключения типичная для указанных датчиков, более детально о распиновке в скетче.
Вступление
В сети много гуляет разных кошмаров про безжалостную черную плесень, которая убивает людей, а плесень любит влажные помещения. Бороться с плесенью тяжело, но самое первое, за чем нужно следить – это влажность воздуха. Еще о влажности стоит вспомнить с наступлением зимы, так как нагревая холодный воздух мы тем самым понижаем его влажность, а слишком сухой воздух негативно сказывается на слизистых оболочках, резко снижая иммунитет.
Рассуждая таким образом я пришел к выводу, что не плохо было бы соорудить на базе Ардуины такой себе показометр влажности. Пользуясь случаем и дешевизной цифровых датчиков, грех было не добавить еще и функцию барометра, термометра и, что немаловажно, функцию измерения количества углекислого газа в воздухе (в старых многоэтажках зачастую плохая вентиляция в квартирах, а сами квартиры на зиму плотно герметизируются). По углекислому газу тоже много страшилок, снижение работоспособности, головная боль, это могут быть симптомы высокой концентрации СО2 в воздухе.
В интернетах так же была найдена такая табличка допустимых концентраций СО2 в воздухе:

Итак, нам понадобится:
- 1. Arduino Pro Mini цена 2.15$
- 2. Датчик влажности и температуры DHT-22 он же AM2302 (улучшенная точность по сравнению с DHT-11), цена 4$
- 3. Датчик давления BMP180, цена 2.98$
- 4. Модуль с датчиком углекислого газа TGS4161, цена 60$
- 5. Дисплей типа Nokia 5110, цена 2,35$
Итого: 71.48$ (промышленные приборы с похожим набором датчиков стоят от 300$)

Датчик углекислого газа
На датчике углекислого газа следует остановиться отдельно. В то время как датчик давления и влажности выдают показания уже в цифре, имеют какие-никакие цепи стабилизации по питанию, то стоимость полностью цифрового датчика СО2 начинается от 120$, многовато как «для поиграться». Самый дешевый в виде модуля к Ардуине китайцы предлагают на базе MG811 за 36$. Посмотрел я на его характеристики, а там дикая зависимость от влажности, наличия посторонних газов в воздухе и решил, что нужно поискать что-то более точное и таким оказался TGS4161, привожу его характеристики:

Успокоившись на счет стабильности показаний, оформил покупку и датчик приехал через две недели.
Сборка устройства
Когда модуль ко мне приехал, у меня уже все было собрано на макетной плате, не хватало только его. Вооружившись паяльником я обратил свой взор к рекламной картинке (см. выше), мол как его подключать? Вот тут пришлось немного опешить, надежда, что Dout это цифровой выход, не оправдалась, документации на этот модуль вообще нет никакой и нигде, модуль делают китайцы штучно. Что же делать? Пришлось тыкать в ноги модуля тестером, дуть на датчик, привлекать такую-то мать, писать кролику… Методом тыка установлено что модуль содержит два операционных усилителя. Первый из них имеет входное сопротивление 1,5 ТОм (Вы не ошиблись именно тера-Ом, т.е. 1500 гиг-Ом, тогда как обычный цифровой мультиметр имеет входное сопротивление не более 20 мега-Ом), второй сдвоенный ОУ работает как компаратор и повторитель. Aout некий аналоговый сигнал с повторителя, Dout – сигнал с компаратора (активен если СО2 зашкаливает). Назначение вывода TCM установить не удалось.
Как же датчик работает?
Датчик представляет собой электрохимическую ячейку для работы которой нужна высокая температура. Температура обеспечивается встроенным в датчик нагревателем мощностью примерно 0,2Вт. Напряжение на ячейке при концентрации СО2 350ppm и ниже имеет некое стабильное значение, а когда концентрация СО2 растет, напряжение на ячейке тоже изменяется (падает). Для согласования высокого выходного сопротивления ячейки и с целью усиления напряжения применены ОУ.
Чтобы воспользоваться датчиком нужно перевести вольты в концентрацию СО2. Документация на сенсор утверждает, что начальное напряжение на сенсоре может быть любым а вот абсолютное изменение этого напряжения строго по даташиту. Значит нужно как минимум замерить нулевую начальную точку на свежем воздухе, дальше, построить модель сенсора на основе графика его чувствительности задав в качестве точки отсчета измеренное значение. В общем худо-бедно, модель была построена, датчик откалиброван и можно было все собирать вместе в какой-нибудь корпус:
Чувствительность свеже-откалиброванного датчика была такой что он мог достоверно отличать более свежий воздух в парку от загазованного проспекта за 300 метров.
По остальным датчикам: влажность меряет отлично, взяв в руки прибор сразу можно заметить рост влажности, прям таки скачек (еще бы, когда в квартире сейчас влажность всего 29%); давление тоже меряет отлично, как абсолютное так и относительное, подняв и опустив прибор можно заметить разницу в давлении.
Далее следует...
На этом история не закончилась, а все только начиналось, потому что когда прибор перешел на автономное питание ему резко поплохело и история его лечения заслуживает отдельного топика, вот осциллограмма из истории болезни:

UPD:
Схема подключения типичная для указанных датчиков, более детально о распиновке в скетче.
Рабочий скетч для Arduino UNO
Скетч собирался (копипастился) с разных кусков, так что сильно не ругайте, надеюсь разобраться в нем можно
#include <SFE_BMP180.h>
#include <Wire.h>
#include "DHT.h"
#define PIN_SCE 7 // LCD CS .... Pin 2
#define PIN_RESET 6 // LCD RST .... Pin 1
#define PIN_DC 5 // LCD Dat/Com. Pin 3
#define PIN_SDIN 4 // LCD SPIDat . Pin 4
#define PIN_SCLK 3 // LCD SPIClk . Pin 5
// LCD Gnd .... Pin 8
// LCD Vcc .... Pin 6
// LCD Vlcd ... Pin 7
#define LCD_C LOW
#define LCD_D HIGH
#define LCD_X 84
#define LCD_Y 48
#define LCD_CMD 0
SFE_BMP180 pressure;
#define DHTPIN 10
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define ALTITUDE 113.0 // Altitude of SparkFun's HQ in Boulder, CO. in meters
int a = 0;
int sensorPin = A0; // вход подключается к Aout модуля с датчиком СО2
int vBattPin = A1; // вход используется для мониторинга за состояние батареи
int sensorValue = 0; // variable to store the value coming from the sensor
float adc_step=5/1024.0f; //шаг измерения АЦП
float a_k=5.0894E-7; //магическая константа модели датчика СО2
float b_k=6.7303E-4;//еще одна магическая константа модели датчика СО2
float v_0=1.09; //напряжение на выходе датчика на свежем воздухе
int ledPin=13;
static const byte ASCII[][5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0xff, 0xff, 0xff, 0xff, 0xff} // 21 !
//,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f →
};
void LcdCharacter(char character)
{
LcdWrite(LCD_D, 0x00);
for (int index = 0; index < 5; index++)
{
LcdWrite(LCD_D, ASCII[character - 0x20][index]);
}
LcdWrite(LCD_D, 0x00);
}
void LcdClear(void)
{
for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D, 0x00);
}
}
void LcdInitialise(void)
{
pinMode(PIN_SCE, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(PIN_DC, OUTPUT);
pinMode(PIN_SDIN, OUTPUT);
pinMode(PIN_SCLK, OUTPUT);
digitalWrite(PIN_RESET, LOW);
// delay(1);
digitalWrite(PIN_RESET, HIGH);
LcdWrite( LCD_CMD, 0x21 ); // LCD Extended Commands.
LcdWrite( LCD_CMD, 0xBf ); // Set LCD Vop (Contrast). //B1
LcdWrite( LCD_CMD, 0x04 ); // Set Temp coefficent. //0x04
LcdWrite( LCD_CMD, 0x14 ); // LCD bias mode 1:48. //0x13
LcdWrite( LCD_CMD, 0x0C ); // LCD in normal mode. 0x0d for inverse
LcdWrite(LCD_C, 0x20);
LcdWrite(LCD_C, 0x0C);
}
void LcdString(char *characters)
{
while (*characters)
{
LcdCharacter(*characters++);
}
}
void LcdWrite(byte dc, byte data)
{
digitalWrite(PIN_DC, dc);
digitalWrite(PIN_SCE, LOW);
shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
digitalWrite(PIN_SCE, HIGH);
}
// gotoXY routine to position cursor
// x - range: 0 to 84
// y - range: 0 to 5
void gotoXY(int x, int y)
{
LcdWrite( 0, 0x80 | x); // Column.
LcdWrite( 0, 0x40 | y); // Row.
}
char * floatToString(char * outstr, double val, byte precision, byte widthp){
char temp[16];
byte i;
// compute the rounding factor and fractional multiplier
double roundingFactor = 0.5;
unsigned long mult = 1;
for (i = 0; i < precision; i++)
{
roundingFactor /= 10.0;
mult *= 10;
}
temp[0]='\0';
outstr[0]='\0';
if(val < 0.0){
strcpy(outstr,"-\0");
val = -val;
}
val += roundingFactor;
strcat(outstr, itoa(int(val),temp,10)); //prints the int part
if( precision > 0) {
strcat(outstr, ".\0"); // print the decimal point
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision--)
mult *=10;
if(val >= 0)
frac = (val - int(val)) * mult;
else
frac = (int(val)- val ) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10)
padding--;
while(padding--)
strcat(outstr,"0\0");
strcat(outstr,itoa(frac,temp,10));
}
// generate space padding
if ((widthp != 0)&&(widthp >= strlen(outstr))){
byte J=0;
J = widthp - strlen(outstr);
for (i=0; i< J; i++) {
temp[i] = ' ';
}
temp[i++] = '\0';
strcat(temp,outstr);
strcpy(outstr,temp);
}
return outstr;
}
void drawLine(void)
{
unsigned char j;
for(j=0; j<84; j++) // top
{
gotoXY (j,0);
LcdWrite (1,0x01);
}
for(j=0; j<84; j++) //Bottom
{
gotoXY (j,5);
LcdWrite (1,0x80);
}
for(j=0; j<6; j++) // Right
{
gotoXY (83,j);
LcdWrite (1,0xff);
}
for(j=0; j<6; j++) // Left
{
gotoXY (0,j);
LcdWrite (1,0xff);
}
}
float VoltageToPPM(float voltage)
{
return pow(b_k, voltage)/a_k;
}
void setup(void)
{
//analogReference(INTERNAL);
LcdInitialise();
LcdClear();
gotoXY(0,0);
if (pressure.begin())
LcdString("BMP180 init success");
else
{
// Oops, something went wrong, this is usually a connection problem,
// see the comments at the top of this sketch for the proper connections.
LcdString("BMP180 init fail\n\n");
while(1); // Pause forever.
}
dht.begin();
}
void loop(void)
{
sensorValue = analogRead(sensorPin);
delay(50);
sensorValue = analogRead(sensorPin);
delay(50);
char buf[20];
float value=sensorValue*adc_step;
gotoXY(0,0);
LcdString("CO2:");
LcdString(floatToString(buf, VoltageToPPM(value),1,5));
LcdString("ppm");
gotoXY(0,1);
LcdString("CO2 V:");
LcdString(floatToString(buf, value,4,5));
gotoXY(0,2);
delay(50);
sensorValue = analogRead(vBattPin);
delay(50);
sensorValue = analogRead(vBattPin);
value=sensorValue*adc_step;
LcdString("V batt:");
LcdString(floatToString(buf, value,3,4));
// static bool led_on_off=true;
// digitalWrite(ledPin, led_on_off);
// led_on_off=!led_on_off;
char status;
double T,P,p0,a;
// Loop here getting pressure readings every 10 seconds.
// If you want sea-level-compensated pressure, as used in weather reports,
// you will need to know the altitude at which your measurements are taken.
// We're using a constant called ALTITUDE in this sketch:
// If you want to measure altitude, and not pressure, you will instead need
// to provide a known baseline pressure. This is shown at the end of the sketch.
// You must first get a temperature measurement to perform a pressure reading.
// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.
status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
//gotoXY(0,3);
// LcdString("temp: ");
//LcdString(floatToString(buf, T,1,4));
// LcdString(" C");
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startPressure(2);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.
status = pressure.getPressure(P,T);
if (status != 0)
{
// Print out the measurement:
gotoXY(0,5);
//lcd.print("ap ");
LcdString(floatToString(buf, P*0.7501,1,4));
//lcd.print(" mb");
// The pressure sensor returns abolute pressure, which varies with altitude.
// To remove the effects of altitude, use the sealevel function and your current altitude.
// This number is commonly used in weather reports.
// Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
// Result: p0 = sea-level compensated pressure in mb
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
LcdString("-");
LcdString(floatToString(buf, p0*0.7501,1,4));
//Serial.print(" mb, ");
//Serial.print(p0*0.0295333727,2);
//Serial.println(" inHg");
// On the other hand, if you want to determine your altitude from the pressure reading,
// use the altitude function along with a baseline pressure (sea-level or other).
// Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.
// Result: a = altitude in m.
a = pressure.altitude(P,p0);
}
else LcdString("error retrieving pressure measurement\n");
}
else LcdString("error starting pressure measurement\n");
}
else LcdString("error retrieving temperature measurement\n");
}
else LcdString("error starting temperature measurement\n");
float h = dht.readHumidity();
float t = dht.readTemperature();
gotoXY(0,4);
if (isnan(t) || isnan(h)) {
LcdString("Failed to read from DHT");
}
else{
LcdString(floatToString(buf, h,1,4));
LcdString("%");
}
gotoXY(0,3);
LcdString("temp: ");
LcdString(floatToString(buf, t,1,4));
LcdString(" C");
delay(1000);
}