关于sht10温湿度传感器的问题

时间:2021-04-15 09:22:41
最近用一个arm的cortex-m0 MCU做一个温湿度传感器,使用的传感器芯片是SHT10,,使用过程中遇到一些问题,特发此贴寻求帮助。
1、关于硬件电路,基本上按照官方给的datasheet做的,只是VDD使用的是3.3V。
2、软件实现在下面给出,基本是官方给的样例修改的。
3、遇到的问题,温度结果过高,湿度结果过低。但是总体上是成线性的。在24~25度室温下,测出温度为30~31度,湿度更谈不上准确。在低温环境下,温度数值也立刻下降,比如放在零度左右,测得8度。
4、我想请问你们用这款传感器时温度是否需要修正,谢谢。
二楼放代码

6 个解决方案

#1


void SHT10_con_init()
{
    SHT10_SCL_CFG();
    SHT10_SDA_CFG();

    SHT10_SCL_OUTPUT();
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    SHT10_delay_half();
}

void SHT10_con_wait()
{
    SHT10_SCL_LOW();
    SHT10_delay_half();
    SHT10_SDA_INPUT();
    SHT10_delay_half();
}

void SHT10_con_reset()
{
    uint8_t i;
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_SCL_LOW();
    SHT10_delay_half();
    for( i=0 ; i<9 ; i++ )
    {
        SHT10_SCL_HIGH();
        SHT10_delay();
        SHT10_SCL_LOW();
        SHT10_delay();
    }

    SHT10_start_transfers();
}

void SHT10_start_transfers()
{
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_SCL_LOW();
    SHT10_delay_half();

    SHT10_SCL_HIGH();
    SHT10_delay_half();
    SHT10_SDA_LOW();
    SHT10_delay_half();

    SHT10_SCL_LOW();
    SHT10_delay();

    SHT10_SCL_HIGH();
    SHT10_delay_half();
    SHT10_SDA_HIGH();
    SHT10_delay_half();
    
    SHT10_SCL_LOW();
}

int SHT10_write_byte(uint8_t data)
{
    uint8_t i;
    SHT10_SDA_OUTPUT();
    for (i=0x80;i>0;i>>=1)
    {   
        if(i&data)
{
            SHT10_SDA_HIGH();
}
        else{
           SHT10_SDA_LOW();
}
        SHT10_delay_half();
        SHT10_SCL_HIGH();
        SHT10_delay();
SHT10_SCL_LOW();
        SHT10_delay_half();
    }
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    SHT10_delay();
    SHT10_SCL_HIGH();
    
    if(SHT10_SDA_READ())
    {
        SHT10_SCL_LOW();
        return -1;
    }
    SHT10_SCL_LOW();
    return 0;
}

uint8_t SHT10_read_byte(uint8_t ack)
{
    uint8_t i;
uint8_t value;
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_delay_half();
    SHT10_SDA_INPUT();

    value = 0;
    for(i=0x80;i>0;i>>=1)
    {
        SHT10_SCL_HIGH();
        SHT10_delay_half();
        if(SHT10_SDA_READ())
{
value |=i;
}
        SHT10_delay_half();
        SHT10_SCL_LOW();
        SHT10_delay();
    }
    SHT10_SDA_OUTPUT();
if(ack)
{
        SHT10_SDA_LOW();
    }else{
SHT10_SDA_HIGH();
}
SHT10_delay_half();
    SHT10_SCL_HIGH();
    SHT10_delay();
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    return value;
}

int SHT10_reset()
{
    SHT10_con_reset();
return SHT10_write_byte(SHT10_CMD_RESET); 
}
int SHT10_set_status(uint8_t status)
{
    SHT10_start_transfers(); 
if(SHT10_write_byte(SHT10_CMD_STATUS_WRITE))
{
return -1;
}
return SHT10_write_byte(status);
}
int SHT10_read_status(uint8_t *status)
{
    uint8_t ack;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_STATUS_READ))
{
return -1;
}
    *status = SHT10_read_byte(1);
ack = SHT10_read_byte(1);
return  0;
}
int SHT10_temp_measure_start()
{
    uint16_t result = 0;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_TEMP_MS))
{
return -1;
}
SHT10_con_wait();
sensor_mod = SHT10_Measure_Temperature;
app_timer_start(sht10_time,MEASURE_TEMP_WAIT_TICK,NULL);
return 0;

}
int SHT10_humi_measure_start()
{
uint16_t result = 0;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_HUMI_MS))
{
return -1;
}

SHT10_con_wait();
sensor_mod = SHT10_Measure_Humidity;
app_timer_start(sht10_time,MEASURE_HUMI_WAIT_TICK,NULL);
return 0;

}

int SHT10_receive_value(uint16_t *value)
{
uint16_t data,count;
uint8_t values[3] = {0,0,0};
count = 0;
    while(SHT10_SDA_READ())
    {
count++;
if(count>=1000)
{
return -1;
}
nrf_delay_ms(1);
    }
values[0] = SHT10_read_byte(1);
values[1] = SHT10_read_byte(0);
//values[2] = SHT10_read_byte(1);
*value =  (values[0] << 8) + values[1];
return 0;
}
float SHT10_get_temp_value(float temp)
{
    return (temp * 0.01 - 40.1);
}
float SHT10_get_humi_value(float humi)
{
    const float c1=-4.0;      // for 12 Bit
    const float c2=0.0405;     // for 12 Bit
    const float c3=-2.8E-6;     // for 12 Bit
    const float t1=0.01;      // for 14 Bit @ 5V
    const float t2=0.00008;     // for 14 Bit @ 5V
float linear,value;
linear = humi * humi *(c3)+(humi)*c2+c1;
value = (temperature_value - 25.0)*(t1+t2*humi)+linear;
return value;
}
/*测量结果是使用一个定时器触发后再去读取的,没有使用循环等待*/
void app_sht10_timeout_handler_t(void * p_context)
{
uint16_t result = 0;
//UNUSED_PARAMETER(p_context);
if(sensor_mod == SHT10_Measure_Temperature)
{
if(SHT10_receive_value(&result))
    {
sensor_mod = SHT10_ERROR;
    }
    temperature_value = SHT10_get_temp_value((float)result);
SHT10_humi_measure_start();
}else if(sensor_mod == SHT10_Measure_Humidity)
{
if(SHT10_receive_value(&result))
    {
sensor_mod = SHT10_ERROR;
    }

    humidity_value = SHT10_get_humi_value((float)result);
sensor_mod = SHT10_Measure_Free;
is_SHT10_busy = 0;
}
}
int SHT10_init()
{
uint8_t status;
if(is_SHT10_busy)
return -1;
is_SHT10_busy = 0;
nrf_delay_ms(20);
SHT10_con_init();
    SHT10_reset();
nrf_delay_ms(11);
sensor_mod = SHT10_Measure_Free;
SHT10_set_status(0);
app_timer_create(&sht10_time,APP_TIMER_MODE_SINGLE_SHOT,app_sht10_timeout_handler_t);
return 0;
}
int SHT10_measure_start()
{
if(is_SHT10_busy)
return -1;
is_SHT10_busy = 1;
if(SHT10_temp_measure_start())
{
SHT10_con_reset();
is_SHT10_busy = 0;
return -1;
}
return 0;
}
int SHT10_pop_value(float *temp,float *humi)
{
if(is_SHT10_busy)
return -1;
*temp = temperature_value;
*humi = humidity_value;
return 0;
}

#2


lz用了华氏温度了吧?

#3


没有,用的摄氏度啊,
温度的公式
 temp * 0.01 - 40.1;

#4


Heater: An on chip heating element can be addressed by
writing a command into status register. The heater may
increase the temperature of the sensor by 5 – 10°C
beyond ambient temperature. The heater draws roughly
8mA @ 5V supply voltage. 
楼主读到这段没?测一下是否有个8ma电流

#5


找了盛思睿的技术支持,对方竟然不建议使用sht10,推荐我使用sht3x系列的,这款更便宜,并且是标注i2c的。至于这个sht10的问题就没有下一步了。。。。。。因为要换传感器又要重新写代码了,如果谁遇到好的解决方案请告诉我,先结贴了,谢谢大家

#6


你 好:我现在要也是用M0的 做的这个,情况和你的差不多,你现在结果怎么样了,

#1


void SHT10_con_init()
{
    SHT10_SCL_CFG();
    SHT10_SDA_CFG();

    SHT10_SCL_OUTPUT();
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    SHT10_delay_half();
}

void SHT10_con_wait()
{
    SHT10_SCL_LOW();
    SHT10_delay_half();
    SHT10_SDA_INPUT();
    SHT10_delay_half();
}

void SHT10_con_reset()
{
    uint8_t i;
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_SCL_LOW();
    SHT10_delay_half();
    for( i=0 ; i<9 ; i++ )
    {
        SHT10_SCL_HIGH();
        SHT10_delay();
        SHT10_SCL_LOW();
        SHT10_delay();
    }

    SHT10_start_transfers();
}

void SHT10_start_transfers()
{
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_SCL_LOW();
    SHT10_delay_half();

    SHT10_SCL_HIGH();
    SHT10_delay_half();
    SHT10_SDA_LOW();
    SHT10_delay_half();

    SHT10_SCL_LOW();
    SHT10_delay();

    SHT10_SCL_HIGH();
    SHT10_delay_half();
    SHT10_SDA_HIGH();
    SHT10_delay_half();
    
    SHT10_SCL_LOW();
}

int SHT10_write_byte(uint8_t data)
{
    uint8_t i;
    SHT10_SDA_OUTPUT();
    for (i=0x80;i>0;i>>=1)
    {   
        if(i&data)
{
            SHT10_SDA_HIGH();
}
        else{
           SHT10_SDA_LOW();
}
        SHT10_delay_half();
        SHT10_SCL_HIGH();
        SHT10_delay();
SHT10_SCL_LOW();
        SHT10_delay_half();
    }
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    SHT10_delay();
    SHT10_SCL_HIGH();
    
    if(SHT10_SDA_READ())
    {
        SHT10_SCL_LOW();
        return -1;
    }
    SHT10_SCL_LOW();
    return 0;
}

uint8_t SHT10_read_byte(uint8_t ack)
{
    uint8_t i;
uint8_t value;
    SHT10_SDA_OUTPUT();
    SHT10_SDA_HIGH();
    SHT10_delay_half();
    SHT10_SDA_INPUT();

    value = 0;
    for(i=0x80;i>0;i>>=1)
    {
        SHT10_SCL_HIGH();
        SHT10_delay_half();
        if(SHT10_SDA_READ())
{
value |=i;
}
        SHT10_delay_half();
        SHT10_SCL_LOW();
        SHT10_delay();
    }
    SHT10_SDA_OUTPUT();
if(ack)
{
        SHT10_SDA_LOW();
    }else{
SHT10_SDA_HIGH();
}
SHT10_delay_half();
    SHT10_SCL_HIGH();
    SHT10_delay();
    SHT10_SCL_LOW();
    SHT10_SDA_INPUT();
    return value;
}

int SHT10_reset()
{
    SHT10_con_reset();
return SHT10_write_byte(SHT10_CMD_RESET); 
}
int SHT10_set_status(uint8_t status)
{
    SHT10_start_transfers(); 
if(SHT10_write_byte(SHT10_CMD_STATUS_WRITE))
{
return -1;
}
return SHT10_write_byte(status);
}
int SHT10_read_status(uint8_t *status)
{
    uint8_t ack;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_STATUS_READ))
{
return -1;
}
    *status = SHT10_read_byte(1);
ack = SHT10_read_byte(1);
return  0;
}
int SHT10_temp_measure_start()
{
    uint16_t result = 0;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_TEMP_MS))
{
return -1;
}
SHT10_con_wait();
sensor_mod = SHT10_Measure_Temperature;
app_timer_start(sht10_time,MEASURE_TEMP_WAIT_TICK,NULL);
return 0;

}
int SHT10_humi_measure_start()
{
uint16_t result = 0;
SHT10_start_transfers();
if(SHT10_write_byte(SHT10_CMD_HUMI_MS))
{
return -1;
}

SHT10_con_wait();
sensor_mod = SHT10_Measure_Humidity;
app_timer_start(sht10_time,MEASURE_HUMI_WAIT_TICK,NULL);
return 0;

}

