Датчик температуры и влажности, i2c (Metro-модуль) - Datasheet

Модуль Metro - Датчик температуры и влажности.

Техническое описание: Данная страница содержит подробное техническое описание модуля и раскрывает работу с модулем через его регистры.

Ознакомиться с пользовательским описанием модуля и примерами работы с библиотекой iarduino_Metro можно на странице Wiki - Датчик температуры и влажности (Metro-модуль).

Назначение:

Модуль Metro - Датчик температуры и влажности - является цифровым датчиком с подключением по шине I2С.

К одной шине I2C можно подключить более 100 модулей.

Модуль можно использовать в любых проектах где требуется датчик температуры и влажности, например, в метеостанциях, термометрах, гигрометрах, умных теплицах, увлажнителях воздуха, для контроля условий хранения складах и т.д.

Описание:

Модуль построен на базе цифрового датчика влажности и температуры AM2320, микроконтроллера STM32F030F4 и снабжен собственный стабилизатором напряжения. Модуль считывает значения с датчика и сохраняет данные в своих регистрах. Доступ к регистрам модуля осуществляется по шине I2C.

С помощью регистров модуля можно:

  • Изменить адрес данного модуля, обнаружить наличие следующего модуля и изменить адрес следующего модуля.
  • Определить относительную влажность воздуха в %.
  • Определить температуру воздуха в °С.
  • Определить событие - влажность изменилась на заданное значение.
  • Определить событие - температура изменилась на заданное значение.
  • Задать значение влажности при изменении на которую установится флаг события - влажность изменилась.
  • Задать значение температуры при изменении на которую установится флаг события - температура изменилась.
  • Задать период обновления значений влажности и температуры.

Выводы модуля:

У модуля имеются две колодки выводов: IN - штыревой разъем (вход модуля) и OUT гнездовой разъем (выход для подключения входа следующего модуля Metro). На каждой колодке имеется по пять выводов:

  • SCL - вход/выход линии тактирования шины I2C.
  • SDA - вход/выход линии данных шины I2C.
  • 5V - вход питания.
  • GND - общий вывод питания.
  • ADR (на колодке IN) - вход установки адреса данного модуля.
  • ADR (на колодке OUT) - вывод (вход/выход) обнаружения следующего модуля и установки его адреса.

Выводы SCL, SDA, 5V и GND внутрисхемно соединены с одноимёнными выводами колодок IN и OUT, и предназначены для передачи данных по шине I2C. Выводы SCL и SDA внутрисхемно НЕ подтянуты в модуле до уровня логической 1.

Вход ADR на колодке IN используется для сброса/записи адреса модуля на шине I2C. Данный вход внутрисхемно прижат к GND через резистор номиналом в 1 кОм. Если на вход ADR подать уровень логической 1, то адрес модуля сбросится в значение по умолчанию 0x09, но этот адрес не сохранится во FLASH памяти модуля, а значит после отключения питания, установится прежний адрес. Если при наличии логической 1 на входе ADR, записать адрес в регистр «ADDRESS» с установленным битом «IF_PIN_ADDRESS» то данный адрес станет новым адресом модуля на шине I2C и сохранится во FLASH памяти модуля, а значит сохранится и после отключения питания.

Вывод ADR на колодке OUT является двунаправленным выводом и используется для обнаружения наличия следующего модуля Metro, а также сброса/записи адреса следующего модуля. Данный вывод внутрисхемно подтянут до уровня 3,3 В через резистор в 100 кОм, что позволяет определить наличие следующего модуля Metro. Если вывод сконфигурирован как вход и на нём уровень логической 1 (3,3 В) - значит следующих модулей нет, а если на нём уровень логического 0 (GND) - значит следующий модуль есть. Если вывод сконфигурирован как выход, то установив на нём уровень логической 1 можно сбросить/записать адрес следующего модуля.

Конфигурация, чтение и установка уровней выводов ADR осуществляется через регистры модуля.

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

  • Напряжение питания: 5 В (постоянного тока)
  • Потребляемый ток: до 15 мА.
  • Диапазон измерений влажности: от 0 до 100 %.
  • Диапазон измерений температуры: от -40 до +80 °С.
  • Интерфейс: I2C.
  • Скорость шины I2C: 100 кбит/с.
  • Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
  • Уровень логической 1 на линиях шины I2C: 3,3 В (толерантны к 5 В).
  • Уровень логической 1 на выводах ADR: 3,3 В (толерантны к 5 В).
  • Рабочая температура: от -40 до +85 °С.
  • Габариты: 35,56 х 25,40 мм (1400 x 1000 mil).
  • Вес: 5 г.

Установка адреса:

Сброс адреса (без сохранения):

Если физически подать уровень логической 1 на вход модуля ADR, то адрес модуля сбросится в значение по умолчанию 0x09, но этот адрес не сохранится во FLASH памяти, а значит после отключения питания, установится прежний адрес модуля.

Установка адреса (без сохранения):

Если в регистр 0x06 «ADDRESS» записать значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 0, то указанный адрес станет адресом модуля на шине I2C, но он не сохранится во FLASH памяти, а значит после отключения питания, установится прежний адрес модуля.

Установка адреса (с сохранением):

Для установки адреса с его сохранением в FLASH память модуля необходимо выполнить два действия:

  • Установить уровень логической 1 на входе ADR колодки IN (при этом адрес модуля сбросится в значение по умолчанию 0x09), или установить в 1 бит «SET_PIN_ADDRES» в регистре 0x01 «BITS_0» (при этом адрес модуля останется прежним).
  • Записать в регистр 0x06 «ADDRESS» значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 1. ВАЖНО: запись адреса занимает не менее 30 мс.

Если в регистр 0x06 «ADDRESS» записать значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 1, при сброшенном бите «SET_PIN_ADDRES» и наличии уровня логического 0 на входе ADR, то указанный адрес проигнорируется и у модуля останется прежний адрес.

Обнаружение следующего модуля:

Модули Metro подключаются друг к другу (вход к выходу) как вагоны метро.

Вход ADR колодки IN внутрисхемно прижат к GND через резистор 1 кОм, значит если данный вход ни к чему не подключён, то на нем присутствует уровень логического 0.

Вывод ADR колодки OUT внутрисхемно подтянут к 3,3 В через резистор 100 кОм, значит если данный вывод сконфигурирован как вход и ни к чему не подключен, то на нем присутствует уровень логической 1.

Следовательно, если вывод ADR колодки OUT сконфигурирован как вход и на нём присутствует уровень логической 1, значит колодка OUT свободна, а если присутствует уровень логического 0, значит к колодке OUT подключена колодка IN следующего модуля.

За конфигурацию вывода ADR колодки OUT отвечает бит «SET_PIN_OUTPUT» регистра 0x01 «BITS_0», а считать логический уровень с этого входа можно через флаг «GET_PIN_OUTPUT» регистра 0x00 «FLAGS_0».

Значит для обнаружения модуля нужно сбросить бит «SET_PIN_OUTPUT» в регистре 0x01 «BITS_0» и считать бит «GET_PIN_OUTPUT» из регистра 0x00 «FLAGS_0». Если считана 1 значит колодка OUT свободна (следующих модулей нет), а если считан 0, значит к колодке OUT подключен следующий модуль.

Регистры:

Карта регистров модуля:

