Skip to content

Commit 1de8623

Browse files
committed
working except for crc
1 parent 5ac5dfb commit 1de8623

File tree

5 files changed

+218
-173
lines changed

5 files changed

+218
-173
lines changed

README.rst

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ This is easily achieved by downloading
3434

3535
Installing from PyPI
3636
=====================
37-
.. note:: This library is not available on PyPI yet. Install documentation is included
38-
as a standard element. Stay tuned for PyPI availability!
39-
40-
.. todo:: Remove the above note if PyPI version is/will be available at time of release.
41-
If the library is not planned for PyPI, remove the entire 'Installing from PyPI' section.
4237

4338
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
4439
PyPI <https://pypi.org/project/adafruit-circuitpython-shtc3/>`_. To install for current user:
@@ -65,7 +60,23 @@ To install in a virtual environment in your current project:
6560
Usage Example
6661
=============
6762

68-
.. todo:: Add a quick, simple example. It and other examples should live in the examples folder and be included in docs/examples.rst.
63+
.. code-block: python3
64+
65+
import time
66+
import busio
67+
import board
68+
import adafruit_shtc3
69+
70+
i2c = busio.I2C(board.SCL, board.SDA)
71+
sht = adafruit_shtc3.SHTC3(i2c)
72+
73+
while True:
74+
temperature, relative_humidity = sht.measurements
75+
print("Temperature: %0.1f C" % temperature)
76+
print("Humidity: %0.1f %%" % relative_humidity)
77+
print("")
78+
time.sleep(1)
79+
6980
7081
Contributing
7182
============

adafruit_shtc3.py

Lines changed: 190 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -34,170 +34,199 @@
3434
__version__ = "0.0.0-auto.0"
3535
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_SHTC3.git"
3636

37-
# Common imports remove if unused or pylint will complain
38-
from time import sleep as delay_seconds
39-
from time import monotonic
40-
import adafruit_bus_device.i2c_device as i2c_device
41-
42-
from adafruit_register.i2c_struct import UnaryStruct, ROUnaryStruct, Struct
43-
from adafruit_register.i2c_bit import RWBit, ROBit
44-
from adafruit_register.i2c_bits import RWBits
4537
from struct import unpack_from
46-
#include "Arduino.h"
47-
#include <Adafruit_I2CDevice.h>
48-
#include <Adafruit_Sensor.h>
49-
50-
_SHTC3_DEFAULT_ADDR = 0x70 # SHTC3 I2C Address
51-
_SHTC3_NORMAL_MEAS_TFIRST_STRETCH = 0x7CA2 # Normal measurement, temp first with Clock Stretch Enabled
52-
_SHTC3_LOWPOW_MEAS_TFIRST_STRETCH = 0x6458 # Low power measurement, temp first with Clock Stretch Enabled
53-
_SHTC3_NORMAL_MEAS_HFIRST_STRETCH = 0x5C24 # Normal measurement, hum first with Clock Stretch Enabled
54-
_SHTC3_LOWPOW_MEAS_HFIRST_STRETCH = 0x44DE # Low power measurement, hum first with Clock Stretch Enabled
55-
56-
_SHTC3_NORMAL_MEAS_TFIRST = 0x7866 # Normal measurement, temp first with Clock Stretch disabled
57-
_SHTC3_LOWPOW_MEAS_TFIRST = 0x609C # Low power measurement, temp first with Clock Stretch disabled
58-
_SHTC3_NORMAL_MEAS_HFIRST = 0x58E0 # Normal measurement, hum first with Clock Stretch disabled
59-
_SHTC3_LOWPOW_MEAS_HFIRST = 0x401A # Low power measurement, hum first with Clock Stretch disabled
60-
61-
_SHTC3_READID = 0xEFC8 # Read Out of ID Register
62-
_SHTC3_SOFTRESET = 0x805D # Soft Reset
63-
_SHTC3_SLEEP = 0xB098 # Enter sleep mode
64-
_SHTC3_WAKEUP = 0x3517 # Wakeup mode
65-
_SHTC3_CHIP_ID = 0x807
66-
def pb(buffer):
67-
print("buf:", [hex(i) for i in buffer])
68-
69-
class SHTC3:
70-
def __init__(self, i2c_bus, address = _SHTC3_DEFAULT_ADDR):
71-
self.i2c_device = i2c_device.I2CDevice(i2c_bus, address)
72-
73-
self._buffer = bytearray(6)
74-
self.reset()
75-
self.sleep = False
76-
if (self._chip_id & 0x083F != _SHTC3_CHIP_ID):
77-
raise RuntimeError("Failed to find an ICM20X sensor - check your wiring!")
78-
38+
import time
39+
import adafruit_bus_device.i2c_device as i2c_device
7940

