树莓派&Python&SHT10

树莓派&Python&SHT10


SHT10的性能.

eg: xx->xx->xx 表示 min值->typ值->max值.

  • 湿度分辨率: 0.4->0.05->0.05(%RH) 或者用二进制位 8->12->12(bit)
  • 湿度精度: ±4.5 %RH (typ 条件下.)
  • 温度分辨率: 0.04->0.01->0.01(℃) 或者用二进制位 12->14->14(bit)
  • 湿度精度: ±0.5 ℃ (typ 条件下.)
  • 供电电压: 2.4->3.3->5.5(V)

传感器默认测量分辨率为温度14位, 湿度12位, 可以通过给状态寄存器发送命令将其降低为温度12位, 湿度8位.

以下分别为相对湿度和温度数据变化图.


SHT10接口.

接口图:

  • 电源引脚: sensor供电电压范围为2.4-5.5v, 建议电压为3.3.在VDD与GND之间须加一个100nF的电容, 用以去耦滤波.
  • 串行时钟输入(SCK): SCK用于处理器与sensor之间的通讯同步. 由于接口包含完全静态逻辑, 因而不存在最小SCK频率.
  • 串行数据(DATA): 三态结构, 用于读取sensor数据.为保证通讯安全稳定, DATA应处于高电平, SCK处于低电平.

SHT10通讯.

通讯过程:

  1. 启动sensor即给其通电, 上电速率不能低于1V/ms. 通电后sensor需要11ms进入休眠状态, 在此之前不允许给sensor发送任何命令.

  2. 发送”启动传输”时序, 来完成数据传输的初始化.它包括: 当SCK为高电平时DATA翻转为低电平, 紧接着SCK变为低电平, 随后是在SCK时钟高电平是DATA翻转为高电平.(可看后2图).

  3. 发送”测量命令”, 来完成测量湿度/温度. 命名包括: 3个地址位 + 5个命令位.(eg: 000 00011 温度), sensor会以下面的方式来表示已经正确地接收到了命令: 在第8个SCK时钟的下降沿之后, 将DATA下拉为低电平即ACK位.在第9个SCK时钟的下降沿之后, 释放DATA即恢复高电平.(具体命令可看后3图.)

  4. 等待sensor测量, 发送一组测量命令后, 控制器需要等待sensor测量完成.这个过程大概为20/80/320ms, 分别对应8/12/14bit测量. sensor通过下拉DATA至低电平并进入空闲模式, 表示测量的结束. 控制器在再次触发SCK时钟前, 必须等待这个结束信号, 来读取数据.

  5. 控制器接收sensor传输来的2个字节的测量数据和1个字节的CRC奇偶校验(可以选择是否读取). 所有的数据从MSB开始, 右值有效.eg: 对于12位的数据, 从左到右第5为开始有效; 对于8位数据, 高8位为无意义数据.

  6. 数据接收后, sensor自动转入休眠模式.

通讯复位时序:
如果与sensor通讯中断, 可通过下列信号时序复位: 当DATA保持高电平时, 触发SCK时钟9次或者更多, 接着发送一个”启动传输”时序. 这里只是复位了串口, 状态寄存器中的内容仍然保留.

图二:

图三:

eg: 这里是测量湿度数据的通讯过程图. 拿去慢慢琢磨

SHT10数据转换.

相对湿度, 温度值, 湿度信号的温度补偿:

RH_true 为真正的湿度测量值.

T_C 为真正的温度测量值.

  • RH_linear = c1 + c2 * SO_RH + c3 * SO_RH * SO_RH
  • T_C = d1 + d2 * SO_T
  • RH_true = (T_C - 25) * (t1 + t2 * SO_RH) + RH_linear

下列图为上面参数的数值, E为10, eg: -2.80000E-6 相当于 -2.8 * 10^(-6).



以上就是关于SHT10或者SHT1x系列传感器信息的个人理解, 如果有看不懂的地方可以直接百度相关文档查看跟细节的东西.

SHT10的理论介绍的也差不多,接下来走实际的.

在树莓派上使用python控制SHT10sensor读取温湿度数据.

树莓派基本操作我就不说了. 自行百度吧.

  1. 将sensor的VDD, GND, DATA, SCK脚分别连在树莓派的5.0v电源脚, 接地脚, 16脚(GPIO), 18脚(GPIO).这里的脚标号按照BOARD模式, 不懂的自己百度(树莓派BCM和BOARD), 这里就不解释了.

  2. 在用户目录中,创建python脚本(名字自己取).py code在后面给出.

  3. 运行脚本, 这就完了.

关于python code我想说的是:

  1. 没有接受CRC校验数据.

  2. 写了复位时序函数, 但是没用, 要用的自行修改.

  3. delay_little()函数, 延时时间可以自行修改.

  4. 这个脚本非常的不pythoner, 不够优雅和完美.

  5. 脚本只完成了基本功能, 若想让脚本变得更强大, 请自行搞定, 因为作者实在太懒.

  6. 当然啦, 这是在windows上写的, 要在树莓派上跑, 请大家自行解决缩进的问题.(也就TAB和4个空格, 自己再写个py脚本来解决这个问题呗).

  7. 当然啦, 如果脚本出现错误, 请自己检查或者发信息给我等修改(没办法现写的code).

