/** * @file SHT3X_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2025 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief Familiar functions of SHT3X tem&hum transistor for all devices * * @version * - 1_01_200318 > ATY * -# Preliminary version, first Release * - 1_02_231229 > ATY * -# add multy addr and channel ******************************************************************************** */ #ifndef __SHT3X_ATY_C #define __SHT3X_ATY_C #include "SHT3X_ATY.h" /******************************* For user *************************************/ /******************************************************************************/ float temperatureSHT3X = 0.0; float humiditySHT3X = 0.0; /* 0: 0-65T, 10-90H, Best accuracy 1: -40-0/65-120T, 0-10/90-100H, not good accuracy, warning 2: out of limit data, error */ uint8_t warningFlag = 0; /** * @brief calc crc with SHT3X data * @param sht3xData data to calc * @param nbrOfBytes length of data to calc * @return uint8_t crc value */ uint8_t SHT3X_CalcCrc(uint8_t* sht3xData, uint8_t nbrOfBytes) { uint8_t bit_t; // bit mask uint8_t crc = 0xFF; // calculated checksum uint8_t byteCtr; // byte counter // calculates 8-Bit checksum with given polynomial for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++) { crc ^= sht3xData[byteCtr]; for(bit_t = 8; bit_t > 0; --bit_t) { if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL; else crc = (crc << 1); } } return crc; } /** * @brief check crc with SHT3X data * @param sht3xData data to check * @param nbrOfBytes length of data to check * @param checksum compare value with calculated crc * @return !0: wrong, 0: success */ uint8_t SHT3X_CheckCrc(uint8_t* sht3xData, uint8_t nbrOfBytes, uint8_t checksum) { // calculates 8-Bit checksum uint8_t crc = SHT3X_CalcCrc(sht3xData, nbrOfBytes); if(crc != checksum) return 1; else return 0; } /** * @brief write command to SHT3X * @param cmd command to send * @param addr chip address * @param channel chip channel */ void SHT3X_WriteCommand(sht3xCommands cmd, uint8_t addr, uint8_t channel) { uint8_t cmd_t[2]; cmd_t[0] = cmd >> 8; cmd_t[1] = cmd & 0xFF; I2C_Write(addr, cmd_t, 2, channel); } /** * @brief start periodic measurment * @param repeatability repeatability * @param frequency frequency * @param addr chip address * @param channel chip channel * @note use depending on the required repeatability and frequency, * the corresponding command */ void SHT3X_StartPeriodicMeasurment(sht3xRepeatability repeatability, sht3xFrequency frequency, uint8_t addr, uint8_t channel) { switch(repeatability) { case REPEATAB_LOW: // low repeatability switch(frequency) { case FREQUENCY_HZ5: // low repeatability, 0.5 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_05_L, addr, channel); break; case FREQUENCY_1HZ: // low repeatability, 1.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_1_L, addr, channel); break; case FREQUENCY_2HZ: // low repeatability, 2.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_2_L, addr, channel); break; case FREQUENCY_4HZ: // low repeatability, 4.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_4_L, addr, channel); break; case FREQUENCY_10HZ: // low repeatability, 10.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_10_L, addr, channel); break; default: break; } break; case REPEATAB_MEDIUM: // medium repeatability switch(frequency) { case FREQUENCY_HZ5: // medium repeatability, 0.5 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_05_M, addr, channel); break; case FREQUENCY_1HZ: // medium repeatability, 1.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_1_M, addr, channel); break; case FREQUENCY_2HZ: // medium repeatability, 2.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_2_M, addr, channel); break; case FREQUENCY_4HZ: // medium repeatability, 4.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_4_M, addr, channel); break; case FREQUENCY_10HZ: // medium repeatability, 10.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_10_M, addr, channel); break; default: break; } break; case REPEATAB_HIGH: // high repeatability switch(frequency) { case FREQUENCY_HZ5: // high repeatability, 0.5 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_05_H, addr, channel); break; case FREQUENCY_1HZ: // high repeatability, 1.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_1_H, addr, channel); break; case FREQUENCY_2HZ: // high repeatability, 2.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_2_H, addr, channel); break; case FREQUENCY_4HZ: // high repeatability, 4.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_4_H, addr, channel); break; case FREQUENCY_10HZ: // high repeatability, 10.0 Hz SHT3X_WriteCommand(CMD_MEAS_PERI_10_H); break; default: break; } break; default: break; } } /** * @brief calc real value from 16 bit data * @param temperature temperature 16 bit origin value * @param humidity humidity 16 bit origin value */ void SHT3X_ValuePorcess(uint16_t* temperature, uint16_t* humidity) { temperatureSHT3X = -45 + 175 * (1.0 * (*temperature) / 65535); humiditySHT3X = 100 * (1.0 * (*humidity) / 65535); warningFlag = 0; if(temperatureSHT3X < 0 || temperatureSHT3X>65) warningFlag = 1; else if(temperatureSHT3X < -40) { warningFlag = 2; temperatureSHT3X = -40; } else if(temperatureSHT3X > 120) { warningFlag = 2; temperatureSHT3X = 120; } if(humiditySHT3X < 10 || humiditySHT3X>90) warningFlag = 1; else if(humiditySHT3X < 0) { warningFlag = 2; humiditySHT3X = 0; } else if(humiditySHT3X > 100) { warningFlag = 2; humiditySHT3X = 100; } } /** * @brief read all data from SHT3X * @param temperature temperature 16 bit origin value * @param humidity humidity 16 bit origin value * @param addr chip address * @param channel chip channel */ void SHT3X_ReadDataAndCrc(uint16_t* temperature, uint16_t* humidity, uint8_t addr, uint8_t channel) { uint8_t bytes[6]; // read 2 data array and 1 checksum byte // read two data bytes and one checksum byte I2C_Read(addr, bytes, 6, channel); // verify checksum then combine the two bytes to a 16-bit value if(!SHT3X_CheckCrc(bytes, 2, bytes[2])) *temperature = (bytes[0] << 8) | bytes[1]; // else // *temperature = 0; if(!SHT3X_CheckCrc(bytes + 3, 2, bytes[5])) *humidity = (bytes[3] << 8) | bytes[4]; // else // *humidity = 0; SHT3X_ValuePorcess(temperature, humidity); } /** * @brief read data and calc real value * @param addr chip address * @param channel chip channel */ void SHT3X_ReadMeasurementBuffer(uint8_t addr, uint8_t channel) { uint16_t hexValueTemp = 0; uint16_t hexValueHumi = 0; SHT3X_WriteCommand(CMD_FETCH_DATA, addr, channel); SHT3X_ReadDataAndCrc(&hexValueTemp, &hexValueHumi, addr, channel); } /** * @brief start measurement in clock stretching mode * @param repeatability repeatability * @param addr chip address * @param channel chip channel * @note use depending on the required repeatability, the corresponding command */ void SHT3X_GetTempAndHumiClkStretch(sht3xRepeatability repeatability, uint8_t addr, uint8_t channel) { uint16_t hexTempValue = 0; uint16_t hexHumiValue = 0; switch(repeatability) { case REPEATAB_LOW: SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_L, addr, channel); break; case REPEATAB_MEDIUM: SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_M, addr, channel); break; case REPEATAB_HIGH: SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_H, addr, channel); break; default: break; } SHT3X_ReadDataAndCrc(&hexTempValue, &hexHumiValue, addr, channel); } /** * @brief init SHT3X, check device * @param addr chip address * @param channel chip channel * @note put at main init */ void SHT3X_InitBegin(uint8_t addr, uint8_t channel) { uint8_t i = 0; SHT3X_StartPeriodicMeasurment(REPEATAB_HIGH, FREQUENCY_10HZ, addr, channel); for(i = 0; i < 9; i++) { DelayMs(110); SHT3X_ReadMeasurementBuffer(addr, channel); // SHT3X_GetTempAndHumiClkStretch(REPEATAB_LOW, addr, channel); } // SHT3X_StartPeriodicMeasurment(REPEATAB_LOW, FREQUENCY_HZ1, addr, channel); SHT3X_StartPeriodicMeasurment(REPEATAB_HIGH, FREQUENCY_10HZ, addr, channel); } // todo: not tested // void main() // { // SHT3X_InitBegin(addr, channel); // while(1) // { // SHT3X_ReadMeasurementBuffer(addr, channel); // UartSendStr("\r\nHT: "); // UartSendStr(TemperatureStr); // UartSendStr(" - "); // UartSendStr(HumidityStr); // DelayMs(2000); // } // } // // declare 5byte group, last with '\0' for show // uint8_t Temperature[5] = {0, 0, '.', 0}; // uint8_t Humidity[5] = {0, 0, '.', 0}; // uint8_t TemperatureStr[5] = {0, 0, '.', 0}; // uint8_t HumidityStr[5] = {0, 0, '.', 0}; // uint8_t temperatureHexI = 0; // integer // uint8_t temperatureHexD = 0; // decimal // uint8_t humidityHexI = 0; // uint8_t humidityHexD = 0; // temperature = ((uint8_t)decTempValue << 8) + ((uint16_t)(decTempValue * 100) % 100); // humidity = ((uint8_t)decHumiValue << 8) + ((uint16_t)(decHumiValue * 100) % 100); // temperatureHexI = temperature >> 8; // temperatureHexD = temperature; // humidityHexI = humidity >> 8; // humidityHexD = humidity; // // todo higher than 100 or below 0 // // todo only get origin data, do not change type here // // todo AHT20 deal the same, and change I2C function to standard // // if() // Temperature[0] = temperatureHexI / 10; // Temperature[1] = temperatureHexI % 10; // Temperature[3] = temperatureHexD / 10; // Humidity[0] = humidityHexI / 10; // Humidity[1] = humidityHexI % 10; // Humidity[3] = humidityHexD / 10; // TemperatureStr[0] = Temperature[0] + '0'; // TemperatureStr[1] = Temperature[1] + '0'; // TemperatureStr[3] = Temperature[3] + '0'; // HumidityStr[0] = Humidity[0] + '0'; // HumidityStr[1] = Humidity[1] + '0'; // HumidityStr[3] = Humidity[3] + '0'; #endif /* __SHT3X_ATY_C */ /******************************** End Of File *********************************/