80-
def _write_command(self, command):
81-
self._buffer[0] = command >> 8
82-
self._buffer[1] = command & 0xFF
83-
84-
with self.i2c_device as i2c:
85-
i2c.write(self._buffer, start=0, end=2)
86-
87-
@property
88-
def _chip_id(self): # readCommand(SHTC3_READID, data, 3);
89-
self._buffer[0] = _SHTC3_READID >> 8
90-
self._buffer[1] = _SHTC3_READID & 0xFF
91-
92-
with self.i2c_device as i2c:
93-
i2c.write_then_readinto(self._buffer, self._buffer, out_start=0, out_end=2, in_start=0, in_end=2)
94-
95-
return unpack_from(">H", self._buffer)[0]
96-
97-
def reset(self):
98-
try:
99-
self._write_command(_SHTC3_SOFTRESET)
100-
101-
except RuntimeError as run_err:
102-
if run_err.args and run_err.args[0] != "I2C slave address was NACK'd":
103-
raise run_err
104-
delay_seconds(0.001)
105-
106-
@property
107-
def sleep(self):
108-
"""Determines the sleep state of the sensor"""
109-
return self._cached_sleep
110-
111-
@sleep.setter
112-
def sleep(self, sleep_enabled):
113-
if sleep_enabled:
114-
self._write_command(_SHTC3_SLEEP)
115-
else:
116-
self._write_command(_SHTC3_WAKEUP)
117-
delay_seconds(0.001)
118-
self._cached_sleep = sleep_enabled
119-
120-
# lowPowerMode(bool readmode) { _lpMode = readmode
121-
122-
@property
123-
def relative_humidity(self):
124-
"""Current relative humidity in % rH"""
125-
self.measurements[1]
126-
return self._humidity
127-
128-
@property
129-
def temperature(self):
130-
"""Current temperature in degrees celcius"""
131-
self.measurements[0]
132-
133-
@property
134-
def measurements(self):
135-
"""both `temperature` and `relative_humidity`, read simultaneously"""
136-
137-
self.sleep = False
138-
raw_readings = []
139-
140-
if False: # check for lowPower
141-
self._write_command(_SHTC3_LOWPOW_MEAS_TFIRST)
142-
delay_seconds(0.001)
143-
else:
144-
self._write_command(_SHTC3_NORMAL_MEAS_TFIRST)
145-
delay_seconds(0.013)
146-
147-
self._buffer = bytearray(6)
148-
with self.i2c_device as i2c:
149-
i2c.readinto(self._buffer)
150-
raw_readings = unpack_from(">hbh", self._buffer)
151-
152-
153-
# check CRC of bytes
154-
# if (self._buffer[2] != crc8(self._buffer, 2) or
155-
# self._buffer[5] != crc8(self._buffer + 3, 2)):
156-
# print("NOT CHECKING")
157-
158-
raw_temp = raw_readings[0]
159-
raw_temp = ((4375 * raw_temp) >> 14) - 4500
160-
temperature = raw_temp / 100.0
161-
162-
raw_humidity = raw_readings[2]
163-
raw_humidity = (625 * raw_humidity) >> 12
164-
humidity = raw_humidity / 100.0
165-
166-
self.sleep = True
167-
return (temperature, humidity)
168-
169-
170-
171-
172-
# /**
173-
# * Performs a CRC8 calculation on the supplied values.
174-
# *
175-
# * @param data Pointer to the data to use when calculating the CRC8.
176-
# * @param len The number of bytes in 'data'.
177-
# *
178-
# * @return The computed CRC8 value.
179-
# */
180-
# static uint8_t crc8(const uint8_t *data, int len) {
181-
# /*
182-
# *
183-
# * CRC-8 formula from page 14 of SHT spec pdf
184-
# *
185-
# * Test data 0xBE, 0xEF should yield 0x92
186-
# *
187-
# * Initialization data 0xFF
188-
# * Polynomial 0x31 (x8 + x5 +x4 +1)
189-
# * Final XOR 0x00
190-
# */
19141

42+
# include "Arduino.h"
43+
# include <Adafruit_I2CDevice.h>
44+
# include <Adafruit_Sensor.h>
45+
46+
_SHTC3_DEFAULT_ADDR = 0x70 # SHTC3 I2C Address
47+
_SHTC3_NORMAL_MEAS_TFIRST_STRETCH = (
48+
0x7CA2 # Normal measurement, temp first with Clock Stretch Enabled
49+
)
50+
_SHTC3_LOWPOW_MEAS_TFIRST_STRETCH = (
51+
0x6458 # Low power measurement, temp first with Clock Stretch Enabled
52+
)
53+
_SHTC3_NORMAL_MEAS_HFIRST_STRETCH = (
54+
0x5C24 # Normal measurement, hum first with Clock Stretch Enabled
55+
)
56+
_SHTC3_LOWPOW_MEAS_HFIRST_STRETCH = (
57+
0x44DE # Low power measurement, hum first with Clock Stretch Enabled
58+
)
59+
60+
_SHTC3_NORMAL_MEAS_TFIRST = (
61+
0x7866 # Normal measurement, temp first with Clock Stretch disabled
62+
)
63+
_SHTC3_LOWPOW_MEAS_TFIRST = (
64+
0x609C # Low power measurement, temp first with Clock Stretch disabled
65+
)
66+
_SHTC3_NORMAL_MEAS_HFIRST = (
67+
0x58E0 # Normal measurement, hum first with Clock Stretch disabled
68+
)
69+
_SHTC3_LOWPOW_MEAS_HFIRST = (
70+
0x401A # Low power measurement, hum first with Clock Stretch disabled
71+
)
72+
73+
_SHTC3_READID = 0xEFC8 # Read Out of ID Register
74+
_SHTC3_SOFTRESET = 0x805D # Soft Reset
75+
_SHTC3_SLEEP = 0xB098 # Enter sleep mode
76+
_SHTC3_WAKEUP = 0x3517 # Wakeup mode
77+
_SHTC3_CHIP_ID = 0x807
19278
# const uint8_t POLYNOMIAL(0x31)
193-
# uint8_t crc(0xFF)
79+
_POLYNOMIAL = 0x31
19480

195-
# for (int j = len j --j) {
196-
# crc ^= *data++
19781

