Last active
August 29, 2015 14:09
-
-
Save iwanders/44671b3cf09afe390d3e to your computer and use it in GitHub Desktop.
[Teensy] Script used to relate analogRead(39) with input voltage.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
""" | |
Script to relate Teensy 3.0 analogRead(39) values to the input voltage. | |
That's the original purpose atleast, it could probably be used to create | |
polynomials for any file in which holds measurements of: "x y" per line. | |
Datafiles included here: | |
https://gist.github.com/iwanders/44671b3cf09afe390d3e | |
""" | |
import os | |
import numpy as np | |
import matplotlib.pyplot as plt | |
def parse_file(f): | |
d = [] # data list. | |
with open(f, 'r') as f: | |
lines = f.readlines() | |
for line in lines: | |
line = line.strip() # strip newlines. | |
if (line.startswith('#')): # skip comments. | |
continue | |
a = line.split(" ") # split on spaces | |
if (len(a) < 2): # remove empty line. | |
continue | |
# get values from start and end of line, interpret as float. | |
reading = (float(a[0]), float(a[-1])) | |
d.append(reading) | |
return d | |
# sort the data on the first column. | |
def order_data(d): | |
return sorted(d, key=lambda x: x[0]) | |
# swap the first and second column. | |
def swap_cols(d): | |
nd = [] | |
for r in d: | |
nd.append((r[1], r[0])) | |
return nd | |
def perform_analysis(path, interval=(1500, 3100), xlim=(1200, 3100), | |
ylim=(1500, 4500), | |
image_path=None, plot_this_poly=None, | |
plot_ADC_inversion=True): | |
plt.clf() | |
d = parse_file(path) | |
plt.xlim(xlim) | |
plt.ylim(ylim) | |
# order on readings (as we use this as x) | |
d = swap_cols(d) | |
d = order_data(d) | |
d = swap_cols(d) | |
d = np.array(d) | |
v = d[:, 0]*1000 # millivolt | |
r = d[:, 1] # reading | |
# draw measurement scatter plot in green | |
plt.scatter(r, v, c=(0.25, 1, 0.25), alpha=0.7, label="Measurements") | |
# resample: | |
x_r = np.arange(interval[0], interval[1], 100) | |
y_r = np.interp(x_r, r, v) | |
plt.scatter(x_r, y_r, c=(1, 0.25, 0.25), alpha=0.7, label="Resampled") | |
# cubic polynomial | |
p_values_2, residuals_2, _, _, _ = np.polyfit(x_r, y_r, 2, full=True) | |
print("Coefficients P_2: %s" % p_values_2) | |
# print("Residuals: %s" % residuals_2) | |
float_values = np.polyval(p_values_2, x_r) | |
plt.plot(x_r, float_values, c=(0.5, 1, 0.2), label="Quadratic poly") | |
# quadratic polynomial | |
p_values_3, residuals_3, _, _, _ = np.polyfit(x_r, y_r, 3, full=True) | |
print("Coefficients P_3: %s" % p_values_3) | |
# print("Residuals: %s" % residuals_3) | |
float_values = np.polyval(p_values_3, x_r) | |
plt.plot(x_r, float_values, c=(0.5, 0.2, 1), label="Cubic poly") | |
if (plot_this_poly): | |
integer_values = plot_this_poly(x_r) | |
plt.plot(x_r, integer_values, c="k", linestyle='--', | |
label="Integer poly", linewidth=2) | |
diff = np.sqrt(np.mean(np.power(float_values - integer_values, 2))) | |
print("Signed difference: %f" % diff) | |
if (plot_ADC_inversion): | |
cal_pos = 3.3 * 1000.0; | |
analogread_at_3v3 = np.interp(np.array([cal_pos]), v[::-1], r[::-1]) | |
#(1474*3.33/4096 = 1.198344 v) | |
vref = ((analogread_at_3v3[0] * cal_pos) / 4096.0) | |
#Vcc=1.198344*4096/analogRead(39) | |
Vcc = vref * (4096.0 / x_r) | |
plt.scatter(analogread_at_3v3,[cal_pos], c="m", marker='x', | |
label="AD@3.3v:{:.2f}, vref:{:.2f}".format(analogread_at_3v3[0],vref), linewidth=2, s=50) | |
plt.plot(x_r, Vcc, c="g", linestyle='--', | |
label="({:.2f} * 4096)/x".format(vref), linewidth=2) | |
plt.xlim(xlim[0], xlim[1]) | |
plt.xlabel('analogRead(39), res=12bit, avg=32') | |
plt.title(os.path.basename(path)) | |
plt.ylabel('Input voltage measured [V]') | |
plt.legend() | |
# plt.show() | |
if (image_path): | |
plt.savefig(image_path, bbox_inches='tight', dpi=150) | |
def tainting_type(f): | |
def foo(x): | |
x = np.array(x, dtype=f) | |
return x.astype(f, casting='no') | |
return foo | |
uint32_t = tainting_type(np.uint32) | |
int32_t = tainting_type(np.int32) | |
def integer_poly_vin_T30(): | |
coeffs = np.array([4.79305738e-04, 3.18084349e+00, 7.22111948e+03]) | |
# x is in [1400, 3000] | |
uint32_t_max = 2**32 - 1 | |
x_max = 3000 | |
# calculate scale such that it does not overflow. | |
scale = uint32_t_max / (coeffs[0] * x_max**2 + coeffs[2]) | |
print("Scale: {}".format(scale)) | |
c_scaled = [uint32_t(coeffs[i]*scale) for i in (0, 1, 2)] | |
print("C0: {}".format(c_scaled[0])) | |
print("C1: {}".format(c_scaled[1])) | |
print("C2: {}".format(c_scaled[2])) | |
print("Calculation in C:") | |
print("output = ({C0:}*x*x + {C2:} - {C1:} * x) / {scale:};".format(**{ | |
"C0": c_scaled[0], | |
"C1": c_scaled[1], | |
"C2": c_scaled[2], | |
"scale": uint32_t(scale)})) | |
def foo(x): | |
xi = uint32_t(x) | |
return uint32_t((uint32_t(uint32_t(c_scaled[0] * xi**2) + | |
uint32_t(c_scaled[2])) - uint32_t(c_scaled[1] * xi)) | |
/ uint32_t(scale)) | |
return foo | |
def integer_poly_vin_T31(): | |
coeffs = np.array([ 4.80021836e-04, 3.17930738e+00, 7.23180952e+03]) | |
# x is in [1400, 3000] | |
uint32_t_max = 2**32 - 1 | |
x_max = 3000 | |
# calculate scale such that it does not overflow. | |
scale = uint32_t_max / (coeffs[0] * x_max**2 + coeffs[2]) | |
print("Scale: {}".format(scale)) | |
c_scaled = [uint32_t(coeffs[i]*scale) for i in (0, 1, 2)] | |
print("C0: {}".format(c_scaled[0])) | |
print("C1: {}".format(c_scaled[1])) | |
print("C2: {}".format(c_scaled[2])) | |
print("Calculation in C:") | |
print("output = ({C0:}*x*x + {C2:} - {C1:} * x) / {scale:};".format(**{ | |
"C0": c_scaled[0], | |
"C1": c_scaled[1], | |
"C2": c_scaled[2], | |
"scale": uint32_t(scale)})) | |
def foo(x): | |
xi = uint32_t(x) | |
return uint32_t((uint32_t(uint32_t(c_scaled[0] * xi**2) + | |
uint32_t(c_scaled[2])) - uint32_t(c_scaled[1] * xi)) | |
/ uint32_t(scale)) | |
return foo | |
def integer_poly_3v3_TLC(): | |
coeffs = np.array([ 7.75866783e-04, 4.17213376e+00, 7.27723148e+03]) | |
# x is in [1400, 3000] | |
uint32_t_max = 2**32 - 1 | |
x_max = 2600 | |
# calculate scale such that it does not overflow. | |
scale = uint32_t_max / (coeffs[0] * x_max**2 + coeffs[2]) | |
print("Scale: {}".format(scale)) | |
c_scaled = [uint32_t(coeffs[i]*scale) for i in (0, 1, 2)] | |
print("C0: {}".format(c_scaled[0])) | |
print("C1: {}".format(c_scaled[1])) | |
print("C2: {}".format(c_scaled[2])) | |
print("Calculation in C:") | |
print("output = ({C0:}*x*x + {C2:} - {C1:} * x) / {scale:};".format(**{ | |
"C0": c_scaled[0], | |
"C1": c_scaled[1], | |
"C2": c_scaled[2], | |
"scale": uint32_t(scale)})) | |
def foo(x): | |
xi = uint32_t(x) | |
return uint32_t((uint32_t(uint32_t(c_scaled[0] * xi**2) + | |
uint32_t(c_scaled[2])) - uint32_t(c_scaled[1] * xi)) | |
/ uint32_t(scale)) | |
return foo | |
def integer_poly_vin_TLC(): | |
coeffs = np.array([ 7.53720089e-04, 4.06922934e+00, 7.19510440e+03]) | |
# x is in [1400, 3000] | |
uint32_t_max = 2**32 - 1 | |
x_max = 2700 | |
# calculate scale such that it does not overflow. | |
scale = uint32_t_max / (coeffs[0] * x_max**2 + coeffs[2]) | |
print("Scale: {}".format(scale)) | |
c_scaled = [uint32_t(coeffs[i]*scale) for i in (0, 1, 2)] | |
print("C0: {}".format(c_scaled[0])) | |
print("C1: {}".format(c_scaled[1])) | |
print("C2: {}".format(c_scaled[2])) | |
print("Calculation in C:") | |
print("output = ({C0:}*x*x + {C2:} - {C1:} * x) / {scale:};".format(**{ | |
"C0": c_scaled[0], | |
"C1": c_scaled[1], | |
"C2": c_scaled[2], | |
"scale": uint32_t(scale)})) | |
def foo(x): | |
xi = uint32_t(x) | |
return uint32_t((uint32_t(uint32_t(c_scaled[0] * xi**2) + | |
uint32_t(c_scaled[2])) - uint32_t(c_scaled[1] * xi)) | |
/ uint32_t(scale)) | |
return foo | |
if __name__ == "__main__": | |
print("Analysing 3v3 input measurements.") | |
perform_analysis("to_3v3.txt", | |
interval=(1252, 3000), | |
image_path=os.path.join("to_3v3.png")) | |
print("\nAnalysing Vin input measurements.") | |
perform_analysis("to_Vin.txt",image_path="to_Vin.png", | |
plot_this_poly=integer_poly_vin_T30()) | |
print("\nAnalysing 3v3 input measurements, T3.1") | |
perform_analysis("to_Vin_T3.1.txt",image_path="to_Vin_T3.1.png", | |
plot_this_poly=integer_poly_vin_T31()) | |
print("\nAnalysing Vin input measurements, Teensy LC") | |
perform_analysis("to_Vin_LC.txt",image_path="to_Vin_LC.png", | |
interval=(1246,2500), | |
xlim=(1200,2600), | |
plot_this_poly=integer_poly_vin_TLC()) | |
print("\nAnalysing 3v3 input measurements, Teensy LC") | |
perform_analysis("to_3v3_LC.txt",image_path="to_3v3_LC.png", | |
interval=(1150,2510), | |
xlim=(1100,2600), | |
plot_this_poly=integer_poly_3v3_TLC()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Supply to 3.3v: | |
#Volt Reading | |
3.75 1310 | |
3.66 1343 | |
3.58 1373 | |
3.35 1467 | |
3.22 1530 | |
2.99 1639 | |
3.45 1425 | |
3.07 1601 | |
2.67 1842 | |
2.26 2186 | |
1.98 2498 | |
1.90 2597 | |
1.70 2911 | |
1.65 3000 | |
1.69 2931 | |
1.92 2583 | |
2.45 2012 | |
2.62 1888 | |
3.33 1474 | |
3.69 1333 | |
3.74 1314 | |
3.78 1299 | |
3.50 1405 | |
3.57 1379 | |
2.95 1662 | |
2.71 1812 | |
2.38 2070 | |
1.89 2609 | |
2.47 1996 | |
3.68 1336 | |
3.53 1393 | |
3.38 1456 | |
3.10 1593 | |
2.49 1978 | |
2.21 2236 | |
1.88 2634 | |
2.54 1940 | |
2.70 1823 | |
3.16 1553 | |
3.46 1422 | |
3.04 1621 | |
3.18 1549 | |
3.50 1404 | |
3.87 1273 | |
3.93 1252 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Supply to Vin: | |
# analogReference(INTERNAL); | |
# analogReadResolution(12); | |
# analogReadAveraging(32); | |
# PMC_REGSC |= PMC_REGSC_BGBE; | |
#Volt Reading | |
3.55 1151 | |
3.27 1252 | |
3.09 1329 | |
2.82 1452 | |
2.68 1528 | |
2.50 1645 | |
2.24 1839 | |
2.03 2026 | |
1.81 2270 | |
1.75 2350 | |
1.65 2493 | |
1.64 2510 | |
# shuts down around here... | |
1.69 2436 | |
1.87 2203 | |
1.92 2151 | |
1.97 2096 | |
2.10 1960 | |
2.33 1764 | |
2.44 1684 | |
2.51 1637 | |
2.55 1611 | |
2.62 1566 | |
2.74 1494 | |
2.93 1397 | |
3.01 1362 | |
3.12 1315 | |
3.23 1264 | |
3.31 1235 | |
3.34 1224 | |
3.41 1200 | |
3.45 1187 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Supply to Vin: | |
#Volt Reading | |
3.43 1562 | |
3.37 1596 | |
3.71 1468 | |
3.23 1677 | |
3.05 1782 | |
2.88 1908 | |
2.60 2146 | |
2.21 2598 | |
4.98 1464 | |
5.35 1460 | |
5.58 1455 | |
5.20 1462 | |
4.74 1465 | |
4.61 1465 | |
4.41 1466 | |
4.17 1466 | |
3.91 1466 | |
3.59 1489 | |
3.31 1624 | |
#Second batch of measurements | |
2.30 2456 | |
2.88 1899 | |
3.06 1778 | |
3.27 1652 | |
2.68 2066 | |
2.16 2667 | |
2.75 2002 | |
2.27 2527 | |
1.97 2982 | |
2.14 2695 | |
2.47 2282 | |
2.29 2503 | |
2.15 2675 | |
2.07 2802 | |
2.86 1916 | |
2.02 2901 | |
2.59 2154 | |
2.36 2402 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Supply to Vin: | |
# analogReference(INTERNAL); | |
# analogReadResolution(12); | |
# analogReadAveraging(32); | |
# PMC_REGSC |= PMC_REGSC_BGBE; | |
#Volt Reading | |
1.69 2495 | |
1.76 2392 | |
1.79 2354 | |
1.92 2180 | |
1.99 2105 | |
2.06 2024 | |
2.20 1896 | |
2.32 1799 | |
2.42 1717 | |
2.55 1626 | |
2.63 1577 | |
2.74 1505 | |
2.87 1440 | |
3.03 1369 | |
3.10 1332 | |
3.20 1291 | |
3.34 1246 | |
3.40 1245 | |
3.72 1245 | |
3.79 1245 | |
4.00 1245 | |
4.34 1245 | |
4.59 1244 | |
4.87 1232 | |
5.04 1241 | |
5.43 1234 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Supply to Vin: | |
#Volt Reading | |
3.35 1610 | |
2.87 1927 | |
2.48 2289 | |
2.00 2988 | |
2.19 2652 | |
2.43 2344 | |
2.93 1882 | |
3.42 1586 | |
3.90 1469 | |
4.28 1469 | |
3.70 1469 | |
3.54 1519 | |
4.78 1467 | |
3.94 1469 | |
3.62 1483 | |
3.40 1593 | |
3.07 1784 | |
2.91 1895 | |
2.62 2151 | |
3.87 1469 | |
2.91 1896 | |
2.03 2928 | |
2.37 2405 | |
2.62 2144 | |
2.57 2197 | |
2.13 2740 | |
2.01 2974 | |
2.13 2744 | |
2.25 2567 | |
2.71 2061 | |
3.11 1754 | |
3.15 1731 | |
3.19 1703 | |
3.38 1593 | |
3.69 1469 | |
3.26 1660 | |
2.33 2450 | |
2.18 2663 | |
2.17 2677 | |
2.25 2557 | |
2.03 2918 | |
2.07 2839 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment