Skip to content

Commit 33dd86d

Browse files
author
Holger Fleischmann
committed
Added support for TSic 506 and 716 type sensors
1 parent 815bd49 commit 33dd86d

3 files changed

Lines changed: 82 additions & 12 deletions

File tree

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
# python-tsic
22

3-
Receive temperature readings from TSIC 206/306 chips connected to Raspberry Pi GPIO.
4-
The module `tsic.py` requires Python 3 and the great library `pigpio` for GPIO access with precise timing.
3+
Receive temperature readings from TSIC chips connected to Raspberry Pi GPIO.
54

6-
It provides three major classes:
5+
Supported:
6+
* TSic 206/306
7+
* TSic 506
8+
* TSic 706
9+
10+
The module `tsic.py` requires Python 3 and the great library `pigpio` for GPIO access with precise timing.
11+
12+
Note: Python 2 will not work.
13+
14+
It provides the following classes:
715
* `TsicInputChannel` receive temperature measurements
816
* `Measurement` a temperature measurement
17+
* `TsicType` TSic type definition with instances `TSIC206`, `TSIC306`, `TSIC506`, `TSIC716` (206 and 306 are currently equivalent)
918
* `ZacWireInputChannel` receive byte packets over ZACWire protocol (low-level handler for TsicInputChannel)
1019

11-
See `example.py` for API usage or start `tsic.py <gpio-bcm> [--loop]` to read temperatures from a GPIO pin (Broadcom numbering).
20+
See `example.py` for API usage or start `tsic.py <gpio-bcm> [--type {206,506,716,306}] [--loop]` to read temperatures from a GPIO pin (Broadcom numbering). See `tsic.py --help` for command line usage.
1221

1322
Greetings from Bavaria
1423
Holger

example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
__license__ = 'Apache License 2.0'
1111

1212
import pigpio
13-
from tsic import TsicInputChannel, Measurement
13+
from tsic import TsicInputChannel, Measurement, TSIC306
1414
import time
1515

1616
# TsicInputChannel and ZacWireInputChannel require pigpio
1717
# for GPIO access with precise timing:
1818
pi = pigpio.pi()
1919

20-
tsic = TsicInputChannel(pigpio_pi=pi, gpio=17)
20+
tsic = TsicInputChannel(pigpio_pi=pi, gpio=17, tsic_type=TSIC306)
2121

2222
print('\nA. Single measurement:')
2323
print(tsic.measure_once(timeout=1.0))

tsic.py

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
__license__ = 'Apache License 2.0'
1313

1414
from datetime import datetime
15+
from functools import partial
1516
import argparse
1617
import logging
1718

@@ -228,18 +229,65 @@ def __repr__(self, *args, **kwargs):
228229
""" Undefined measurement """
229230

230231

232+
class TsicType(object):
233+
"""
234+
Definition of a TSic type.
235+
"""
236+
237+
def __init__(self, name, bytes_to_celcius_func):
238+
self.name = name
239+
self.__bytes_to_celcius_func = bytes_to_celcius_func
240+
241+
def bytes_to_degree_celcius(self, packet_bytes):
242+
"""
243+
Decode the received bytes of a data packet to degrees celsius.
244+
"""
245+
return self.__bytes_to_celcius_func(packet_bytes)
246+
247+
def __repr__(self, *args, **kwargs):
248+
return self.name
249+
250+
251+
def _tsic_11bit(packet_bytes, ht, lt):
252+
return ((packet_bytes[0] * 256 + packet_bytes[1]) / 2047. * (ht - lt) + lt)
253+
254+
def _tsic_14bit(packet_bytes, ht, lt):
255+
return ((packet_bytes[0] * 256 + packet_bytes[1]) / 16383. * (ht - lt) + lt)
256+
257+
258+
TSIC206 = TsicType("TSic 206/306", partial(_tsic_11bit, ht=150, lt=-50))
259+
""" TSic 206 with range from -50°C to 150°C, 11 bit resolution, +-0.5°C accuracy. Equivalent to TSIC306. """
260+
261+
TSIC306 = TSIC206
262+
""" TSic 306 with range from -50°C to 150°C, 11 bit resolution, +-0.3°C accuracy. Equivalent to TSIC206. """
263+
264+
#TSIC316 = TsicType(partial(_tsic_14bit, ht=???, lt=???))
265+
#""" TSic 316 with range from ???°C to ???°C, 14 bit resolution, +-???°C accuracy. """
266+
# ??? data-sheet not available anywhere, but 316 mentioned in the application notes
267+
268+
TSIC506 = TsicType("TSic 506", partial(_tsic_11bit, ht=60, lt=-10))
269+
""" TSic 506 with range from -10°C to 60°C, 11 bit resolution, +-0.1°C accuracy. """
270+
271+
TSIC716 = TsicType("TSic 716", partial(_tsic_14bit, ht=60, lt=-10))
272+
""" TSic 716 with range from -10°C to 60°C, 14 bit resolution, +-0.07°C accuracy. """
273+
274+
231275
class TsicInputChannel(object):
232276
"""
233-
Receive temperature measurements from a TSIC 206 or TSIC 306 sensor
277+
Receive temperature measurements from a TSIC sensor
234278
connected to a Raspberry PI GPIO channel.
279+
The default temperature decoding is set to match TSIC 206/306.
280+
Choose other tsic_type TSIC206, TSIC306, TSIC506, TSIC716 if necessary.
235281
"""
236282

237-
def __init__(self, pigpio_pi, gpio):
283+
def __init__(self, pigpio_pi, gpio, tsic_type = TSIC306):
238284
"""
239285
Initialize TSIC receiving channel.
240286
pigpio_pi is the pigpio.pi object to use for GPIO access.
241287
gpio is the as GPIO Broadcom chip number.
288+
tsic_type defines the temperature decoding.
242289
"""
290+
self.tsic_type = tsic_type
243291
self.__callback = None
244292
self.__degree_celsius = None
245293
self.__timestamp = None
@@ -316,7 +364,7 @@ def __packet_received(self, status, packet_bytes):
316364
if status == ZacWireInputChannel.STATUS_OK and len(packet_bytes) == 2:
317365

318366
with self.__lock:
319-
self.__degree_celsius = ((packet_bytes[0] * 256 + packet_bytes[1]) / 2047. * (150 + 50) - 50)
367+
self.__degree_celsius = self.tsic_type.bytes_to_degree_celcius(packet_bytes)
320368
self.__timestamp = time.time()
321369
measurement = self.measurement
322370

@@ -332,15 +380,28 @@ def __repr__(self, *args, **kwargs):
332380

333381

334382
if __name__ == '__main__':
383+
384+
tsic_types = { '206' : TSIC206,
385+
'306' : TSIC306,
386+
'506' : TSIC506,
387+
'716' : TSIC716 }
388+
335389
parser = argparse.ArgumentParser(description=
336-
'''Read temperatures from a TSIC 206/306 sensor
337-
connected to a Raspberry PI GPIO pin.''')
390+
'''Read temperatures from a TSic 206/306/506/716 sensor
391+
connected to a Raspberry PI GPIO pin.
392+
Select your TSic type to get correct temperatures.
393+
The default is TSic 206/306.''')
338394
parser.add_argument('gpio', type=int, help='GPIO pin as Broadcom number')
395+
parser.add_argument('--type', dest='type', choices=tsic_types.keys(), default='206', help='type of TSic sensor - 206/306 is default')
339396
parser.add_argument('--loop', dest='loop', action='store_const', const=True, default=False, help='print each received measurement until break')
340397
args = parser.parse_args()
341398

399+
tsic_type = tsic_types[args.type]
400+
401+
print("Receiving data from " + str(tsic_type) + "...")
402+
342403
pi = pigpio.pi()
343-
tsic = TsicInputChannel(pi, args.gpio)
404+
tsic = TsicInputChannel(pi, args.gpio, tsic_type)
344405
try:
345406
if args.loop:
346407
tsic.start(callback=lambda m: print(m))

0 commit comments

Comments
 (0)