198-
# for (int i = 8 i --i) {
199-
# crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1)
200-
#
201-
#
202-
# return crc
203-
#
82+
class SHTC3:
83+
"""
84+
A driver for the SHTC3 temperature and humidity sensor.
85+
:param i2c_bus: The `busio.I2C` object to use. This is the only required parameter.
86+
:param int address: (optional) The I2C address of the device.
87+
"""
88+
89+
def __init__(self, i2c_bus):
90+
self.i2c_device = i2c_device.I2CDevice(i2c_bus, _SHTC3_DEFAULT_ADDR)
91+
92+
self._buffer = bytearray(6)
93+
self.low_power = False
94+
self.reset()
95+
self.sleep = False
96+
if self._chip_id & 0x083F != _SHTC3_CHIP_ID:
97+
raise RuntimeError("Failed to find an ICM20X sensor - check your wiring!")
98+
99+
def _write_command(self, command):
100+
self._buffer[0] = command >> 8
101+
self._buffer[1] = command & 0xFF
102+
103+
with self.i2c_device as i2c:
104+
i2c.write(self._buffer, start=0, end=2)
105+
106+
@property
107+
def _chip_id(self): # readCommand(SHTC3_READID, data, 3);
108+
self._buffer[0] = _SHTC3_READID >> 8
109+
self._buffer[1] = _SHTC3_READID & 0xFF
110+
111+
with self.i2c_device as i2c:
112+
i2c.write_then_readinto(
113+
self._buffer, self._buffer, out_start=0, out_end=2, in_start=0, in_end=2
114+
)
115+
116+
return unpack_from(">H", self._buffer)[0]
117+
118+
def reset(self):
119+
"""Perform a soft reset of the sensor, resetting all settings to their power-on defaults"""
120+
try:
121+
self._write_command(_SHTC3_SOFTRESET)
122+
123+
except RuntimeError as run_err:
124+
if run_err.args and run_err.args[0] != "I2C slave address was NACK'd":
125+
raise run_err
126+
time.sleep(0.001)
127+
128+
@property
129+
def sleep(self):
130+
"""Determines the sleep state of the sensor"""
131+
return self._cached_sleep
132+
133+
@sleep.setter
134+
def sleep(self, sleep_enabled):
135+
if sleep_enabled:
136+
self._write_command(_SHTC3_SLEEP)
137+
else:
138+
self._write_command(_SHTC3_WAKEUP)
139+
time.sleep(0.001)
140+
self._cached_sleep = sleep_enabled
141+
142+
# lowPowerMode(bool readmode) { _lpMode = readmode
143+
144+
@property
145+
def low_power(self):
146+
"""Enables the less accurate low power mode, trading accuracy for power consumption"""
147+
return self._low_power
148+
149+
@low_power.setter
150+
def low_power(self, low_power_enabled):
151+
self._low_power = low_power_enabled
152+
153+
@property
154+
def relative_humidity(self):
155+
"""Current relative humidity in % rH"""
156+
return self.measurements[1]
157+
158+
@property
159+
def temperature(self):
160+
"""Current temperature in degrees celcius"""
161+
return self.measurements[0]
162+
163+
@property
164+
def measurements(self):
165+
"""both `temperature` and `relative_humidity`, read simultaneously"""
166+
167+
self.sleep = False
168+
raw_readings = []
169+
170+
if self.low_power:
171+
self._write_command(_SHTC3_LOWPOW_MEAS_TFIRST)
172+
time.sleep(0.001)
173+
else:
174+
self._write_command(_SHTC3_NORMAL_MEAS_TFIRST)
175+
time.sleep(0.013)
176+
177+
self._buffer = bytearray(6)
178+
with self.i2c_device as i2c:
179+
i2c.readinto(self._buffer)
180+
raw_readings = unpack_from(">hbh", self._buffer)
181+
182+
# print("CRC8-ing some beef:", hex(self._crc8(bytearray([0xBE, 0xEF]), 2)))
183+
# check CRC of bytes
184+
# if (self._buffer[2] != crc8(self._buffer, 2) or
185+
# self._buffer[5] != crc8(self._buffer + 3, 2)):
186+
# print("NOT CHECKING")
187+
188+
raw_temp = raw_readings[0]
189+
raw_temp = ((4375 * raw_temp) >> 14) - 4500
190+
temperature = raw_temp / 100.0
191+
192+
raw_humidity = raw_readings[2]
193+
raw_humidity = (625 * raw_humidity) >> 12
194+
humidity = raw_humidity / 100.0
195+
196+
self.sleep = True
197+
return (temperature, humidity)
198+
199+
## CRC-8 formula from page 14 of SHT spec pdf
200+
#
201+
# Test data 0xBE, 0xEF should yield 0x92
202+
#
203+
# Initialization data 0xFF
204+
# Polynomial 0x31 (x8 + x5 +x4 +1)
205+
# Final XOR 0x00
206+
207+
# @staticmethod
208+
# def _crc8(buffer, length):
209+
# print("buffer:", buffer)
210+
# crc = 0xFF
211+
# print("0: crc = ", format(crc, "#010b"))
212+
213+
# buff_index = 0
214+
# for i in range(length):
215+
# curr_buff = buffer[i]
216+
# print("buffer[%d]" % i, hex(curr_buff), format(curr_buff, "#010b"))
217+
# crc ^= curr_buff
218+
# print("1 crc = ", format(crc, "#010b"))
219+
220+
# for i in range(8):
221+
# print("crc & 0x80: ", format(crc & 0x80, "#010b"))
222+
# crc_shift_one = (crc << 1)
223+
# if crc & 0x80: # if crc top bit is set
224+
# print("yes")
225+
# crc = crc_shift_one ^ _POLYNOMIAL
226+
# else:
227+
# print("no")
228+
# crc = crc_shift_one
229+
# print("3 crc = crc << 1", format(crc, "#010b"))
230+
# print("\t*** NEXT BIT **")
231+
# print("*** NEXT BYTE **")
232+
# return crc

0 commit comments

Comments
 (0)