Here are the additional modifications:
Additional modification to the PCB |
For a 2A current, the ADC should see around 2A * 0.01R * (100+1)/1 = 2.02V. For the native 10-bit ADC, I should get about 3mA resolution. I am extending the ADC resolution using oversampling.
The Opamp has a negative DC offset (Vos), so it cannot read low currents. The part also have a somewhat high temperature coefficient as it drifts. There are at least 2 different pin outs for opamp that I am aware of. The TLV2461 from TI matches this part.
.
opamp pin out |
It is not the first choice I would have picked because of its negative Vos (offset voltage) around ground. This negative Vos if not corrected can drown out low current measurements. The Vos has a curious shape of 3 distinct sections. This is typical of rail to rail input opamps as it actually have both ground rail and supply rail input section for the full supply range. Each of these front ends have their dominating Vos in its operating regions. Around mid rail is where they sort of cancel out each other.
Vos vs input common voltage |
Temperature coefficient: 2uV/C |
I have added a 2M2 resistor to add a DC offset. This offset get multiplied by the gain of the amplifier (101X). Now the output is around 63mV with 0mA load. This DC will be taken care of by the calibration.
New: I had a lot of issues with the current measurements jumps all over the place. I trace it down to poor grounding in the layout. They use a thin trace to connect the ground. This same thin track is shared by the LDO which supplies the microcontroller. The voltage drop on the trace changes as the LED segments are lit and this gets amplified by the current sense amplifier. There is also a tiny bit of DC offset between the opamp ground and the microcontroller which introduce about 2-3 LSB of offset. I added a couple of 24AWG wires (shown in purple) and they help to reduce the amount of jitters in the raw measurement. I also have a sliding window averaging as a low pass filter to stabilize the readings.
Replaced USB cable, improved grounding and SWIM for debugging |
I have replaced the flimsy USB cable with 2 twisted pairs from Ethernet patch cable in sleeving. The wires are 24AWG which can carry up to 3.5A safely. Unfortunately these cable weren't meant for soldering, so there are some solderability issues. I had to use some heat shrink tubing to cover the easily melted insulation. I drilled a bigger hole in the plastic molding from the original cable.
From https://www.powerstream.com/Wire_Size.htm |
SWIM connector for debugger |
For calibration, I modify the display routine to show the raw ADC value which I then input the data into a spreadsheet for linear regression.
Regression analysis of raw ADC values vs input voltage |
Note: The website no longer exists. Use this High Precision Decimal to Fraction online calculator
After the preliminary calibration, the measurements are within +/- 1 digits of my multimeter. I probably need to redo this as I have improved the grounding and that shifted the offset slightly.
The mod seems to be able to see current down to 1mA. I ran into a bit of non-linearity issues as the current gets higher due to heating effects on the traces and sampling resistor.
As larger range is used for the analysis, the higher currents affects the otherwise linear data at the lower ranges. Using the 0 - 0.604A coefficients, I get +/-1 mA for 0-500mA, but the values gets to +/-2 above that.
One way to avoid this is to use piece-wise fit as it'll allow much closer fit to a subset. As shown below, the residual is within +/- 1 for 0.653A - 1.065A.
The higher current ranges has a reduced display resolution of 10mA, so I could get by with extrapolation from the 1A curve.
The specs after calibration:
While there are no free I/O pins, the column drivers (CC2..CC6) could be re-purposed for reading push buttons. They are programmed as open drain output.
Inside the TIM2_Update_IRQ( ), the 5 inactive column drivers can be reprogrammed into the "Input pull-up" configuration using the CNF1 and CNF0 registers. Push buttons in series with a 4K7 series resistor can be used to pull these I/O to '0'. The resistors limits the current to minimize display artifacts.
Alternate display format can be used for additional data e.g. min, max voltage/current, power measurement.
The hardware UART pins are used for ADC and cannot be shared. One of the segments (e.g. Decimal Point) into a 3V UART transmit pin. The timer compare functions could be used for more precise timing needed for bit-banging.
I have decided to make a small adapter PCB for the microcontroller.
It probably going to take 3 weeks. Available from https://oshpark.com/shared_projects/nWySOWYk
Link: Part 1, part 3
Project file: https://github.com/FPGA-Computer/USB-Voltage-Current-Meter
The option bytes are default (0x00)
After the preliminary calibration, the measurements are within +/- 1 digits of my multimeter. I probably need to redo this as I have improved the grounding and that shifted the offset slightly.
Multimeter in voltage mode |
Multimeter in current mode |
As larger range is used for the analysis, the higher currents affects the otherwise linear data at the lower ranges. Using the 0 - 0.604A coefficients, I get +/-1 mA for 0-500mA, but the values gets to +/-2 above that.
Residual plots of different current ranges |
The higher current ranges has a reduced display resolution of 10mA, so I could get by with extrapolation from the 1A curve.
The specs after calibration:
- Below 3.20V, "LO" (Low) is displayed. Above 10.19V, "OV" (Over Voltage) is displayed
- 3.20V - 9.99V : +/- 0.01V.
- Current display: 0-999mA +/- 1mA with zero suppression. 1.00 - 2.00A +/- 10mA.
While there are no free I/O pins, the column drivers (CC2..CC6) could be re-purposed for reading push buttons. They are programmed as open drain output.
Inside the TIM2_Update_IRQ( ), the 5 inactive column drivers can be reprogrammed into the "Input pull-up" configuration using the CNF1 and CNF0 registers. Push buttons in series with a 4K7 series resistor can be used to pull these I/O to '0'. The resistors limits the current to minimize display artifacts.
Alternate display format can be used for additional data e.g. min, max voltage/current, power measurement.
The hardware UART pins are used for ADC and cannot be shared. One of the segments (e.g. Decimal Point) into a 3V UART transmit pin. The timer compare functions could be used for more precise timing needed for bit-banging.
I have decided to make a small adapter PCB for the microcontroller.
It probably going to take 3 weeks. Available from https://oshpark.com/shared_projects/nWySOWYk
Link: Part 1, part 3
Project file: https://github.com/FPGA-Computer/USB-Voltage-Current-Meter
The option bytes are default (0x00)
Option byte setting |