]> jspc29.x-matter.uni-frankfurt.de Git - labtools.git/commitdiff
pt100: major upgrade of pt100_config & new cli pt100_csv_readback
authorPhilipp Klaus <klaus@physik.uni-frankfurt.de>
Mon, 28 Aug 2017 13:05:16 +0000 (15:05 +0200)
committerPhilipp Klaus <klaus@physik.uni-frankfurt.de>
Mon, 28 Aug 2017 13:05:22 +0000 (15:05 +0200)
sensors/pt100-board-python-package/pt100_board/pt100_config.py
sensors/pt100-board-python-package/pt100_board/pt100_csv_readback.py [new file with mode: 0644]
sensors/pt100-board-python-package/pt100_board/pt100_reader.py
sensors/pt100-board-python-package/setup.py

index 2f1d481d26bfa2aa48034102e3a28cdc6e3f86f6..5d83e4409c791066f1f4cca3f554483c4e6f08e9 100755 (executable)
@@ -12,6 +12,11 @@ except ImportError:
     sys.stderr.write("Could not import the PySerial module. Please install it first.\n")
     sys.exit(1)
 
+try:
+    input = raw_input
+except:
+    pass
+
 REGISTER_NAMES = {
     0x0: 'channel 0 offset',
     0x1: 'channel 1 offset',
@@ -47,42 +52,46 @@ def main():
     parser.add_argument('--write-eeprom', type=parse_uint, metavar=('ADDR','VALUE'), nargs=2, help='write uint16 value to address in eeprom; first arg: ADDR, second: VALUE')
     parser.add_argument('--period', type=float, help='Set conversion period in ms')
     parser.add_argument('--average', type=parse_uint, help='Number of temperature values to average over (1 to 16, reduces the output frequency).')
+    parser.add_argument('--calibrate', action='store_true', help='Run the calibration procedure for all channels')
     parser.add_argument('--initialize', action='store_true', help='Initialize a new board with sensible default EEPROM values. Use with caution.')
     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.read(1024) # clear input buffers when opening device...
 
-    def send(cmd):
-        print('Sending command:', cmd.strip())
+    def send(cmd, verbose=True):
+        if verbose: print('Sending command:', cmd.strip())
         ser.write(cmd.encode('ascii'))
 
     def write_register(board_id, address, value):
         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 read_eeprom(board_id, address):
-        send('WG{:1X}0{:02X}0000\n'.format(board_id, address))
+    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)
         start = time.time()
-        print('---')
+        if verbose: print('---')
         answer = False
-        while (time.time() - start) < 0.3:
+        while (time.time() - start) < 0.99:
             recv = ser.readline()
             if recv:
+                if verbose: print('Received answer:', recv)
                 recv = recv.strip(b'\x00').decode('ascii').strip()
                 if not recv.startswith('AG'): continue
-                answer = True
-                print('Received answer:', recv)
                 addr = int(recv[4:6],  16)
                 val  = int(recv[6:10], 16)
-                print('Value stored at address 0x{:02X}: 0x{:04X}'.format(addr, val))
+                if addr != address:
+                    continue
+                if verbose: print('Value stored at address 0x{:02X}: 0x{:04X}'.format(addr, val))
                 if addr in REGISTER_NAMES:
-                    print('Register name:', REGISTER_NAMES[addr])
-                break
-        if not answer: print('No answer received so far. Try again?')
+                    if verbose: print('Register name:', REGISTER_NAMES[addr])
+                return val
+        raise TimeoutError('No answer received. Old board without read eeprom support?')
 
     if args.read_eeprom is not None:
-        read_eeprom(args.board_id, args.read_eeprom)
+        read_eeprom(args.board_id, args.read_eeprom, verbose=True)
 
     if args.write_eeprom is not None:
         write_register(args.board_id, *args.write_eeprom)
@@ -105,20 +114,49 @@ def main():
         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.')
-        for i in range(8):
-            write_register(args.board_id, i, 0x57)
-        write_register(args.board_id, 0x8, 0xffff)
-        write_register(args.board_id, 0x9, 0xd211)
-        write_register(args.board_id, 0xa, 250)
-        write_register(args.board_id, 0xb, 0x1)
-        write_register(args.board_id, 0xc, 0x1)
+        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:
+            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))
+        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)
+
         print("Done initializing the EEPROM")
+
         if not args.reload_configuration:
             print("You didn't choose to reload the configuration. The new values will only be used once reloaded or power cycled.")
             print("Consider using the -r option.")
         else:
             time.sleep(0.1)
 
+    if args.calibrate:
+        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)
+                continue
+            print("Connect the 100Ohm reference!")
+            print("Connect the 120Ohm reference!")
+            print("Done with channel", channel)
+
     if args.reload_configuration:
         send('WR{:1X}0000000\n'.format(args.board_id))
 
diff --git a/sensors/pt100-board-python-package/pt100_board/pt100_csv_readback.py b/sensors/pt100-board-python-package/pt100_board/pt100_csv_readback.py
new file mode 100644 (file)
index 0000000..7c9f175
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+def readback_csv_file_numpy(filename):
+    import numpy as np
+    with open(filename, 'r') as f:
+        first_line = f.readline()
+        if 'sensor0' in first_line:
+            skiprows = 1
+        else:
+            skiprows = 0
+    return np.loadtxt(filename, skiprows=1)
+
+def readback_csv_file_pandas(filename):
+    import pandas as pd
+    df = pd.read_csv(filename, delimiter=' ')
+    print([df.columns])
+    if 'reltime' in df.columns:
+        timecol = 'reltime'
+    elif 'abstime' in df.columns:
+        timecol = 'reltime'
+    df = df.set_index(['boardid', timecol])
+    return df
+
+def main():
+    from argparse import ArgumentParser
+    from matplotlib import pyplot as plt
+    parser = ArgumentParser()
+    parser.add_argument('csv_file')
+    args = parser.parse_args()
+    df = readback_csv_file_pandas(args.csv_file)
+    df.loc[0,:].plot()
+    df.loc[1,:].plot()
+    plt.show()
+
+if __name__ == "__main__": main()
index 66276ee85cac3b80a8e4eb9a053da54deada26a8..4d87ef37c98708f7aca0e3c633db30258b0113ea 100755 (executable)
@@ -17,6 +17,7 @@ except ImportError:
 def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('--plot', action='store_true', help='Real time plot of the temperatures')
+    parser.add_argument('--verbose', action='store_true', help='Enable verbose mode where also disconnected sensors and other datagrams are shown')
     parser.add_argument('device', help='The serial port to open')
     args = parser.parse_args()
 
@@ -49,10 +50,10 @@ def main():
                 if dg.connected:
                     sensor_values['{}.{}'.format(dg.board, dg.sensor)] = dg.temperature
                 else:
-                    continue
+                    if not args.verbose: continue
+                sys.stdout.write('{}.{} {}\n'.format(dg.board, dg.sensor, dg.temperature))
             else:
-                continue
-            sys.stdout.write('{}.{} {}\n'.format(dg.board, dg.sensor, dg.temperature))
+                if args.verbose: sys.stdout.write('other datagram received: ' + chunk)
             sys.stdout.flush()
 
             now = time.time()
index 4ecf7a253d271a66488ef86e03f9588fbdae4559..50cf4ce8c0187f2ee53f1ff612c6c41fc3160188 100644 (file)
@@ -16,6 +16,7 @@ setup(name='pt100-board',
           'pt100_config         = pt100_board.pt100_config:main',
           'pt100_reader         = pt100_board.pt100_reader:main',
           'pt100_csv_reader     = pt100_board.pt100_csv_reader:main',
+          'pt100_csv_readback   = pt100_board.pt100_csv_readback:main',
           'pt100_logfile_reader = pt100_board.pt100_logfile_reader:main',
         ],
       },