int SHT10_receive_value(uint16_t *value)
{
uint16_t data,count;
uint8_t values[3] = {0,0,0};
count = 0;
    while(SHT10_SDA_READ())
    {
count++;
if(count>=1000)
{
return -1;
}
nrf_delay_ms(1);
    }
values[0] = SHT10_read_byte(1);
values[1] = SHT10_read_byte(0);
//values[2] = SHT10_read_byte(1);
*value =  (values[0] << 8) + values[1];
return 0;
}
float SHT10_get_temp_value(float temp)
{
    return (temp * 0.01 - 40.1);
}
float SHT10_get_humi_value(float humi)
{
    const float c1=-4.0;      // for 12 Bit
    const float c2=0.0405;     // for 12 Bit
    const float c3=-2.8E-6;     // for 12 Bit
    const float t1=0.01;      // for 14 Bit @ 5V
    const float t2=0.00008;     // for 14 Bit @ 5V
float linear,value;
linear = humi * humi *(c3)+(humi)*c2+c1;
value = (temperature_value - 25.0)*(t1+t2*humi)+linear;
return value;
}
/*测量结果是使用一个定时器触发后再去读取的,没有使用循环等待*/
void app_sht10_timeout_handler_t(void * p_context)
{
uint16_t result = 0;
//UNUSED_PARAMETER(p_context);
if(sensor_mod == SHT10_Measure_Temperature)
{
if(SHT10_receive_value(&result))
    {
sensor_mod = SHT10_ERROR;
    }
    temperature_value = SHT10_get_temp_value((float)result);
SHT10_humi_measure_start();
}else if(sensor_mod == SHT10_Measure_Humidity)
{
if(SHT10_receive_value(&result))
    {
sensor_mod = SHT10_ERROR;
    }

    humidity_value = SHT10_get_humi_value((float)result);
sensor_mod = SHT10_Measure_Free;
is_SHT10_busy = 0;
}
}
int SHT10_init()
{
uint8_t status;
if(is_SHT10_busy)
return -1;
is_SHT10_busy = 0;
nrf_delay_ms(20);
SHT10_con_init();
    SHT10_reset();
nrf_delay_ms(11);
sensor_mod = SHT10_Measure_Free;
SHT10_set_status(0);
app_timer_create(&sht10_time,APP_TIMER_MODE_SINGLE_SHOT,app_sht10_timeout_handler_t);
return 0;
}
int SHT10_measure_start()
{
if(is_SHT10_busy)
return -1;
is_SHT10_busy = 1;
if(SHT10_temp_measure_start())
{
SHT10_con_reset();
is_SHT10_busy = 0;
return -1;
}
return 0;
}
int SHT10_pop_value(float *temp,float *humi)
{
if(is_SHT10_busy)
return -1;
*temp = temperature_value;
*humi = humidity_value;
return 0;
}

#2


lz用了华氏温度了吧?

#3


没有,用的摄氏度啊,
温度的公式
 temp * 0.01 - 40.1;

#4


Heater: An on chip heating element can be addressed by
writing a command into status register. The heater may
increase the temperature of the sensor by 5 – 10°C
beyond ambient temperature. The heater draws roughly
8mA @ 5V supply voltage. 
楼主读到这段没?测一下是否有个8ma电流

#5


找了盛思睿的技术支持,对方竟然不建议使用sht10,推荐我使用sht3x系列的,这款更便宜,并且是标注i2c的。至于这个sht10的问题就没有下一步了。。。。。。因为要换传感器又要重新写代码了,如果谁遇到好的解决方案请告诉我,先结贴了,谢谢大家

#6


你 好:我现在要也是用M0的 做的这个,情况和你的差不多,你现在结果怎么样了,