PowerSensor

Voltage Dividers

In order to measure the voltages on the powerboard using the Attiny84's ADCs simple voltage dividers are used. The following script calculates the closest resistors values from the E96 (1% tolerance) resistor standard series in a voltage divider network given the input voltage V_in, the output voltage V_out and the overall current I.


In [8]:
# Input voltage
V_in = 5.8 # V
# Output voltage (corresponding to the Attiny84's internal reference voltage of 1.1V)
V_out = 1.1 # V
# Desired overall current
I = 0.001 # Ohm

# Path to CSV file containing resistor values
res_value_file = 'E96_resistor_values.csv'

# Open file and create a list with standard resistor values
f = open(res_value_file, 'r')
resistor_values = []
for line in f.readlines():
    resistor_values += [float(i) for i in line.strip().split(',')]
f.close()

# Multiply resistor values by powers of 10 to get full list of standard values
mult_cnt = 0
resistor_values_new = resistor_values
while mult_cnt <=4:
    resistor_values_new = [i*10 for i in resistor_values_new]
    resistor_values += resistor_values_new
    mult_cnt +=1

# Compute overall resistance
R_full = V_in/I

# Compute resistance of R1 and R2
R2 = R_full / (V_in / V_out)
R1 = R_full - R2

# Get standard resistance value closest to R2
R2_std = min(resistor_values, key=lambda x:abs(x-R2))

# Get standard resistance value closest to R1
R1_tmp = R_full - R2_std
R1_std = min(resistor_values, key=lambda x:abs(x-R1_tmp))

# Compute V_out with standard values
V_out_std = R2_std / (R1_std + R2_std) * V_in

# Compute I with standard values
I_std = V_in / (R1_std + R2_std)

print 'R1 closest standard value: ' + str(R1_std) + ' Ohm'
print 'R2 closest standard value: ' + str(R2_std) + ' Ohm\n'

print 'R1 optimal: ' + str(R1) + ' Ohm'
print 'R2 optimal: ' + str(R2) + ' Ohm\n'

print 'V_out with standard values at ' + str(V_in) + 'V: ' + str(V_out_std) + ' V'
print 'I with standard values at ' + str(V_in) + 'V: ' + str(I_std) + ' A\n'

print 'resolution at 16 Bit: ' + str(V_out_std / 2**16) + ' V'


R1 closest standard value: 4750.0 Ohm
R2 closest standard value: 1100.0 Ohm

R1 optimal: 4700.0 Ohm
R2 optimal: 1100.0 Ohm

V_out with standard values at 5.8V: 1.0905982906 V
I with standard values at 5.8V: 0.000991452991453 A

resolution at 16 Bit: 1.66412092682e-05 V

ADC low pass filtering

In order to get rid of high-frequency noise on the board's power lines simple RC low pass filters are implented in the input lines of the Attiny84's ADCs. Voltage measurements on the MCU are supposed to be performed with a maximum temporal resolution of 10Hz per input channel. Hence, according to the Nyquist-Shannon theorem

$$ f_{Nyquist} = \frac{1}{2}f_{sample}$$

the sample rate $f_{sample}$ of the ADCs should be set to 20Hz. Consequently, the corner frequency $f_c$ of the low pass filters in the input channels should be set equal to the sample rate. However, as there is no perfect low pass filter in practice, commonly a sample rate of

$$ f_{sample} \approx 2.2f_{Nyquist}$$

is used to compensate for the non-perfect damping of the low pass filter; in this case resulting in a sample rate $f_{sample}$ and a corner frequency $f_c$ of 22 Hz.

TODO:

  • write script for computing R and C from standard series resistors and capacitors
  • measure damping and phase shift "on-board"

In [ ]: