//==============================================================================
// E - R A D I O N I C A . C O M, H.Kolomana 6/A, Djakovo 31400, Croatia
//==============================================================================
// Project : SHT21 Arduino Library (V1.0)
// File : SHT21.cpp
// Author : e-radionica.com 2017
// Licence : Open-source !
//==============================================================================
//==============================================================================
// Use with any SHT21 breakout. Check ours:
// https://e-radionica.com/en/sht21-humidity-and-temperature-sensor.html
// If any questions,
// just contact techsupport@e-radionica.com
//==============================================================================
// Modified for ChibiOS Mike James Feb 2020
#include "ch.h"
#include <SHT21.h>
//==============================================================================
// PUBLIC
//==============================================================================
float SHT21::getHumidity(void) {
uint16_t result; // return variable
result = readSensor_hm(TRIGGER_RH_MEASUREMENT_HM);
return CalcRH(result);
}
float SHT21::getTemperature(void) {
uint16_t result; // return variable
result = readSensor_hm(TRIGGER_T_MEASUREMENT_HM);
return CalcT(result);
}
void SHT21::reset() {
const uint8_t buff = SOFT_RESET;
msg_t err = i2cMasterTransmit(m_driver, I2C_ADD, &buff, sizeof(buff), 0,0);
if(err != MSG_OK)
chThdSleepMilliseconds(15); // wait for SHT to reset
}
msg_t SHT21::getSerialNumber(uint8_t * serialNumber) {
// read memory location 1
const uint8_t buff []= { 0xFA,0x0F };
uint8_t rxbuff[8];
msg_t err = i2cMasterTransmit(m_driver, I2C_ADD, buff, sizeof(buff), &rxbuff[0], sizeof(rxbuff));
if(err != MSG_OK)
return err;
serialNumber[5] = rxbuff[0]; // read SNB_3
// CRC SNB_3 not used
serialNumber[4] = rxbuff[2]; // read SNB_2
// CRC SNB_2 not used
serialNumber[3] = rxbuff[4]; // read SNB_1
// CRC SNB_1 not used
serialNumber[2] = rxbuff[7]; // read SNB_0
// CRC SNB_0 not used
// read memory location 2
const uint8_t buff2[] = {0xFC,0xC9};
err = i2cMasterTransmit(m_driver, I2C_ADD, buff2, sizeof(buff2), &rxbuff[0], 6);
serialNumber[1] = rxbuff[0]; // read SNC_1
serialNumber[0] = rxbuff[1]; // read SNC_0
serialNumber[7] = rxbuff[3]; // read SNA_1
serialNumber[6] = rxbuff[4]; // read SNA_0
return MSG_OK;
}
//==============================================================================
// PRIVATE
//==============================================================================
uint16_t SHT21::readSensor_hm(uint8_t command) {
uint8_t checksum;
uint8_t data[2];
uint16_t result;
uint8_t rxBuff[3];
msg_t err = i2cMasterTransmit(m_driver, I2C_ADD, &command, 1, &rxBuff[0], 3);
if (err != MSG_OK)
data[0] = rxBuff[0]; // read data (MSB)
data[1] = rxBuff[1]; // read data (LSB)
checksum = rxBuff[2]; // read checksum
result = (data[0] << 8);
result += data[1];
if(CRC_Checksum (data,2,checksum)) {
reset();
return 1;
}
else return result;
}
float SHT21::CalcRH(uint16_t rh) {
rh &= ~0x0003; // clean last two bits
return (-6.0 + 125.0/65536 * (float)rh); // return relative humidity
}
float SHT21::CalcT(uint16_t t) {
t &= ~0x0003; // clean last two bits
return (-46.85 + 175.72/65536 * (float)t);
}
uint8_t SHT21::CRC_Checksum(uint8_t data[], uint8_t no_of_bytes, uint8_t checksum) {
uint8_t crc = 0;
uint8_t byteCtr;
//calculates 8-Bit checksum with given polynomial
for (byteCtr = 0; byteCtr < no_of_bytes; ++byteCtr)
{ crc ^= (data[byteCtr]);
for (uint8_t bit = 8; bit > 0; --bit)
{ if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
if (crc != checksum) return 1;
else return 0;
}