Skip to content

Commit

Permalink
Updated to patch bit shifting problem. See issue #2.
Browse files Browse the repository at this point in the history
  • Loading branch information
John Robinson committed Feb 24, 2017
1 parent f412620 commit 9e9cada
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ __pycache__/
# Distribution / packaging
.Python
env/
env_py3/
build/
develop-eggs/
dist/
Expand Down
69 changes: 49 additions & 20 deletions Adafruit_MAX31856/max31856.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,44 +124,73 @@ def __init__(self, tc_type=MAX31856_T_TYPE, avgsel=0x0, clk=None, cs=None, do=No
self._write_register(self.MAX31856_REG_WRITE_CR0, self.MAX31856_CR0_READ_CONT)
self._write_register(self.MAX31856_REG_WRITE_CR1, self.CR1)

def _cjTempFromBytes(MSB, LSB):
"""Takes in the MSB and LSB from a Cold Junction (CJ) temperature reading and converts it into a decimal value.
This function was removed from readInternalTempC() and moved to its own method to allow for easier testing with standard values.
Args:
MSB (hex): Most significant byte of CJ temperature
LSB (hex): Least significant byte of a CJ temperature
"""
# ( ((MSB w/o +/-) shifted by number of 1 byte above LSB)
# + val_low_byte )
# >> shifted back by # of dead bits
temp_bytes = ( ((MSB & 0x7F) << 8) + LSB ) >> 2

if MSB & 0x80:
# Negative Value. Scale back by number of bits
temp_bytes -= 2**(MAX31856.MAX31856_CONST_CJ_BITS -1)

# temp_bytes*value of LSB
temp_C = temp_bytes*MAX31856.MAX31856_CONST_CJ_LSB

return temp_C

def readInternalTempC(self):
"""Return internal temperature value in degrees celsius."""
val_low_byte = self._read_register(self.MAX31856_REG_READ_CJTL)
val_high_byte = self._read_register(self.MAX31856_REG_READ_CJTH)

# ( ((val_high_byte w/o +/-) shifted by number of bits above LSB)
# + val_low_byte )
temp_bytes = ( ((val_high_byte & 0x7F) << 6) + val_low_byte )
temp_C = MAX31856._cjTempFromBytes(val_high_byte, val_low_byte)
self._logger.debug("Cold Junction Temperature {0} deg. C".format(temp_C))

if val_high_byte & 0x80:
# Negative Value. Scale back by number of bits
temp_bytes -= 2**(self.MAX31856_CONST_CJ_BITS -1)
return temp_C

def _thermocoupleTempFromBytes(byte0, byte1, byte2):
"""Converts the thermocouple byte values to a decimal value.
This function was removed from readInternalTempC() and moved to its own method to allow for easier testing with standard values.
Args:
byte2 (hex): Most significant byte of thermocouple temperature
byte1 (hex): Middle byte of thermocouple temperature
byte0 (hex): Least significant byte of a thermocouple temperature
"""
# ( ((val_high_byte w/o +/-) shifted by 2 bytes above LSB)
# + (val_mid_byte shifted by number 1 byte above LSB)
# + val_low_byte )
# >> back shift by number of dead bits
temp_bytes = ( ((byte2 & 0x7F) << 16) + (byte1 << 8) + byte0 )
temp_bytes = temp_bytes >> 5

if byte2 & 0x80:
temp_bytes -= 2**(MAX31856.MAX31856_CONST_THERM_BITS -1)

# temp_bytes*value of LSB
temp_C = temp_bytes*self.MAX31856_CONST_CJ_LSB
self._logger.debug("Cold Junction Temperature {0} deg. C".format(temp_C))
temp_C = temp_bytes*MAX31856.MAX31856_CONST_THERM_LSB

return temp_C


def readTempC(self):
"""Return the thermocouple temperature value in degrees celsius."""
val_low_byte = self._read_register(self.MAX31856_REG_READ_LTCBL)
val_mid_byte = self._read_register(self.MAX31856_REG_READ_LTCBM)
val_high_byte = self._read_register(self.MAX31856_REG_READ_LTCBH)

# ( ((val_high_byte w/o +/-) shifted by number of bits above LSB)
# + (val_mid_byte shifted by number of bits above LSB)
# + val_low_byte )
temp_bytes = ( ((val_high_byte & 0x7F) << 11) + (val_mid_byte << 3) + val_low_byte )

if val_high_byte & 0x80:
# Negative Value. Scale back by number of bits
temp_bytes -= 2**(self.MAX31856_CONST_THERM_BITS -1)

# temp_bytes*value of LSB
temp_C = temp_bytes*self.MAX31856_CONST_THERM_LSB
temp_C = MAX31856._thermocoupleTempFromBytes(val_low_byte, val_mid_byte, val_high_byte)

self._logger.debug("Thermocouple Temperature {0} deg. C".format(temp_C))

Expand Down
55 changes: 55 additions & 0 deletions Adafruit_MAX31856/test_MAX31856.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,61 @@ def test_get_internal_temperaure_reading(self):
self.assertTrue(True)
else:
self.assertTrue(False)

def test_temperature_byte_conversions(self):
'''Checks the byte conversion for various known temperature byte values.
'''
_logger.debug('test_temperature_byte_conversions()')

#-------------------------------------------#
# Test Thermocouple Temperature Conversions #
byte2 = 0x01; byte1 = 0x70; byte0 = 0x20;
decimal_temp = MAX31856._thermocoupleTempFromBytes(byte0, byte1, byte2)
self.assertEqual(decimal_temp, 23.0078125)

# Check a couple values from the datasheet
byte2 = 0b00000001; byte1 = 0b10010000; byte0 = 0b00000000;
decimal_temp = MAX31856._thermocoupleTempFromBytes(byte0, byte1, byte2)
self.assertEqual(decimal_temp, 25.0)

byte2 = 0b00000000; byte1 = 0b00000000; byte0 = 0b00000000;
decimal_temp = MAX31856._thermocoupleTempFromBytes(byte0, byte1, byte2)
self.assertEqual(decimal_temp, 0.0)

byte2 = 0b11111111; byte1 = 0b11110000; byte0 = 0b00000000;
decimal_temp = MAX31856._thermocoupleTempFromBytes(byte0, byte1, byte2)
self.assertEqual(decimal_temp, -1.0)

byte2 = 0b11110000; byte1 = 0b01100000; byte0 = 0b00000000;
decimal_temp = MAX31856._thermocoupleTempFromBytes(byte0, byte1, byte2)
self.assertEqual(decimal_temp, -250.0)

#---------------------------------#
# Test CJ Temperature Conversions #
MSB = 0x1C; LSB = 0x64;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, 28.390625)

# Check a couple values from the datasheet
MSB = 0b01111111; LSB = 0b11111100;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, 127.984375)

MSB = 0b00011001; LSB = 0b00000000;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, 25)

MSB = 0b00000000; LSB = 0b00000000;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, 0)

MSB = 0b11100111; LSB = 0b00000000;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, -25)

MSB = 0b11001001; LSB = 0b00000000;
decimal_CJ_temp = MAX31856._cjTempFromBytes(MSB, LSB)
self.assertEqual(decimal_CJ_temp, -55)


if __name__ == "__main__":
Expand Down
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
rpi.gpio


Adafruit_GPIO
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from setuptools import setup, find_packages

setup(name = 'Adafruit_MAX31856',
version = '0.0.3',
version = '0.0.4',
author = 'John Robinson',
author_email = '[email protected]',
description = 'Library for accessing the MAX31856 thermocouple temperature sensor on a Raspberry Pi.',
Expand Down

0 comments on commit 9e9cada

Please sign in to comment.