SHTx Temperature and Humidity Sensor (Part 3)

Part 12, 3

PlainSHT1x contains a set of additional functions which perform advanced tasks such as checking power supply voltage:

uint8_t PlainSHT1x::Battery() 
{
	uint8_t regContent = ReadRegister();
	return ((regContent >> 6) & 0x01);
};

… changing the resolution of measurements:

void PlainSHT1x::Resolution(uint8_t state)
{
	_resolution = state;
	uint8_t regContent = ReadRegister();
	if (state) {
		regContent |= (1 << 0);
	} else {
		regContent &= ~(1 << 0);
	}
	WriteRegister(regContent);
};

uint8_t PlainSHT1x::Resolution()
{
	uint8_t regContent = ReadRegister();
	_resolution = ((regContent >> 0) & 0x01);
	return(_resolution);
};

… turning the heating element ON and OFF for conditioning the sensor

uint8_t PlainSHT1x::Heater(uint8_t state) 
{
	_heater = state;
	uint8_t regContent = ReadRegister();
	if (state) {
		regContent |= (1 << 2);
	} else {
		regContent &= ~(1 << 2);
	}
	WriteRegister(regContent);
	return(_heater);
};

uint8_t PlainSHT1x::Heater(void) 
{
	uint8_t regContent = ReadRegister();
	_heater = ((regContent >> 2) & 0x01);
	return(_heater);
};

More interesting are the functions which perform physical measurements. One function gets thermal OR humidity measurements

uint16_t PlainSHT1x::GetSingleADCData(uint8_t dataType)
/* Get one single adc value for temperature or humidity */
{
	if (_errorCode != ERR_NONE) {
		return(0); /* exit and propagate error */
	}
	/* Init transmission with sensor */
	StartTransmit();
	/* Query data */
	WriteByte(dataType);
	if (_errorCode != ERR_NONE) {
		return(0); /* exit and propagate error */
	}
	/* Wait for convertion completion */
	uint16_t timeOut = 1000;
	do {
		_delay_ms(1.0);
		timeOut -= 1;
		if(timeOut == 0) {
			_errorCode = ERR_CVT_FAILURE;
			break;
		}
	} while (GetPinLevel(_pinData));
	if (_errorCode != ERR_NONE) {
		return(0); /* exit and propagate error */
	}
	/* Read and store two data bytes (MSB-LSB) */
	uint8_t MSB = ReadByte(ACK_YES);
	uint8_t LSB = ReadByte(ACK_YES);
	uint8_t readCRC = ReadByte(ACK_NO);
	uint16_t data = ((MSB << 8) | LSB);
	return(data);
};

While the GetData() function manages the collection of raw data and calculates additional information such as linear RH%, compensated RH% and dew point:

 
void PlainSHTx::GetData(void) 
/* Get combined data */
{
	/* Reset error code */
	ErrorCode(ERR_NONE);
	/* Get and compute temperature */
	uint32_t tempADC = GetSingleADCData(CMD_GET_TEMPERATURE);
	if (_errorCode != ERR_NONE) {
		return; /* Exit and propagate error */
	}
	/* Convert adc data in C (5V)*/
	if (_resolution == RES_HIGH) {
		tempADC &= 0x3FFF; /* Apply 14 bits mask */
		_temperature = ((tempADC * 0.01) - 40.1); 
	} else { 
		tempADC &= 0xFFF; /* Apply 12 bits mask */
		_temperature = ((tempADC * 0.04) - 40.1); 
	}
	/* Get and compute relative humidity */
	uint32_t relHumADC = GetSingleADCData(CMD_GET_REL_HUMIDITY);
	if (_errorCode != ERR_NONE) {
		return; /* Exit and propagate error */
	}
	/* Convert adc data in rh% */
	if (_resolution == RES_HIGH) {
		relHumADC &= 0xFFF; /* Apply 12 bits mask */
		_relHumidityLin = ((-1.5955E-6 * (relHumADC * relHumADC)) + (0.0367 * relHumADC) - 2.0468);
	} else { /* Default is high */
		relHumADC &= 0xFF; /* Apply 8 bits mask */
		_relHumidityLin = ((-4.0845E-4 * (relHumADC * relHumADC)) + (0.5872 * relHumADC) - 2.0468);
	}
	/* Compute compensated relative humidity */
	if (_resolution == RES_HIGH) {
		_relHumidityTempCompensated = (_temperature - 25.0) * (0.01 + (0.00008 * relHumADC)) + _relHumidityLin;;
	} else {
		_relHumidityTempCompensated = (_temperature - 25.0) * (0.01 + (0.00128 * relHumADC)) + _relHumidityLin;;
	}
	/* Keep result within bounds */
	if (_relHumidityTempCompensated > 100.0) {
		_relHumidityTempCompensated = 100.0; 
	}
	if (_relHumidityTempCompensated < 0.1) { 		_relHumidityTempCompensated = 0.1; 	} 	/* Compute dew point */ 	if (_temperature > 0) {
		double H = ((log10(_relHumidityTempCompensated) - 2.0) / 0.4343) + ((17.62 * _temperature) / (243.12 +_temperature));
		_dewPoint = ((243.12 * H) / (17.62 - H));
	} else {
		double H = ((log10(_relHumidityTempCompensated) - 2.0) / 0.4343) + ((22.46 * _temperature) / (272.62 +_temperature));
		_dewPoint = ((272.62 * H) / (22.46 - H));
	}
};

Note: In case of error, the resulting temperatures are set to an aberrant -300°C value, while RH% are set to a negative %.

Each measurement can be extracted using public functions:

double PlainSHT1x::Temperature(void)
{
	if (_errorCode != ERR_NONE) {
		return(-300.0); 
	}
	return(_temperature);
};

double PlainSHT1x::DewPoint(void)
{
	if (_errorCode != ERR_NONE) {
		return(-300.0); 
	}
	return(_dewPoint);
};

double PlainSHT1x::RelHumidityTempCompensated(void)
{
	if (_errorCode != ERR_NONE) {
		return(-1.0); 
	}
	return(_relHumidityTempCompensated);
};

double PlainSHT1x::RelHumidityLinear(void)
{
	if (_errorCode != ERR_NONE) {
		return(-1.0); 
	}
	return(_relHumidityLin);
};

 

As usual, these functions are embedded in a clean nicely working library available on request

 

Leave a Reply

You must be logged in to post a comment.