Parts:
- SparkFun Humidity Sensor Breakout - SHTC3 (Qwiic)
- SparkFun Qwiic pHAT v2.0 for Raspberry Pi
- Raspberry Pi 3 B+
Reference Material:
- SHTC3_Datasheet
- smbus2 Python library
Free to use and remix under Creative Commons CC0 Public Domain Dedication
Parts:
Reference Material:
Free to use and remix under Creative Commons CC0 Public Domain Dedication
| from __future__ import print_function | |
| import time | |
| from shtc3 import SHTC3 | |
| with SHTC3.with_bus_addr() as sensor: | |
| sensor.wake() | |
| print("ID:", sensor.id()) | |
| for step in range(120): | |
| sensor.wake() | |
| reading = sensor.measure(clock=False) | |
| sensor.sleep() | |
| print('reading:', reading) | |
| time.sleep(0.1) |
| $ python demo_shtc3.py | |
| ID: [8, 135, 91] | |
| reading: {'t_r': 0.390051, 't_c': 23.26, 't_f': 73.87, 'h': 0.170321} | |
| reading: {'t_r': 0.389944, 't_c': 23.24, 't_f': 73.83, 'h': 0.170397} | |
| reading: {'t_r': 0.39028, 't_c': 23.3, 't_f': 73.94, 'h': 0.170123} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.170199} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.170397} | |
| reading: {'t_r': 0.390005, 't_c': 23.25, 't_f': 73.85, 'h': 0.170092} | |
| reading: {'t_r': 0.389853, 't_c': 23.22, 't_f': 73.8, 'h': 0.169986} | |
| reading: {'t_r': 0.390204, 't_c': 23.29, 't_f': 73.91, 'h': 0.170016} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.16994} | |
| reading: {'t_r': 0.390158, 't_c': 23.28, 't_f': 73.9, 'h': 0.169757} | |
| reading: {'t_r': 0.390188, 't_c': 23.28, 't_f': 73.91, 'h': 0.170016} | |
| reading: {'t_r': 0.38999, 't_c': 23.25, 't_f': 73.85, 'h': 0.170138} | |
| reading: {'t_r': 0.390234, 't_c': 23.29, 't_f': 73.92, 'h': 0.16994} | |
| reading: {'t_r': 0.390021, 't_c': 23.25, 't_f': 73.86, 'h': 0.169909} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.170047} | |
| reading: {'t_r': 0.390158, 't_c': 23.28, 't_f': 73.9, 'h': 0.169909} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.169909} | |
| reading: {'t_r': 0.390066, 't_c': 23.26, 't_f': 73.87, 'h': 0.169741} | |
| reading: {'t_r': 0.390158, 't_c': 23.28, 't_f': 73.9, 'h': 0.169558} | |
| reading: {'t_r': 0.390341, 't_c': 23.31, 't_f': 73.96, 'h': 0.169665} | |
| reading: {'t_r': 0.39028, 't_c': 23.3, 't_f': 73.94, 'h': 0.169833} | |
| reading: {'t_r': 0.390112, 't_c': 23.27, 't_f': 73.89, 'h': 0.169711} | |
| reading: {'t_r': 0.390051, 't_c': 23.26, 't_f': 73.87, 'h': 0.169757} | |
| reading: {'t_r': 0.389899, 't_c': 23.23, 't_f': 73.82, 'h': 0.169757} | |
| reading: {'t_r': 0.389914, 't_c': 23.23, 't_f': 73.82, 'h': 0.169909} | |
| reading: {'t_r': 0.389868, 't_c': 23.23, 't_f': 73.81, 'h': 0.16994} | |
| reading: {'t_r': 0.390021, 't_c': 23.25, 't_f': 73.86, 'h': 0.170092} | |
| reading: {'t_r': 0.38999, 't_c': 23.25, 't_f': 73.85, 'h': 0.169833} | |
| reading: {'t_r': 0.389776, 't_c': 23.21, 't_f': 73.78, 'h': 0.170047} | |
| reading: {'t_r': 0.390188, 't_c': 23.28, 't_f': 73.91, 'h': 0.169909} | |
| reading: {'t_r': 0.390112, 't_c': 23.27, 't_f': 73.89, 'h': 0.169909} | |
| reading: {'t_r': 0.390204, 't_c': 23.29, 't_f': 73.91, 'h': 0.169986} | |
| reading: {'t_r': 0.389944, 't_c': 23.24, 't_f': 73.83, 'h': 0.169894} | |
| reading: {'t_r': 0.390097, 't_c': 23.27, 't_f': 73.88, 'h': 0.169711} | |
| reading: {'t_r': 0.390097, 't_c': 23.27, 't_f': 73.88, 'h': 0.169909} | |
| reading: {'t_r': 0.389807, 't_c': 23.22, 't_f': 73.79, 'h': 0.169894} | |
| reading: {'t_r': 0.390097, 't_c': 23.27, 't_f': 73.88, 'h': 0.169833} | |
| reading: {'t_r': 0.389807, 't_c': 23.22, 't_f': 73.79, 'h': 0.169802} | |
| reading: {'t_r': 0.389822, 't_c': 23.22, 't_f': 73.79, 'h': 0.169604} | |
| reading: {'t_r': 0.389899, 't_c': 23.23, 't_f': 73.82, 'h': 0.16965} | |
| reading: {'t_r': 0.390112, 't_c': 23.27, 't_f': 73.89, 'h': 0.169528} | |
| reading: {'t_r': 0.390188, 't_c': 23.28, 't_f': 73.91, 'h': 0.169604} | |
| reading: {'t_r': 0.390112, 't_c': 23.27, 't_f': 73.89, 'h': 0.169528} | |
| reading: {'t_r': 0.390097, 't_c': 23.27, 't_f': 73.88, 'h': 0.169497} |
| smbus2==0.4.0 |
| import time | |
| from contextlib import contextmanager | |
| from smbus2 import SMBus, i2c_msg | |
| class SHTC3: | |
| def __init__(self, bus, addr=0x70): | |
| self.bus = bus | |
| self.addr = addr | |
| def sleep(self): | |
| self._send_cmd(0xB098) | |
| def wake(self): | |
| self._send_cmd(0x3517) | |
| def reset(self): | |
| self._send_cmd(0x805d) | |
| def id(self): | |
| return self._send_cmd(0xefc8, 3) | |
| def measure(self, wait=0.05, **kw): | |
| if not callable(wait): | |
| wait = lambda td=wait: time.sleep(td) | |
| for ans in self.iter_measure(**kw): | |
| if ans is not None: | |
| return ans | |
| wait() | |
| def iter_measure(self, **kw): | |
| for raw in self._iter_raw_measure(**kw): | |
| if raw is not None: | |
| yield self._as_reading(raw) | |
| else: yield None | |
| def _as_reading(self, raw) : | |
| h = round(raw['h'] / 65535., 6) | |
| temp_raw = round(raw['t'] / 65535., 6) | |
| return dict(h=h, | |
| t_f=self._temp_f(temp_raw), | |
| t_c=self._temp_c(temp_raw), | |
| t_r=temp_raw) | |
| def _temp_f(self, temp_raw): | |
| return round(-49 + 315 * temp_raw, 2) | |
| def _temp_c(self, temp_raw): | |
| return round(-45 + 175 * temp_raw, 2) | |
| _measure_cmd = { | |
| ('normal', 'clock', 'th'): 0x7CA2, | |
| ('normal', 'clock', 'ht'): 0x5C24, | |
| ('normal', 'poll', 'th'): 0x7866, | |
| ('normal', 'poll', 'ht'): 0x58E0, | |
| ('low', 'clock', 'th'): 0x6458, | |
| ('low', 'clock', 'ht'): 0x44DE, | |
| ('low', 'poll', 'th'): 0x609C, | |
| ('low', 'poll', 'ht'): 0x401A, | |
| } | |
| def _iter_raw_measure(self, low_power=False, clock=False, humdity_first=False): | |
| cmd = self._measure_cmd[ | |
| "low" if low_power else "normal", | |
| "clock" if clock else "poll", | |
| "ht" if humdity_first else "th"] | |
| self._send_cmd(cmd) | |
| reading = None | |
| while reading is None: | |
| reading = self._raw_reading(humdity_first) | |
| yield reading | |
| def _raw_reading(self, humdity_first): | |
| raw = i2c_msg.read(self.addr, 6) | |
| try: self.bus.i2c_rdwr(raw) | |
| except IOError: | |
| return None | |
| if humdity_first: | |
| [h_hi, h_low, h_crc, t_hi, t_low, t_crc] = raw | |
| else: | |
| [t_hi, t_low, t_crc, h_hi, h_low, h_crc] = raw | |
| t = (t_hi << 8) | t_low | |
| h = (h_hi << 8) | h_low | |
| return dict(t=t, h=h, t_crc=t_crc, h_crc=h_crc) | |
| def _send_cmd(self, cmd, len_read=None): | |
| c0 = (cmd >> 8) & 0xff | |
| c1 = (cmd >> 0) & 0xff | |
| mc = i2c_msg.write(self.addr, [c0,c1]) | |
| if len_read is None: | |
| return self.bus.i2c_rdwr(mc) | |
| else: | |
| mr = i2c_msg.read(self.addr, len_read) | |
| self.bus.i2c_rdwr(mc, mr) | |
| return list(mr) | |
| @classmethod | |
| @contextmanager | |
| def with_bus_addr(klass, bus_id=0x01, addr=0x70): | |
| with SMBus(bus_id) as bus: | |
| yield klass(bus, addr) |
Thank you for this. Helped me a lot!