CODE:

    # _*_ coding:utf-8 _*_
    # !/usr/bin/python
    import time
    import RPi.GPIO as GPIO

    # 测量温度/湿度/复位的命令.
    MEASURE_TEMP = 0x03  # 000 0001 1
    MEASURE_HUMI = 0x05  # 000 0010 1
    RESET = 0x1e         # 000 1111 0

    noACK = 0  # 继续通信.
    ACK = 1  # 不继续通信.

    # 温湿度模式.
    TEMP = 0
    HUMI = 1

    # DATA/SCK 对应树莓派GPIO脚号.
    D = 16
    S = 18

    # 设置为BOARD模式.
    GPIO.setmode(GPIO.BOARD)

    # 将DATA, SCK 设置为输出脚, 并给默认电平值.
    # 高电平: 1/GPIO.HIGH/True
    GPIO.setup(D, GPIO.OUT, initial=1)
    GPIO.setup(S, GPIO.OUT, initial=0)
    # 测量函数.
    def measure(mode):
        start_up()  # 发送启动时序.
        error = 0  # 用于记录过程是否出错.

        if mode == TEMP:
            error += write_cmd(MEASURE_TEMP)  # 传入温度测量命令.
        elif mode == HUMI:
            error += write_cmd(MEASURE_HUMI)
        else:
            error += 1

        # print 'measure:', error
        # try control sensor measure time.
        # GPIO.setup(D, GPIO.OUT)
        # time.sleep(0.080)
        # GPIO.setup(D, GPIO.IN)

        while GPIO.input(D):  # 等待sensor测量完成, 等待sensor拉低DATA为低电平.
            continue
        delay_little()

        h8 = read_data(noACK)  # 接收高8位数据并继续读取接收.
        l8 = read_data(ACK)  # 接收低8位数据并停止继续接收CRC数据.

        GPIO.setup(D, GPIO.OUT, initial=1)

        return (h8 << 8) + l8  # 将h8左移8位再加上l8再返回给run()函数.
    # 延时函数.
    def delay_little():
        time.sleep(0.0006)
    # 通信中断时可调用的复位时序函数, 没有调用.
    def communication_reset():
        GPIO.output(D, 1)
        GPIO.output(S, 0)

        for i in range(0, 8):
            GPIO.output(S, 1)
            delay_little()
            GPIO.output(S, 0)
            delay_little()
        start_up()
    # 软复位函数, 没有调用.
    def softreset():
        communication_reset()
        error = 0
        error += write_cmd(RESET)

        return error
    # 发送"启动传输"时序 函数.
    def start_up():
        delay_little()

        GPIO.output(S, 1)
        delay_little()
        GPIO.output(D, 0)
        delay_little()
        GPIO.output(S, 0)
        delay_little()
        GPIO.output(S, 1)
        delay_little()
        GPIO.output(D, 1)
        delay_little()
        GPIO.output(S, 0)
    # 发送测量命令函数.
    # 自己对应传输过程图来看吧, 没啥可解释的. error都是为了检测通讯是否正确.
    def write_cmd(cmd):
        GPIO.output(D, 0)
        delay_little()

        for i in range(0, 8):
            GPIO.output(S, 0)
            if (0x80 >> i) & cmd:
                GPIO.output(D, 1)
            else:
                GPIO.output(D, 0)
            delay_little()
            GPIO.output(S, 1)
            delay_little()

        GPIO.output(S, 0)
        GPIO.setup(D, GPIO.IN)

        GPIO.output(S, 1)
        while GPIO.input(D):
            continue
        error = 0

        delay_little()
        GPIO.output(S, 0)
        delay_little()

        return error
    # 接收sensor测量数据的函数.
    # 这里也一样没啥可解释的.
    def read_data(ack):
        data = 0

        n = 0x80
        for i in range(0, 8):
            GPIO.output(S, 1)
            if GPIO.input(D):
                data = data | n
            delay_little()
            GPIO.output(S, 0)
            delay_little()
            n >>= 1

        GPIO.setup(D, GPIO.OUT)
        if ack:
            GPIO.output(D, 1)
        else:
            GPIO.output(D, 0)

        delay_little()
        GPIO.output(S, 1)
        delay_little()
        GPIO.output(S, 0)
        GPIO.setup(D, GPIO.IN)

        return data
    # 数据的转换计算函数.
    def count_data(temp, humi):
        c1 = -4.0
        c2 = 0.0405
        c3 = 0.0000028
        t1 = 0.01
        t2 = 0.00008

        rh = humi
        t = temp

        tc = t * t1 - 40
        rh_lin = c3 * rh * rh + c2 * rh + c1
        rh_true = (tc - 25) * (t1 + t2 * rh) + rh_lin

        if rh_true > 100.0:
            rh_true = 100.0
        if rh_true < 0.1:
            rh_true = 0.1

        return tc, rh_true
    # 主函数.
    def run():
        while 1:
            temp = measure(TEMP)  # 测量一波温度数据.
            humi = measure(HUMI)  # 与上同理.

            temp, humi = count_data(temp, humi)

            print 'T: {}C\nH: {}%'.format(temp, humi)

            time.sleep(2)  # 延时2秒.
    # 从这开始.
    if __name__ == '__main__':
        run()

猜你喜欢

转载自blog.csdn.net/One_of_them/article/details/78581879