BDCoDE 0 Posted March 27, 2013 Author Share Posted March 27, 2013 Your code is working well so far. The only thing I edited was resistance , from 6.9 to 13 Here is the output example:Voltage= 1.42V Current= 0.11A Capacity= 0.01Ah Discharging time= 430.00s Voltage= 1.35V Current= 0.10A Capacity= 0.01Ah Discharging time= 431.00s Voltage= 1.42V Current= 0.11A Capacity= 0.01Ah Discharging time= 432.00s Voltage= 1.37V Current= 0.11A Capacity= 0.01Ah Discharging time= 433.00s Voltage= 1.43V Current= 0.11A Capacity= 0.01Ah Discharging time= 434.00s Voltage= 1.37V Current= 0.11A Capacity= 0.01Ah Discharging time= 435.00s Voltage= 1.41V Current= 0.11A Capacity= 0.01Ah Discharging time= 436.00s Voltage= 1.37V Current= 0.11A Capacity= 0.01Ah Discharging time= 437.00s Voltage= 1.42V Current= 0.11A Capacity= 0.01Ah Discharging time= 438.00s Voltage= 1.35V Current= 0.10A Capacity= 0.01Ah Discharging time= 439.00s Voltage= 1.59V Current= 0.12A Capacity= 0.01Ah Discharging time= 440.00s Voltage= 1.42V Current= 0.11A Capacity= 0.01Ah Discharging time= 441.00s Voltage= 1.36V Current= 0.10A Capacity= 0.01Ah Discharging time= 442.00s Voltage= 1.45V Current= 0.11A Capacity= 0.01Ah Discharging time= 443.00s Voltage= 1.36V Current= 0.10A Capacity= 0.01Ah Discharging time= 444.00s Voltage= 1.45V Current= 0.11A Capacity= 0.01Ah Discharging time= 445.00s Voltage= 1.39V Current= 0.11A Capacity= 0.01Ah Discharging time= 446.00s Voltage= 1.76V Current= 0.14A Capacity= 0.01Ah Discharging time= 447.00s Voltage= 1.44V Current= 0.11A Capacity= 0.01Ah Discharging time= 448.00s Voltage= 1.41V Current= 0.11A Capacity= 0.01Ah Discharging time= 449.00s Voltage= 1.33V Current= 0.10A Capacity= 0.01Ah Discharging time= 450.00s I can smell the resistors burning . I think it's strange that Voltage is so unstable. but we will see what will happen the next hour. P.S The real voltage is 3.7 Li-ion battery :grin: Quote Link to post Share on other sites
semicolo 39 Posted March 27, 2013 Share Posted March 27, 2013 Probably noise, the recommended way to get a sample is to put the cpu in sleep mode and wake up by the conversion interrupt, I don't know if energia is doing that. Also the noise can come from the supply. Did you add a voltage divider for the battery voltage? A fully charged battery is around 4.2V this could damage the MCU. BDCoDE 1 Quote Link to post Share on other sites
BDCoDE 0 Posted March 27, 2013 Author Share Posted March 27, 2013 No voltage divider, here is the actual schematic. Besides, I was getting 1.4V when I was using "voltage=value/1024*3.7;" , instead of "voltage=value/1024*5.0" as in your example. Now with "voltage=value/1024*5.0" I get constant 5.00V and 0.38A, but I'm not sure if it's correct. P.S Here is the new output. I used "voltage=value/1024*5.0" Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3220.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3221.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3222.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3223.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3224.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3225.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3226.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3227.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3228.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3229.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3230.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3231.00s Voltage= 5.00V Current= 0.38A Capacity= 0.34Ah Discharging time= 3232.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3233.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3234.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3235.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3236.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3237.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3238.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3239.00s Voltage= 5.00V Current= 0.38A Capacity= 0.35Ah Discharging time= 3240.00s Quote Link to post Share on other sites
BDCoDE 0 Posted March 27, 2013 Author Share Posted March 27, 2013 How do you think this voltage divider will work? Quote Link to post Share on other sites
semicolo 39 Posted March 27, 2013 Share Posted March 27, 2013 You're lucky you didn't kill the MCU, I'd use resistors with higher values to keep the current below 1mA, for example 1K and 3.3K (with 4.7K voltage is still a bit high to my taste) Then the formula should be voltage=value/1023*3.3 (3.3V because the voltage reference is VCC). Quote Link to post Share on other sites
BDCoDE 0 Posted March 27, 2013 Author Share Posted March 27, 2013 Thanks for advice, I will try it tomorrow. The test is finished. Here is the last lines of output file. As you can see the voltage is about 3.5V at the lowest, I don't know why but the voltage was constant 5.00V til 16653.00s :!!!: The test showed that battery is 1.87Ah. I think it's true, because the battery sticker says it's 2000mAh, but it's produced in China :grin:. Will run some more tests tomorrow, with voltage divider ;-) Voltage= 3.60V Current= 0.28A Capacity= 1.87Ah Discharging time= 17590.00s Voltage= 3.59V Current= 0.28A Capacity= 1.87Ah Discharging time= 17591.00s Voltage= 3.58V Current= 0.28A Capacity= 1.87Ah Discharging time= 17592.00s Voltage= 3.57V Current= 0.27A Capacity= 1.87Ah Discharging time= 17593.00s Voltage= 3.56V Current= 0.27A Capacity= 1.87Ah Discharging time= 17594.00s Voltage= 3.56V Current= 0.27A Capacity= 1.87Ah Discharging time= 17595.00s Voltage= 3.54V Current= 0.27A Capacity= 1.87Ah Discharging time= 17596.00s Voltage= 3.54V Current= 0.27A Capacity= 1.87Ah Discharging time= 17597.00s Voltage= 3.54V Current= 0.27A Capacity= 1.87Ah Discharging time= 17598.00s Voltage= 3.52V Current= 0.27A Capacity= 1.87Ah Discharging time= 17599.00s Voltage= 3.51V Current= 0.27A Capacity= 1.87Ah Discharging time= 17600.00s Voltage= 0.00V Current= 0.00A Capacity= 1.87Ah Discharging time= 17601.00s Voltage= 0.00V Current= 0.00A Capacity= 1.87Ah Discharging time= 17602.00s Voltage= 0.00V Current= 0.00A Capacity= 1.87Ah Discharging time= 17603.00s Quote Link to post Share on other sites
semicolo 39 Posted March 28, 2013 Share Posted March 28, 2013 it reads 5V because you didn't use a voltage divider, it means until the voltage dropped below 3.3V the conversion returned 1023 and since you used voltage=value/1024*5, it showed 5 Quote Link to post Share on other sites
semicolo 39 Posted March 28, 2013 Share Posted March 28, 2013 Just did some research, you could use the internal voltage reference for a a better accuracy analogReference(INTERNAL2V5) and use 1K/1K for the voltage reference. voltage would be voltage=value/1023*5 You need *5 because the reference is 2.5V but you're using a 1/2 voltage divider (by the way I forgot to take the voltage into account on the post above) energia 1 Quote Link to post Share on other sites
BDCoDE 0 Posted March 28, 2013 Author Share Posted March 28, 2013 Like this? The schematic with voltage divider will then look like this. Are everything ??????? correctly now? // Very simple Arduino Lithium-ion battery capacity tester // from electronicsblog.net #define LED GREEN_LED #define resistor 13 float capacity=0, value,voltage,current, time=0; void measure (void) { analogReference(INTERNAL2V5); delay(1) value= analogRead(A5); voltage=value/1023*5; current = voltage/resistor; capacity=capacity+current/3600; time++; Serial.print("Voltage= "); Serial.print(voltage); Serial.print("V Current= "); Serial.print(current); Serial.print("A Capacity= "); Serial.print(capacity); Serial.print("Ah "); Serial.print("Discharging time= "); Serial.print(time); Serial.print("s "); Serial.print("\n"); } boolean x=false; unsigned long ms; void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); ms = millis()+1000; }; void loop () { digitalWrite(LED, x); x=!x; measure(); while (millis() < ms); ms=millis()+1000; }; Quote Link to post Share on other sites
roadrunner84 466 Posted March 28, 2013 Share Posted March 28, 2013 R3 should be twice the value of R2. The input voltage of the MSP430's ADC is usually 2.5V. So when you have a voltage of 3.7V max the divider (say 1k over 2k) would be 3.7V * 2k/(2k+1k) = 2.47V, which is just in the max of the ADC's range. Quote Link to post Share on other sites
BDCoDE 0 Posted March 28, 2013 Author Share Posted March 28, 2013 The output of fully charged Li-ion battery can be up to 4.1/ 4.2 V. Therefor if I use 1k as R2 and 1.5k as R3 I'll get 4.15V * 1.5k /( 1.5k+1k) = 2.49V Almost the same as yours. R3 should be twice the value of R2. Can't get the voltage to fit under 2.5V using this rule. Quote Link to post Share on other sites
semicolo 39 Posted March 28, 2013 Share Posted March 28, 2013 You'll have to correct your voltage to be: voltage = value/1023*2.5*2.5/1.5; The maximum you can measure is 4.17V. Quote Link to post Share on other sites
BDCoDE 0 Posted March 29, 2013 Author Share Posted March 29, 2013 I run the test again with new code and got 1.55Ah. Here is the new output. Voltage= 0.00V Current= 0.00A Capacity= 0.00Ah Discharging time= 1.00s // battery isn't connected yet Voltage= 0.00V Current= 0.00A Capacity= 0.00Ah Discharging time= 2.00s // battery isn't connected yet Voltage= 3.60V Current= 0.28A Capacity= 0.00Ah Discharging time= 3.00s Voltage= 3.64V Current= 0.28A Capacity= 0.00Ah Discharging time= 4.00s Voltage= 3.64V Current= 0.28A Capacity= 0.00Ah Discharging time= 5.00s ...................................................................... ...................................................................... ...................................................................... Voltage= 2.22V Current= 0.17A Capacity= 1.55Ah Discharging time= 21694.00s Voltage= 2.22V Current= 0.17A Capacity= 1.55Ah Discharging time= 21695.00s Voltage= 2.21V Current= 0.17A Capacity= 1.55Ah Discharging time= 21696.00s Voltage= 0.00V Current= 0.00A Capacity= 1.55Ah Discharging time= 21697.00s Voltage= 0.00V Current= 0.00A Capacity= 1.55Ah Discharging time= 21698.00s Quote Link to post Share on other sites
semicolo 39 Posted March 29, 2013 Share Posted March 29, 2013 If the measure is accurate, isn't 2.2V a bit low? You shouldn't go below 2.5V Quote Link to post Share on other sites
roadrunner84 466 Posted March 29, 2013 Share Posted March 29, 2013 You'll have to correct your voltage to be: voltage = value/1023*2.5*2.5/1.5; The maximum you can measure is 4.17V. Ow! This hurts! Value (0-1023) divided by 1023 will be 0 unless value is 1023. At least, that's the case for integers! And in a microcontroller you don't want to use floating point! So, I feel obligated to describe how this is done without making a monster of your code. We have a value that is in the range 0 to 1023 which actually maps onto a voltage of 4.16V I stated we don't want to use floating point, so 4.16V is actually 4167mV or 417cV (centivolts) Would we divide 4166.6 over 1023 the value would be about 4.073. In an integer multiplication this would become 4. The error this generates is noticably large, since 1023 * 4 = 4092 or 4.092V If you can settle for a displayed value of 4.09V for an actual voltage of 4.17V then you're done: just multiply by 4 to get the value in millivolts. If you want higher accuracy, seek for the larges multiplier within the 0 to 2^16-1 (65535) range. So, we already determined that the multiplier value is close to 4.073. Let's divide 65536/1024 by that value to see how many times we can fit that in. (65536/1024)/4.073... is about 15.7. Too bad it fits just under 16 times, since we don't have a hardware accelerated divider we settle for 8 (highest power of 2 that fits under 15.7). So, we have a value of (4166.6/1023)*8, which turns out to be about 32.55. Too bad this is close to 32.5. But just for the example we'll continue. A value of 1023 would be 4.16V, so we'll multiply the value 1023 by the rounded value of 32.55, which is 33. The result is 33759. This result is now divided by 8 (23) (since that is the multiple of the constant we just used). 33759/8=4219.875. which rounds down to 4.21V. So an actual voltage of 4.16V is displayed as 4.09V for the formula voltage = value * 4; with an error of 0,06V 4.21V for the formula voltage = (value * 33u) >> 3; with an error of 0.043V Both are about the same. But what I wanted to explain is, using this little bit of math results in way smaller and way faster code, at the expense of a mere 67 millivolts worst case. Let me add a third calculation. In the second example I showed that the multiplicand is close to 32.5. This means that multiplying it by 2 would get it close to 65.0. This is good, because a smaller discarded fraction results in a more accurate result. The expense here will be that we cannot use 16-bit (native) integer resolution anymore. We could actually expand the resolution to the full 32 bits now, but that's for example 4. We repeat the calculation of dividing (2something/1024)/4.073... but with something being 17 intead of 16. The result is (217/1024)/4.073... which is about 31.4. This again is just under 32, so we'll go for 16 now (highest power of 2 under 31.4). Again we calculate (4166.6/1023)*16, which now turns out to be about 65.1678. This is quite good, since this value is close to 65. A value of 1023 would be 4.16V, so we'll multiply the value 1023 by 65. The result is 66,495. Notice this value is larger than a native integer can contain on the MSP430; the code will be a little less efficient. This result is now divided by 16 (24) (since that is the multiple of the constant we just used). 66,495/16=4155.9375. which rounds down to 4.15V. Wow, that's close to 4.16V! Now, for a last example, since we crossed the 16 bit boundary, let's do this again for the highest value within the 32 bit realm. Again we calculate (2something/1024)/4.073..., but now for something we use 32. The result is (232/1024)/4.073... which is about 1,029,785.5, this is just under 1,048,576 (220), so we'll settle for 524,288 (219). These numbers are larger, but the calculations are identical to the previous examples. Now we calculate again (4166.6/1023)*524,288, which is about 2,135,418.7. The fracion is not close to a whole number, but it gets divided away so heavily that we won't notice it later on. A value of 1023 would be 4.16V, so we'll multiply the value 1023 by 2,135,418. The result is 2,184,532,614. Now the result is divided by 524,288 (219): 2,184,532,614/524,288=4166.66529... which rounds down to 4.166665V which is even closer to 4.16V For a last summary: 4.09V for the formula voltage = value * 4; with an error of 0,06V (about 67mV) 4.21V for the formula voltage = (value * 33u) >> 3; with an error of 0.043V (about 43mV) 4.15V for the formula voltage = (value * 65L) >> 4; with an error of 0.01072916V (about 11mV) 4.16V for the formula voltage = (value * 524288uL) >> 19; with an error of 0.0000013720194498697916V (about 1.4uV) And a plot twist: An accuracy of about 1.4 microvolt seems awesome, but remember that you're using a 10-bit ADC, so you can be off by 4.16/1024 is about 0.004V or 4mV by the quantisation noise introduced by your ADC! Then we assume the resistors are perfect and the ADC is perfectly callibrated and perfectly linear. Neither of these things is the case. So maybe just saying that the voltage in millivolts is equal to the value multiplied by 4 is just accurate enough. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.