адрес76 5 4 3 2 10
0x00 FLG_RESET FLG_SELF_TEST - - - - GET_PIN_ADDRES GET_PIN_OUTPUT
0x01 SET_RESET SET_SELF_TEST - - - - SET_PIN_ADDRES SET_PIN_OUTPUT
0x02
0x03
RESERVED
0x04 MODEL[7-0]
0x05 VERSION[7-0]
0x06 ADDRESS[6-0] IF_PIN_ADDRES
0x07 CHIP_ID[7-0]
0x08 PERIOD[7-0]
0x09
---
0x0F
RESERVED
0x10 - - - - - CHANGED-HUM CHANGED-TEM CHANGED
0x11 TEM[7-0]
0x12 NEGATIVE TEM[14-8]
0x13
0x14
HUM[7-0]
HUM[15-8]
0x15 TEM_CHANGE[7-0]
0x16 HUM_CHANGE[7-0]

Регистры с адресами 0x02, 0x03, 0x09 - 0x0F зарезервированы, их биты сброшены в 0. Попытка записи данных в эти регистры будет проигнорирована модулем.

Регистр 0x00 «FLAGS_0» - содержит флаги чтения состояния модуля:

Регистр только для чтения.

  • FLG_RESET - Флаг указывает на факт выполнения успешной перезагрузки модуля. Флаг самостоятельно сбрасывается после чтения регистра 0x00 «FLAGS_0».
  • FLG_SELF_TEST - Флаг указывает на результат выполнения самотестирования модуля (0-провал, 1-успех). Не поддерживается данным модулем.
  • GET_PIN_ADDRES - Бит повторяет логический уровень считанный со входа ADR колодки IN модуля.
  • GET_PIN_OUTPUT - Бит повторяет логический уровень считанный с вывода ADR колодки OUT модуля.

Регистр 0x01 «BITS_0» - содержит биты установки состояния модуля:

Регистр для записи и чтения.

  • SET_RESET - Бит запускает программную перезагрузку модуля. О завершении перезагрузки свидетельствует установка флага «FLG_RESET» регистра 0x00 «FLAGS_0».
  • SET_SELF_TEST - Бит запускает самотестирование модуля. При успешном завершении самотестирования устанавливается флаг «FLG_SELF_TEST » регистра 0x00 «FLAGS_0». Не поддерживается данным модулем.
  • SET_PIN_ADDRES - Бит является альтернативой входа ADR колодки IN. Установка бита в 1 расценивается как наличие логической 1 на входе ADR колодки IN, но не устанавливает этот уровень физически на входе, что позволяет установить и сохранить адрес модуля во FLASH память не используя вход ADR. Бит самостоятельно сбрасывается после сохранения адреса во FLASH память. Установка бита в 1 не сбрасывает адрес модуля в значение по умолчанию (0x09), как это делает физическая «1» на входе ADR колодки IN.
  • SET_PIN_OUTPUT - Бит конфигурации вывода ADR колодки OUT. Установка бита в 1 сконфигурирует вывод ADR колодки OUT модуля в режим выхода и установит на нём уровень логической 1. Сброс бита в 0 сконфигурирует вывод ADR колодки OUT в режим входа, логический уровень которого можно считать через бит «GET_PIN_OUTPUT» регистра 0x00 «FLAGS_0».

Регистр 0x04 «MODEL» - содержит идентификатор типа модуля:

Регистр только для чтения.

Регистр 0x05 «VERSION» - содержит версию прошивки модуля:

Регистр только для чтения.

  • VERSION[7-0] - Версия прошивки (от 0x01 до 0xFF).

Регистр 0x06 «ADDRESS» - отвечает за чтение/установку адреса модуля на шине I2C:

Регистр для чтения и записи.

  • ADDRESS[6-0] - 7 бит адреса модуля на шине I2C. При чтении возвращается текущий адрес модуля, при записи устанавливается указанный адрес модулю.
  • IF_PIN_ADDRES - Флаг проверки состояния входа ADR колодки IN для записи адреса в FLASH память модуля.
    При чтении регистра, флаг указывает на то, что адрес ADDRESS[6-0] считан из Flash памяти.
    При записи в регистр:
    Если флаг сброшен, то адрес в битах ADDRESS[6-0] будет установлен временно (до отключения питания, или сброса/записи нового адреса). Если флаг «IF_PIN_ADDRES» установлен, то адрес в битах ADDRESS[6-0] будет сохранён в FLASH память модуля (останется и после отключения питания), но только если на входе ADR колодки IN, или в бите «SET_PIN_ADDRES» регистра 0x01 «BITS_0» установлена логическая 1. Если флаг «IF_PIN_ADDRES» установлен, бит «SET_PIN_ADDRES» сброшен и на входе ADR колодки IN установлен уровень логического 0, то адрес в битах ADDRESS[6-0] не будет установлен ни временно, ни постоянно.

