Jump to content
43oh

Problem using Arduino code in Energia


Recommended Posts

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:
Link to post
Share on other sites
  • Replies 51
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

What about my my code? It just works I don't think you really need the sampling intervals to be spot on accuracy that you need a timer. If you really want it to be better just do   // Very simple

Yes and remove all the timer stuff from setup So something like this   // Very simple Arduino Lithium-ion battery capacity tester // from electronicsblog.net   #define LED 13 #define resistor 6.9

Your code is ATmega specific (you're directly addressing the timer peripheral of the Arduino), and hence cannot be run at the MSP430/launchpad. You could translate this code to work for the Launchpad.

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.

Link to post
Share on other sites

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 
Link to post
Share on other sites

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).

Link to post
Share on other sites

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 
Link to post
Share on other sites

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)

Link to post
Share on other sites

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;
};

Link to post
Share on other sites

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.

Link to post
Share on other sites

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 
Link to post
Share on other sites

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.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...