Не останавливаясь на достигнутом, фирма Silicon Labs, практически одновременно выпустила несколько датчиков температуры и влажности второго поколения, среди которых Si7021.

Спецификация: Рабочее напряжение: 1.9-3.6 В (рекомендуем 3.3 В) Ток в режиме ожидания: 60nA Температурный диапазон:-40-85 °C (Рекомендуем 10-60 °C ) Точность температуры: ±0. 4 °C (-10 - 85 °C ) Диапазон влажности: 0-100% RH (рекомендуем 20%-80% RH) Точность влажности: ± 3% RH (0-80% RH) Время преобразования температуры: 7 мс Время преобразования влажности: 17 мс (RH измерения будет автоматически инициировать измерения температуры) Интерфейс: I2C

Применение: HVAC/R Термостаты Погодные станции Автомобильные системы климат-контроля и очищения.

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

Разработчики ввели новую команду 0xE0. Она позволяет считывать температуру, при которой производилось последнее измерение влажности. Для получения данных температуры и влажности надо подать команду измерения влажности, потом считать из датчика сырое (необработанное) значение влажности, и после подачи команды 0xE0 считать (сырое) значение температуры. Это позволяет сократить время проведения и чтения обоих измерений, когда датчик находится в активном режиме, в свою очередь, это способствует снижению токопотреблению.

После измерения и чтения параметра SI7021 автоматически входит в режим сна с низким токопотреблением.

Однако в целях уменьшения токопотребления чтение измеренных данных из датчика следует производить оперативно. Обусловлено это тем, что после окончания измерения датчик будет находиться в активном режиме пока результат измерения не будет прочитан микроконтроллером. Это относится к обоим режимам: с блокировкой SCL линии интерфейса I2C, и без блокировки.

У датчика Si7021 есть отличные перспективы применения его в различных Weather Shield. Датчики Si7020/21 могут быть установлены на платы, спроектированные для датчиков SHT20/21 фирмы Sensirion, где обеспечат более высокие показатели назначения и низкую стоимость.

Теперь посмотрим как нам подключить Si7021 допустим к Arduino Uno и проведем небольшой функциональный тест. Схема: У нас есть 3.3V I2C Si7020 и 5V Arduino UNO поэтому нам потребуется использовать двунаправленный конвертер логических уровней. Тестовый код:

/* Measurement of relative humidity and temperature using Si7021 */

#include

#define ADDRESS_SI7021 0x40

#define MEASURE_RH_HOLD 0xE5

#define READ_T_FROM_PRE_RH_MEASUREMENT 0xE0

byte buffer[] = {0, 0, 0};

byte crcHumi;

word outHumi = 0;

word outTemp = 0;

float valueHumi = 0;

float valueTemp = 0;

void setup()

{

Wire.begin();

Serial.begin(9600);

}

void loop()

{

//perform a RH measurement and read back the RH value

Wire.beginTransmission(ADDRESS_SI7021);

Wire.write(MEASURE_RH_HOLD);

Wire.endTransmission();

Wire.requestFrom(ADDRESS_SI7021, 3);

if(Wire.available() >= 3)

{

buffer[0] = Wire.read(); //high byte

buffer[1] = Wire.read(); //low byte

buffer[2] = Wire.read(); //crc

}

outHumi = (buffer[0]<<8) | buffer[1];

crcHumi = CRC8(buffer, 3);

//read temperature from previous RH measurement

Wire.beginTransmission(ADDRESS_SI7021);

Wire.write(READ_T_FROM_PRE_RH_MEASUREMENT);

Wire.endTransmission();

Wire.requestFrom(ADDRESS_SI7021, 2);

if(Wire.available() >= 2)

{

buffer[0] = Wire.read(); //high byte

buffer[1] = Wire.read(); //low byte; no crc

}

outTemp = (buffer[0]<<8) | buffer[1];

valueHumi = 125.0*outHumi/65536 - 6;

valueTemp = 175.72*outTemp/65536 - 46.85;

Serial.print(valueHumi); Serial.print(" \%RH\t");

Serial.print(valueTemp); Serial.println(" `C");

if (crcHumi == 0 && outHumi != 0 && outTemp != 0)

{

Serial.println("CRC checked.");

}

else

{

Serial.println("Error!");

}

delay(4000);

}

byte CRC8(byte *data, byte len)

{

byte crc[8];

byte result = 0;

byte i;

byte doInvert;

String bitString = MakeString(data, len);

for (i = 0; i < 8; i++)

{

crc[i] = 0;

}

for (i = 0; i < bitString.length(); i ++)

{

doInvert = (byte(bitString[i] == '1')) ^ crc[7];

crc[7] = crc[6];

crc[6] = crc[5];

crc[5] = crc[4] ^ doInvert;

crc[4] = crc[3] ^ doInvert;

crc[3] = crc[2];

crc[2] = crc[1];

crc[1] = crc[0];

crc[0] = doInvert;

}

for (i = 0; i < 8; i++)

{

bitWrite(result, i, crc[i]);

}

return result;

}

String MakeString(byte *data, byte len)

{

int i, j;

String tempString[len];

String bitString="";

for (i = 0; i < len; i++)

{

tempString[i] = String(data[i], BIN);

int zeros = 8 - tempString[i].length();

for (j = 0; j < zeros; j++)

{

tempString[i] = '0' + tempString[i];

}

}

for (i = 0; i < len; i++)

{

bitString = bitString + tempString[i];

}

return bitString;

}