Регистр 0x07 «CHIP_ID» - содержит идентификатор общий для всей линейки Metro:

Регистр только для чтения.

У всех модулей линейки метро в регистре «CHIP_ID» содержится значение 0xC3. Если требуется отличить модули Metro на шине I2C от сторонних модулей, то достаточно прочитать значение регистров 0x06 «ADDRESS» и 0x07 «CHIP_ID» всех модулей на шине I2C. Если 7 старших битов регистра 0x06 «ADDRESS» хранят адрес совпадающий с адресом модуля, а в регистре 0x07 «CHIP_ID» хранится значение 0xC3, то можно с большой долей вероятности утверждать, что данный модуль является модулем Metro.

Регистр 0x08 «PERIOD» - содержит время обновления данных:

Регистр только для записи.

PERIOD[7-0] - Время обновления показаний датчика AM2320 в десятых долях секунд от 0 (0 сек.) до 255 (25,5 сек.). Значение по умолчанию 30 (3,0 сек.). Это время по истечении которого микроконтроллер модуля Metro опрашивает датчик AM2320 и, следовательно, обновляет свои регистры. В соответствии с описанием датчика AM2320 не рекомендуется устанавливать период его опроса ниже 3 секунд.

Регистр 0x10 «REG_DATA» - содержит флаги событий:

Регистр только для чтения.

  • CHANGED-HUM - Флаг события смены влажности. Устанавливается если показания влажности изменились более чем на «HUM_CHANGE» % после последней установки флага. Флаг «CHANGED-HUM» сбрасываются самостоятельно после чтения данного регистра.
  • CHANGED-TEM - Флаг события смены температуры. Устанавливается если показания температуры изменились более чем на «TEM_CHANGE» °C после последней установки флага. Флаг «CHANGED-TEM» сбрасываются самостоятельно после чтения данного регистра.
  • CHANGED - Флаг события смены влажности или температуры. Флаг сбрасывается самостоятельно после чтении данного регистра.
    ( «CHANGED» = «CHANGED-HUM» | «CHANGED-TEM» ).

Регистры 0x11 и 0x12 «TEM» - содержат значение температуры в десятых долях °С:

Регистры только для чтения.

  • TEM[7-0] - Младший байт температуры (доступен для чтения из регистра 0x11).
  • TEM[14-8] - Старший байт температуры (доступен для чтения из регистра 0x12).
  • NEGATIVE - Флаг отрицательной температуры (старший бит регистра 0x12).
    Данные температуры хранятся в десятых долях °C, от -400 (-40,0°С) до 800 (80,0°С).
    Температура = ( ( (TEM[14-8] << 8) + TEM[7-0] ) / 10 ) °С.
    if ( NEGATIVE ){ Температура = -Температура }

Регистры 0x13 и 0x14 «HUM» - содержат значение влажности в десятых долях %:

Регистры только для чтения.

  • HUM[7-0] - Младший байт влажности (доступен для чтения из регистра 0x13).
  • HUM[15-8] - Старший байт влажности (доступен для чтения из регистра 0x14).
    Данные влажности хранятся в десятых долях %, от 0 (0,0%) до 1000 (100,0%).
    Влажность = ( ( (HUM[15-8] << 8) + HUM[7-0] ) / 10 ) %.

Регистр 0x15 «TEM_CHANGE» - содержит диапазон температуры для флага CHANGED-TEM:

