Вдоволь наигравшись с датчиками температуры и влажности серии DHT, я решил больше никогда их не использовать в сколько-нибудь серьезных проектах. Слишком уж ненадежно их использование. Датчики младшей серии DHT11 выдают подозрительные результаты, далеко не всегда точные, а старшие братья из разряда DHT22 хоть и точны, но с завидной периодичностью начинают подвисать, выдавая невероятные значения в виде отрицательной влажности. Хотя последнее утверждение можно отнести скорее не к самим датчикам, а вероятнее к сложным алгоритмам получения данных с сенсоров либо «аппаратным» проблемам конкретных чипов.
По моему глубокому убеждению, использовать DHT можно только в обучающих проектах, в стиле собрал, посмотрел что работает, порадовался, разобрал и забыл. А вот если хочется реализовать хоть что-то немного более сложное, нежели просто измерение температуры и влажности на протяжении десятка минут, то стоит обратить внимание на более совершенные устройства. Ниже я поделюсь крошечным опытом использования датчиков SHT1x, установленных на плату от RobotDyn.
Начну с того, что сами сенсоры SHT1x производятся компанией Sensirion. И соответственно индекс датчика расшифровывается примерно следующим образом: Sensirion Humidity Temperature. А 1x означает стандартную версию датчика первого поколения. Впрочем, производитель выпускает SHT10, в качестве очень дешевой версии сенсора, видимо, в нее попадают изделия не прошедшие строгое тестирование и имеющие меньшую точность, а SHT15 относится к уровню Hi-End, стоит дороже, но показания выдает точнее. Впрочем, различия между показаниями между этими сенсорами минимально и гоняться за более дорогими явно не стоит, благо даже стандартная версия по карману не бьет, а точность обеспечивает достаточную.
Кстати, сами датчики бывают в исполнении для поверхностного монтажа, такой монтаж применяется в промышленном производстве. Но присутствует и версия с ножками, для радиолюбительской пайки. Маркируется она как SHT7x (и соответственно SHT70, SHT75). Тем не менее, если вы не ас в пайке, то приобретать стоит уже готовую платку для подключения к Arduino и прочим микроконтроллерам, поскольку в этом случае вам не придется заниматься ненужным подбором обвязки для сенсора.
Огромным преимуществом датчиков от Sensirion, в том числе и SHT1x, я могу смело назвать то, что каждый из выпускаемых датчиков проходит индивидуальную калибровку. И конечному пользователю нет необходимости бегать с тазиком воды и бубном вокруг сенсора в попытках получить от него хоть какое-то вменяемое показание. На производстве, в контролируемых условиях, в ПЗУ сенсора загружаются калибровочные показания и впоследствии он использует их как поправку при определении влажности и температуры. Все же у цифровых устройств есть свои, неоспоримые, преимущества.
Для измерения влажности в сенсоре применяется емкостная технология (не резистивная!), а для температуры использован метод похитрее. В основе измерения температуры в сенсорах SHT лежит принцип изменения запрещенной зоны полупроводника (bandgap) в зависимости от температуры. Многие компьютерные энтузиасты в курсе, что некоторые кремневые чипы в «персоналках» необходимо очень активно охлаждать. И если не предпринимать никаких мер, то при нагреве свыше критической температуры устройство просто перестает работать. Причина подобного поведения электроники состоит в том, что при превышении порога в полупроводниках к электронно-дырочной проводимости присоединяется еще и тепловая проводимость, когда электроны туннелируют через запрещенную зону из-за интенсивных тепловых колебаний. Насколько я помню со студенческих времен, для кремния предельная температура около 120 градусов Цельсия, а для германия в районе 80 градусов. Но не суть. Для измерения температуры в сенсоре применяется схема на кремниевом диоде и происходит измерение прямого напряжения. Которое впоследствии пересчитывается в температуру по мудреной формуле.
Для получения данных с сенсора SHT1x можно применить только один способ — считать данные через последовательный порт (он же UART, он же SBUS, он же Serial Port). Плата с сенсором подключается через четыре контакта: питание (Vin), земля (Gnd), «часы» (Scl) и данные (Sda). Программная реализация последовательного порта в среде Arduino уже включена в стандарт. Однако, для облегчения использования датчиков созданы, в том числе, классы оболочки, позволяющие подключать и использовать SHT1x за пару кликов мышкой. Для проверки я использовал библиотеку SHT1x от practicalarduino.
Пример вывода данных с двух сенсоров DHT1x:
Sht1x - 1 Temperature: 27.8499984741C Humidity: 42.09% Sht1x - 2 Temperature: 26.5599975586C Humidity: 43.63% Sht1x - 1 Temperature: 27.8799972534C Humidity: 42.70% Sht1x - 2 Temperature: 26.5899963379C Humidity: 43.97% Sht1x - 1 Temperature: 27.8699951172C Humidity: 42.64% Sht1x - 2
Более совершенные сенсоры от Sensirion могут работать в том числе и с I2C или PWM, но в нашем случае придется ограничиться последовательной передачей данных. На контакт Scl подается тактовая частота, а по Sda происходит обмен данных. В теории и на практике, при подключении сразу двух сенсоров к одной плате, можно сэкономить один порт. Контакты Scl от двух датчиков можно смело подключить к одному порту, не позабыв указать его при создании двух объектов класса датчик SHT1x. Что я с успехом и проделал.
Ну и в завершение, хочу отметить, что переход от DHT к SHT оказался настолько качественным, что возвращаться к DHT нет никакого желания. Даже скорее наоборот, я смотрю уже на датчики с реализацией I2C, как на возможное использование в еще более сложных проектах, где упираешься в ограничение, связанное с количеством свободных портов на плате контроллера.
#include <SHT1x.h>; // Sensor 1 #define dataPin D1 #define clockPin D2 SHT1x sht1x(dataPin, clockPin); // Sensor 2 #define dataPin2 D5 #define clockPin2 D2 SHT1x sht2x(dataPin2, clockPin2); void setup() { // put your setup code here, to run once: Serial.begin(38400); // Open serial connection to report values to host Serial.println("Starting up"); } void loop() { // put your main code here, to run repeatedly: float temp_c; float humidity; // Read values from the sensor temp_c = sht1x.readTemperatureC(); humidity = sht1x.readHumidity(); // Print the values to the serial port Serial.println("Sht1x - 1"); Serial.print("Temperature: "); Serial.print(temp_c, DEC); Serial.print("C"); Serial.print(" Humidity: "); Serial.print(humidity); Serial.println("%"); delay(2000); temp_c = sht2x.readTemperatureC(); humidity = sht2x.readHumidity(); Serial.println("Sht1x - 2"); Serial.print("Temperature: "); Serial.print(temp_c, DEC); Serial.print("C"); Serial.print(" Humidity: "); Serial.print(humidity); Serial.println("%"); delay(2000); }