#include <Wire.h>
// HTU21D (модуль GY-21) на I2C. Библиотека не нужна: у датчика всего
// несколько команд, и вся работа видна в скетче.
//
// Алгоритм один на оба измерения:
// 1. послать команду «измерь» (0xF3 — температура, 0xF5 — влажность);
// 2. подождать: измерение занимает до 50 мс, и раньше времени датчик
// не отвечает;
// 3. прочитать три байта: старший, младший и контрольную сумму CRC-8;
// 4. сверить сумму и пересчитать число по формуле из даташита.
const uint8_t HTU21D = 0x40;
const uint8_t CMD_TEMPERATURE = 0xF3;
const uint8_t CMD_HUMIDITY = 0xF5;
uint8_t crc8(uint8_t msb, uint8_t lsb) {
// Многочлен датчика x^8 + x^5 + x^4 + 1 (0x131), начальное значение 0.
uint16_t crc = 0;
uint8_t data[2] = {msb, lsb};
for (int i = 0; i < 2; i++) {
crc ^= data[i];
for (int bit = 0; bit < 8; bit++) {
crc = (crc & 0x80) ? ((crc << 1) ^ 0x131) : (crc << 1);
}
}
return crc & 0xFF;
}
// Возвращает false, если датчик не ответил или сумма не сошлась.
bool measure(uint8_t command, uint16_t &raw) {
Wire.beginTransmission(HTU21D);
Wire.write(command);
if (Wire.endTransmission() != 0) return false;
delay(60);
if (Wire.requestFrom((int)HTU21D, 3) != 3) return false;
uint8_t msb = Wire.read();
uint8_t lsb = Wire.read();
uint8_t crc = Wire.read();
if (crc8(msb, lsb) != crc) return false;
// Два младших бита — служебные, перед пересчётом их обнуляют.
raw = ((uint16_t)msb << 8) | (lsb & 0xFC);
return true;
}
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
uint16_t rawT, rawH;
if (!measure(CMD_TEMPERATURE, rawT) || !measure(CMD_HUMIDITY, rawH)) {
Serial.println(F("датчик не ответил: проверьте A4, A5 и питание"));
delay(2000);
return;
}
float t = -46.85 + 175.72 * rawT / 65536.0;
float h = -6.0 + 125.0 * rawH / 65536.0;
h = constrain(h, 0.0, 100.0); // у границ формула может чуть выйти за 0..100
Serial.print("t:");
Serial.print(t, 2);
Serial.print(" h:");
Serial.println(h, 1);
delay(2000);
}
Arduino Uno: HTU21D по I2C без библиотеки
Температура и влажность двумя командами по I2C. Контрольная сумма проверяется в скетче, чтобы сбой на шине не стал показанием.
Что на схеме
Плата Arduino Uno, к ней подключены:
- Датчик HTU21D: температура и влажность (I2C) —
htu1, влажность 45 %, температура 23 °C
Задействованы выводы платы: 5V, GND, A4, A5. Всего соединений на схеме: 4.
Библиотеки
Пример собирается с библиотеками:
- Wire
Они уже установлены на сервере сборки — отмечать их в проекте вручную не нужно, список приезжает вместе с примером.
Как это устроено в коде
Основное, чем пользуется скетч:
delay()— пауза, на время которой ядро занято ожиданиемSerial.begin()— открывает монитор порта на заданной скоростиWire.begin()— поднимает шину I²C, по ней говорят датчики и дисплеиSerial.println()— печатает строку в монитор портаconstrain()— зажимает значение в границах
В скетче 71 строка; свои функции: crc8(), measure(); подключено заголовков: 1. Сам скетч открыт на соседней вкладке — его можно менять и запускать заново.
Что попробовать изменить
- Замените
delay()на счёт поmillis()— иloop()освободится для всего остального, что должно происходить одновременно. - Добавьте свои
Serial.println()в интересных местах — монитор порта здесь и есть отладчик. - Перенесите деталь на другой вывод — на схеме и в коде — и убедитесь, что пример работает так же.
- Нажмите «Форкнуть»: копия станет вашим проектом, и в ней можно менять что угодно.
Смотрите также
- Подключение датчика HTU21D — Цифровой датчик температуры и влажности (I2C)
- Arduino Uno: датчик движения HC-SR501 — Выход датчика цифровой: движение — высокий уровень. Свет включается по движению и гаснет через несколько секунд тишины…
- Arduino Uno: сенсорная кнопка TTP223 — Пока палец на площадке, выход высокий. Скетч ловит момент касания и каждым касанием переключает светодиод.
- Arduino Uno: датчик влажности почвы — Чем влажнее почва, тем ниже напряжение на AO. Скетч переводит отсчёты АЦП в проценты и зажигает светодиод, когда горшок…
- Arduino Uno: датчик газа MQ-2 — Чем больше газа, тем выше напряжение на AO. Сигнал включается при высоком пороге и выключается только при заметно более…
- Arduino Uno: термометр LM35 — 10 мВ на градус: напряжение на выходе, делённое на 0,01 В, и есть температура. Восемь замеров усредняются.
- Arduino Uno: джойстик KY-023 — Две оси на аналоговых входах и кнопка с внутренней подтяжкой. Вокруг центра оставлена мёртвая зона.
Сборка ещё не запускалась.
Печатайте в Serial числа — они станут графиком.
Serial.println(t); — один ряд,
Serial.printf("t:%.1f h:%.1f\n", t, h); — два с подписями.
Формат тот же, что понимает плоттер Arduino IDE.