Регистр для чтения и записи.

  • TEM_CHANGE[7-0] - Диапазон температуры в десятых долях °С. Изменение температуры воздуха на значение превышающее указанное в настоящем регистре, приведёт к установке флага «CHANGED-TEM».

    Регистр 0x16 «HUM_CHANGE» - содержит диапазон влажности для флага CHANGED-HUM:

    Регистр для чтения и записи.

    • HUM_CHANGE[7-0] - Диапазон влажности в десятых долях %. Изменение влажности воздуха на значение превышающее указанное в настоящем регистре, приведёт к установке флага «CHANGED-HUM».

    Доступ к данным регистров:

    Каждый регистр модуля хранит 1 байт данных. Так как модуль использует интерфейс передачи данных I2C, то и доступ к данным охарактеризован им.

    Обмен данными по шине I2C происходит по одному биту за один такт, после каждых переданных 8 бит (1 байта) принимающее устройство отвечает передающему одним битом: «ACK» в случае успешного приёма, или «NACK» в случае ошибки. Пакет приёма/передачи данных начинается сигналом «START» и завершается сигналом «STOP». Первый байт пакета всегда состоит из 7 бит адреса устройства и одного (младшего) бита R/W.

    Сигналы интерфейса передачи данных I2C:

      Для удобства восприятия сигналов они выполнены в следующих цветах:
    • Зелёный - сигналы формируемые мастером.
    • Красный - данные отправляемые мастером.
    • Синий - данные отправляемые модулем Metro.
    • Фиолетовый - данные отправляемые мастером или модулем Metro.
    • «START» - отправляется мастером в начале пакета приема/передачи данных. Сигнал представляет переход уровня линии «SDA» из «1» в «0» при наличии «1» на линии «SCL».
    • «STOP» - отправляется мастером в конце пакета приёма/передачи данных. Сигнал представляет переход уровня линии «SDA» из «0» в «1» при наличии «1» на линии «SCL».
    • БИТ - значение бита считывается с линии «SDA» по фронту импульса на линии «SCL».
    • «ACK» - бит равный 0, отправляется после успешного приёма байта данных.
    • «NACK» - бит равный 1, отправляется после байта данных в случае ошибки.
    • ПЕРВЫЙ БАЙТ - отправляется мастером, состоит из 7 бит адреса и бита «RW».
    • «R/W» - младший бит первого байта данных указывает направление передачи данных пакета, 1 - прием (от модуля к мастеру), 0 - передача (от мастера в модуль).
    • «RESTART» - повторный старт, отправляется мастером внутри пакета. Сигнал представляет из себя «START» отправленный не на свободной шине, а внутри пакета.

    ВАЖНО: Все изменения на линии «SDA» должны происходить только при наличии «0» на линии «SCL» за исключением сигналов «START», «STOP» и «RESTART».

      Запись данных в регистры:

      • Отправляем сигнал «START».
      • Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
        Получаем ответ от модуля в виде одного бита «ACK».
      • Отправляем второй байт: адрес регистра в который будет произведена запись.
        Получаем ответ от модуля в виде одного бита «ACK».
      • Отправляем третий байт: данные для записи в регистр.
        Получаем ответ от модуля в виде одного бита «ACK».
      • Далее можно отправить четвёртый байт данных для записи в следующий по порядку регистр и т.д.
      • Отправляем сигнал «STOP».

      Пример записи в один регистр:

      Запись значения 0x2A в регистр 0x06 модуля с адресом 0x09:

                                       // Запись в регистр методами библиотеки Wire.h
      Wire.beginTransmission(0x09);    // Инициируем передачу данных в устройство с адресом 0x09.
      Wire.write(0x06);                // Записываем в буфер байт адреса регистра.
      Wire.write(0x26);                // Записываем в буфер байт который будет записан в регистр.
      Wire.endTransmission();          // Выполняем передачу адреса и байтов из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
      

      Пример записи в несколько регистров подряд:

      Запись в модуль с адресом 0x09 нескольких значений начиная с регистра 0x12:
      В регистр 0x12 запишется значение 0x0F, в следующий по порядку регистр (0x13) запишется значение 0x30 и в следующий по порядку регистр (0x14) запишется значение 0xB1.

                                       // Запись в регистры методами библиотеки Wire.h
      byte data[3] = {0x0F,0x30,0xB1}; // Определяем массив с данными для передачи.
      Wire.beginTransmission(0x09);    // Инициируем передачу данных в устройство с адресом 0x09.
      Wire.write(0x12);                // Записываем в буфер байт адреса первого регистра.
      Wire.write(data, 3);             // Записываем в буфер 3 байта из массива data.
      Wire.endTransmission();          // Выполняем передачу адреса и байт из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.

      Примечание: Так как в модуле Metro - Датчик температуры и влажности регистры 0x12, 0x13 и 0x14 предназначены только для чтения, то данные не будут записаны. При этом модуль не выдаст сообщение об ошибке записи.

      Чтение данных из регистров:

      • При чтении пакет делится на 2 части: запись № регистра и чтение его данных.
      • Отправляем сигнал «START».
      • Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
        Получаем ответ от модуля в виде одного бита «ACK».
      • Отправляем второй байт: адрес регистра из которого нужно прочитать данные.
        Получаем ответ от модуля в виде одного бита «ACK».
      • Отправляем сигнал «RESTART».
      • Отправляем первый байт после «RESTART»: 7 бит адреса и бит «R/W» равный 1 (чтение).
        Получаем ответ от модуля в виде одного бита «ACK».
      • Получаем байт данных из регистра модуля.
        Отвечаем битом «ACK» если хотим прочитать следующий регистр, иначе отвечаем «NACK».
      • Отправляем сигнал «STOP».

      Пример чтения одного регистра:

      Чтение из модуля с адресом 0x09 байта данных регистра 0x05:
      (в примере модуль вернул значение 0x01).

                                       // Чтение регистра методами библиотеки Wire.h
      byte data;                       // Объявляем переменную для чтения байта данных.
      Wire.beginTransmission(0x09);    // Инициируем передачу данных в устройство с адресом 0x09.
      Wire.write(0x05);                // Записываем в буфер байт адреса регистра.
      Wire.endTransmission(false);     // Выполняем передачу без установки состояния STOP.
      Wire.requestFrom(0x09, 1);       // Читаем 1 байт из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART.
      data=wire.read();                // Сохраняем прочитанный байт в переменную data.

      Пример чтения нескольких регистров подряд:

      Чтение из модуля с адресом 0x09 нескольких регистров начиная с регистра 0x05:
      (в примере модуль вернул значения: 0x01 из рег. 0x05, 0x13 из рег. 0x06, 0xC3 из рег. 0x07).

                                       // Чтение регистров методами библиотеки Wire.h
      byte data[3];                    // Объявляем массив для чтения данных.
      Wire.beginTransmission(0x09);    // Инициируем передачу данных в устройство с адресом 0x09.
      Wire.write(0x05);                // Записываем в буфер байт адреса регистра.
      Wire.endTransmission(false);     // Выполняем передачу без установки состояния STOP.
      Wire.requestFrom(0x09, 3);       // Читаем 3 байта из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART.
      int i=0;                         // Определяем счётчик номера прочитанного байта.
      while( Wire.available() ){       // Выполняем цикл while пока есть что читать из буфера.
        if(i<3){                       // Лучше делать такую проверку, чтоб не записать данные за пределы массива data!
          data[i] = wire.read(); i++;  // Читаем очередной байт из буфера в массив data.
        }                              //
      }                                //

      Примечание:

      • Если на линии I2C только один мастер, то сигнал «RESTART» можно заменить на сигналы «STOP» и «START».
      • Рекомендуется не выполнять чтение или запись данных чаще 200 раз в секунду.
        Обратите внимание на сигналы «RESTART» и «STOP» в пакетах чтения данных:
      • Между фронтом и спадом сигнала «RESTART» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 1.
      • Между сигналом «NACK» и сигналом «STOP» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 0.
      • Эти биты не сохраняются в модулях и не расцениваются как ошибки.

      Модуль не поддерживает горячее подключение: Подключайте модуль только при отсутствии питания и данных на шине I2C. В противном случае потребуется отключить питание при уже подключённом модуле.

      Пример чтения температуры и влажности:

      Следующий скетч демонстрирует пример вывода температуры и влажности в монитор последовательного порта.

      #include <Wire.h>                                // Подключаем библиотеку Wire для работы с шиной I2C.
      const int ADDRESS     = 0x09;                    // Определяем адрес модуля Metro - датчик температуры и влажности.
      const int REG_TEM     = 0x11;                    // Определяем адрес регистра TEM.
      const int NEGATIVE    = 7;                       // Определяем номер бита NEGATIVE в регистре TEM.
       uint16_t DATA;                                  // Объявляем переменную для хранения данных с регистров.
          float TEM;                                   // Объявляем переменную для хранения температуры.
          float HUM;                                   // Объявляем переменную для хранения влажности.
                                                       //
      void setup(){                                    //
          Serial.begin(9600);                          // Инициируем связь с монитором последовательного порта на скорости 9600 бит/сек.
          while(!Serial){;}                            // Ждём готовность к работе аппаратной шины UART.
          Wire.setClock(100000L);                      // Устанавливаем скорость передачи данных по шине I2C.
          Wire.begin();                                // Инициируем работу c шиной I2C в качестве мастера.
      }                                                //
                                                       //
      void loop(){                                     //
          Wire.beginTransmission(ADDRESS);             // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся.
          Wire.write(REG_TEM);                         // Функция write() помещает значение своего аргумента в буфер для передачи.
          Wire.endTransmission(false);                 // Выполняем инициированную ранее передачу данных (параметр false указывает что состояние STOP устанавливать не требуется).
          Wire.requestFrom(ADDRESS, 4);                // Читаем из модуля с адресом ADDRESS, 4 байта данных в буфер библиотеки Wire. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART.
                               DATA = 0;               // Чистим переменную DATA.
          if(Wire.available()){DATA|= Wire.read()    ;}// Если в буфере библиотеки Wire есть данные, то читаем байт как младший байт значения DATA.
          if(Wire.available()){DATA|=(Wire.read()<<8);}// Если в буфере библиотеки Wire есть данные, то читаем байт как старший байт значения DATA.
          bool f = DATA & bit(NEGATIVE+8);             // Определяем флаг отрицательной температуры.
          TEM = float( DATA & ~bit(NEGATIVE+8) ) / 10; // Сохраняем значение DATA как температуру в переменную TEM, без бита NEGATIVE.
          if(f){ TEM*=-1; }    DATA = 0;               // Добавляем знак температуры и чистим переменную DATA.
          if(Wire.available()){DATA|= Wire.read()    ;}// Если в буфере библиотеки Wire есть данные, то читаем байт как младший байт значения DATA.
          if(Wire.available()){DATA|=(Wire.read()<<8);}// Если в буфере библиотеки Wire есть данные, то читаем байт как старший байт значения DATA.
          HUM = float( DATA ) / 10;                    // Сохраняем значение DATA как влажность в переменную HUM.
          while( Wire.available() ){  Wire.read()    ;}// Если в буфере библиотеки Wire есть еще данные, то читаем их в никуда (чистим буфер).
          Serial.print("t=");                          //
          Serial.print(TEM);                           //
          Serial.print("°C, RH=");                     //
          Serial.print(HUM);                           //
          Serial.println("%.");                        //
          delay(1000);                                 //
      }                                                //

      Габариты:

      Ссылки:

      Обсуждение