Have you even wondered why your tablet or phone charges faster with one cable and slower with another?
I did, and questions like this keep me awake at night. So, I designed a USB Cable Tester using an Android UNO board.
This device measures the charge efficiency of a micro-USB cable by passing 0.5A through the cable and measuring voltage at various points.
To calculate the efficiency, we assume that the input current ITEST is identical to the output current that flows through the 10 ohm load resistor. I.e. the internal resistance of the cable is negligible.
The efficiency is the ratio of input and output power, which simplifies down to the ratio of input and output voltage.
In order to get the most accurate result possible, this circuit measures both +ve and -ve sides of both Vout and Vin; and measurement points are taken as close as possible to the usb connectors.
The connections to the Arduino analog pins A0 - A3 are shown in the circuit diagram below. Vcc is wired to 5V.
And here's the Arduino code. Initially I found the value on the display 'flickered' as the Arduino was updating the display hundreds of times a second. In this version of the code I have implemented oversampling in an attempt to provide a more 'stable' display of the efficiency value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include <LiquidCrystal.h> #include <stdlib.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); float total = 0; char buff [6] = " " ; const int numReadings = 10; float readings[numReadings]; //array to calculate average and improve stability of display int readIndex = 0; void setup() { // put your setup code here, to run once: analogReference(DEFAULT); //0 - 5V // set up the LCD's number of columns and rows: lcd.begin(16, 2); lcd.print( "USB Cable Tester" ); // initialize all the readings to 0: for ( int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; } } void loop() { lcd.setCursor(0,1); total = total - readings[readIndex]; readings[readIndex] = readAndCalcEfficiency(); //efficiency of 0.1% or less must be no cable connected bool noCable = readings[readIndex] < 0.1; total = total + readings[readIndex]; readIndex++; if (readIndex >= numReadings) { readIndex = 0; } if (noCable) { lcd.print( " -- No cable --" ); } else { dtostrf(calcAvg(readings) * 100,2,0,buff); lcd.print( "Eff.: " ); lcd.print(buff); lcd.print( "% " ); } } float calcAvg( float readings[]){ //filter out the 'co cable' readings from the average calculation int numValidReadings=0; for ( int thisReading = 0; thisReading < numReadings; thisReading++) { if (readings[thisReading] >=0.1) numValidReadings++; } float avg = total / numValidReadings; return avg; } float readAndCalcEfficiency() { //delay of 10ms between reads from different analog pins improves accuracy int val0 = analogRead(0); delay(10); int val1 = analogRead(1); delay(10); int val2 = analogRead(2); delay(10); int val3 = analogRead(3); delay(10); float eff = ( float )(val0-val1)/(val2-val3); return eff; } |
And finally, here's some pictures of the device in use.
A good cable (the best on I could find lying around) measured an efficiency of a little over 98%:
And here's an el-cheapo cable that measured a loss of nearly 10% You know you wan't get optimal charge time with this one:
If you build this yourself please post a comment and let me know how it turned out.
No comments:
Post a Comment