James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 1 | #!/usr/bin/python3 |
| 2 | import sys |
| 3 | import numpy as np |
| 4 | |
| 5 | # Note on associated data files: |
| 6 | # calib_data_60*.csv has each output channel set at a constant value of 60. |
Brian Silverman | 37a95d6 | 2018-11-09 16:08:32 -0800 | [diff] [blame] | 7 | # calib_data_6030*.csv actuates two channels. |
James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 8 | |
| 9 | def calibrate(fnames): |
| 10 | """Do fitting to calibrate ADC data given csv files. |
| 11 | |
| 12 | CSVs should be of format: |
Brian Silverman | 37a95d6 | 2018-11-09 16:08:32 -0800 | [diff] [blame] | 13 | command_a, command_b, command_c, reading0, reading1, reading2 |
| 14 | The command columns are the on-time for each timer in FTM ticks. |
| 15 | The reading columns in this case are the 3 samples taken from the |
| 16 | ADC (with each pair corresponding to the same measurement pre-averaged). We |
| 17 | only care about the averaged samples because otherwise the solution matrix |
| 18 | can't be solved for in a stable manner. |
James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 19 | """ |
Brian Silverman | 37a95d6 | 2018-11-09 16:08:32 -0800 | [diff] [blame] | 20 | data = np.zeros((1, 6)) |
James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 21 | for fname in fnames: |
| 22 | data = np.vstack((data, np.genfromtxt(fname, delimiter=','))) |
| 23 | data = data[1:, :] |
| 24 | |
James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 25 | data = data[:, :6] |
| 26 | |
| 27 | b = data[:, 0:3] |
| 28 | b = b - np.tile(np.mean(b, axis=1), (3, 1)).T |
| 29 | # Vcc / 3000 / R |
Brian Silverman | 37a95d6 | 2018-11-09 16:08:32 -0800 | [diff] [blame] | 30 | # 3000 converts duty cycle in FTM ticks to fraction of full. |
| 31 | b *= 20.9 / 3000.0 / 0.0079 |
James Kuszmaul | 7c8aad6 | 2018-09-08 18:16:18 -0700 | [diff] [blame] | 32 | A = data[:, 3:] |
| 33 | |
| 34 | return np.linalg.lstsq(A, b[:])[0].T |
| 35 | |
| 36 | if __name__ == "__main__": |
| 37 | if len(sys.argv) < 2: |
| 38 | print("Need filenames for data") |
| 39 | sys.exit(1) |
| 40 | print(calibrate(sys.argv[1:])) |