import argparse
import sys
import time
+import struct
from pt100_board import PT100BoardDatagram
0xd: 'multiplex',
}
+default_register_values = [
+ (0x0, 0x0057), # Channel configuration = 87
+ (0x1, 0x0057),
+ (0x2, 0x0057),
+ (0x3, 0x0057),
+ (0x4, 0x0057),
+ (0x5, 0x0057),
+ (0x6, 0x0057),
+ (0x7, 0x0057),
+ (0x8, 0x0000), # nominal offset
+ (0x9, 0xd260), # gain*current = 53856
+ (0xA, 0x00fa), # sample period 250
+ (0xB, 0x0000), # lcd off
+ (0xC, 0x0000), # averaging over (0x1 + 1 =) 2 samples
+ (0xD, 0x0001), # multiplexing the channels is ON
+ ]
+
+DEFAULT_TIMEOUT = 0.1
+
def parse_uint_tuple(text):
return tuple(parse_uint(el) for el in text.split(','))
parser.add_argument('--reload-configuration', '-r', action='store_true', help='Reload the configuration of the board')
args = parser.parse_args()
- ser = serial.Serial(args.device, baudrate=38400, timeout=0.1)
+ ser = serial.Serial(args.device, baudrate=38400, timeout=DEFAULT_TIMEOUT)
ser.read(1024) # clear input buffers when opening device...
def send(cmd, verbose=True):
print('Writing 0x{2:04X} = {2:d} to address 0x{1:02X} of board 0x{0:01X}'.format(board_id, address, value))
send('WE{:1X}0{:02X}{:04X}\n'.format(board_id, address, value))
+ def reload(board_id):
+ time.sleep(.2)
+ send('WR{:1X}0000000\n'.format(board_id))
+ ser.flush()
+ time.sleep(.2)
+
def read_eeprom(board_id, address, verbose=True):
ser.read(1024) # clear input buffers before sending new command...
send('WG{:1X}0{:02X}0000\n'.format(board_id, address), verbose=verbose)
answer = False
while (time.time() - start) < 0.99:
recv = ser.readline()
- if recv:
+ if recv and len(recv) >= 10:
if verbose: print('Received answer:', recv)
recv = recv.strip(b'\x00').decode('ascii').strip()
if not recv.startswith('AG'): continue
return val
raise TimeoutError('No answer received. Old board without read eeprom support?')
+ def read_temperature(board_id, sensor, averages=1, timeout=10):
+ start = time.time()
+ ser.timeout = 0.001
+ while (time.time() - start) < 0.5:
+ recv = ser.readline()
+ ser.timeout = DEFAULT_TIMEOUT
+ values = []
+ start = time.time()
+ while (time.time() - start) < timeout:
+ recv = ser.readline()
+ if recv:
+ try:
+ dg = PT100BoardDatagram(recv)
+ except:
+ continue
+ if dg.kind == 'temperature' and dg.sensor == sensor and dg.connected:
+ values.append(dg.temperature)
+ if len(values) == averages:
+ return sum(values)/averages
+ if len(values) == 0:
+ sys.stdout.write("Didn't receive any temperature samples\n")
+ else:
+ sys.stdout.write("Didn't receive enough temperature samples ({} instead of {})\n".format(len(values), averages))
+ sys.stdout.flush()
+ return None
+
if args.read_eeprom is not None:
read_eeprom(args.board_id, args.read_eeprom, verbose=True)
print('Do you really want to initialize the board with a new set of EEPROM configuration data?')
print('Your current values will be lost!!! This only makes sense for brand new boards!')
input('Press enter to continue or Ctrl-c to abort.')
- new_vals = [
- (0x0, 0x0057), # Channel configuration = 87
- (0x1, 0x0057),
- (0x2, 0x0057),
- (0x3, 0x0057),
- (0x4, 0x0057),
- (0x5, 0x0057),
- (0x6, 0x0057),
- (0x7, 0x0057),
- (0x8, 0x0000), # nominal offset
- (0x9, 0xd260), # gain*current = 53856
- (0xA, 0x00fa), # sample period 250
- (0xB, 0x0000), # lcd off
- (0xC, 0x0000), # averaging over (0x1 + 1 =) 2 samples
- ]
print("Current values of the EEPROM:")
- for reg_addr, new_reg_val in new_vals:
+ for reg_addr, default_reg_val in default_register_values:
old_reg_val = read_eeprom(args.board_id, reg_addr, verbose=False)
- print("Address: 0x{:02X} Old Value: 0x{:04X} New Value: 0x{:04X}".format(reg_addr, old_reg_val, new_reg_val))
+ print("Address: 0x{:02X} Old Value: 0x{:04X} New Value: 0x{:04X}".format(reg_addr, old_reg_val, default_reg_val))
input('Press enter to continue or Ctrl-c to abort.')
- for reg_addr, reg_val in new_vals:
- write_register(args.board_id, reg_addr, reg_val)
+ for reg_addr, default_reg_val in default_register_values:
+ write_register(args.board_id, reg_addr, default_reg_val)
print("Done initializing the EEPROM")
time.sleep(0.1)
if args.calibrate:
+ print("Current values of the EEPROM:")
+ for reg_addr, default_reg_val in default_register_values:
+ old_reg_val = read_eeprom(args.board_id, reg_addr, verbose=False)
+ print("Address: 0x{:02X} Old Value: 0x{:04X}".format(reg_addr, old_reg_val))
+ input('Press enter to continue or Ctrl-c to abort.')
+
print("OK, starting the calibration.")
- for channel in range(8):
- print("Channel", channel)
- inp = input("Enter [c] to continue, anything else will skip this channel.")
- if inp != 'c':
- print("Skipping channel", channel)
+
+ print("starting with default values")
+ # set channel offsets to zero:
+ for reg_addr in range(8):
+ write_register(args.board_id, reg_addr, 0x0000)
+ time.sleep(0.1)
+ # reset gain to default value:
+ write_register(args.board_id, default_register_values[0x9][0], default_register_values[0x9][1])
+ reload(args.board_id)
+
+ print("calibrating the gain")
+
+ def calibrate_offset(board_id, sensor, averages=5):
+ input("Connect the 100 Ohm reference to sensor slot #{} (and wiggle the plug around to asure a good contact)! Press [Enter], when ready.".format(sensor))
+ mean_temperature_before = read_temperature(board_id, sensor, averages=averages, timeout=20)
+ print("mean temperature before correction: {}".format(mean_temperature_before))
+ offset_value = int(round( - mean_temperature_before * 396))
+ tc_number = (num for num in struct.pack('>h', offset_value))
+ offset_value = int('{:02X}{:02X}'.format(*tc_number), 16)
+ write_register(board_id, 0x00 + sensor, offset_value)
+ reload(args.board_id)
+ mean_temperature_after = read_temperature(board_id, sensor, averages=averages, timeout=20)
+ print("mean temperature after correction: {}".format(mean_temperature_after))
+
+ calibrate_offset(args.board_id, 0)
+
+ input("Connect the 120 Ohm reference to sensor slot 0 (and wiggle the plug around to asure a good contact)! Press [Enter], when ready.")
+ mean_temperature_120_before = read_temperature(args.board_id, 0, averages=5, timeout=20)
+ print("mean temperature (120 Ohm) before correction: {}".format(mean_temperature_120_before))
+ expected_value = 51.578
+ new_gain = int( round( expected_value / mean_temperature_120_before * default_register_values[0x9][1] ) )
+ write_register(args.board_id, default_register_values[0x9][0], new_gain)
+ reload(args.board_id)
+ mean_temperature_120_after = read_temperature(args.board_id, 0, averages=5, timeout=20)
+ print("mean temperature after correction: {}".format(mean_temperature_120_after))
+ print("deviation from expected: {}".format(mean_temperature_120_after - expected_value))
+
+ print("calibrating the individual channel offsets")
+ for sensor in range(1, 8):
+ print("Sensor #", sensor)
+ inp = input("Enter [Enter] to continue, anything else (+ [Enter]) will skip this sensor.")
+ if inp != '':
+ print("Skipping sensor #", sensor)
continue
- print("Connect the 100Ohm reference!")
- print("Connect the 120Ohm reference!")
- print("Done with channel", channel)
+ calibrate_offset(args.board_id, sensor)
+ print("Done with sensor #", sensor)
if args.reload_configuration:
- send('WR{:1X}0000000\n'.format(args.board_id))
+ reload(args.board_id)
if __name__ == "__main__": main()