CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Varying Battery Loads

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
stinky



Joined: 05 Mar 2012
Posts: 99
Location: Central Illinois

View user's profile Send private message

Varying Battery Loads
PostPosted: Wed Oct 29, 2014 9:49 am     Reply with quote

    16LF1829
    V4.141
    2 Primary Lithium 123 Cells in Series
    Load draws anywhere from 50mA - 2.5A
    9 different load levels
    PIC VDD @ 3.3V

I'm measuring battery voltage as a varied duty cycle is changing the load on the batteries. Simple resistive divider. Where things are getting "hairy" is that as the load changes from heavy to low, the batteries "relax" and tend to float higher. I feel as if I have begun running in circles as I log duty levels and set trip points at different voltages. The basic framework for how I'm acquiring the data is in the code below. I'm looking for thoughts on best ways to handle the multiple different loads. My goal is to watch the voltage level and begin to reduce the maximum load supplied to extend "runtime" of the batteries. The challenge has been that it takes a varying amount of time for the batteries to "relax" to a higher voltage as the load changes. I'm not sure how best to handle this large set of variables as load levels affect timings. All insight is appreciated.

Code:
/*PCM Compiler  Version 4.141*/
#include "16LF1829.h"
#device adc = 10
#define OSCILLATOR 16000000
#use delay (internal = OSCILLATOR)
#fuses INTRC_IO, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD
#fuses NODEBUG, NOPROTECT, NOCLKOUT, NOIESO, NOFCMEN, NOWRT, STVREN               
#use FAST_IO(ALL)
#use RS232(baud = 9600, XMIT = PIN_A0, RCV = PIN_A1, ERRORS)

#define VBAT_ANALOG            5 //C1
#define FOSC_DIV_BY_4          OSCILLATOR / 4
#define TIMER_PRESCALER                    16
#define TIMER_ROLLOVER_VALUE              255
#define REAL_TIME_FREQUENCY    ((FOSC_DIV_BY_4 / TIMER_PRESCALER) / TIMER_ROLLOVER_VALUE)
#define MILLISECONDS(value)    ((value * REAL_TIME_FREQUENCY) / 1000)
/*
 Nom 6 VDC     1.18k
     ----------^^^^^----------> VBAT_ANALOG
 ____|____            |
    ___               >
 _________            > 390R
    ___               >
     |                |         
     |_______________GND
*/
unsigned int16 analog_count = 0;
unsigned int16 load_count = 0;

void initialize(void) {
  output_a(0b00010001);
  output_b(0b01110000);
  output_c(0b00010000);
  port_a_pullups(0b00101010);
  port_b_pullups(0b00000000);
  port_c_pullups(0b00000100);
  set_tris_a(0b00101010);
  set_tris_b(0b00000000);
  set_tris_c(0b00000111);

  setup_adc(ADC_CLOCK_DIV_32);
  setup_adc_ports(sAN5 | VSS_VDD);
  set_adc_channel(VBAT_ANALOG);

  set_pwm2_duty(1020);
  setup_timer_2(T2_DIV_BY_16, 255, 1);
  setup_ccp2(CCP_PWM | CCP_TIMER4);
  setup_timer_4(T4_DIV_BY_1, 255, 1);
}

unsigned int16 average_voltage(void) {
  static unsigned int8 i = 0;
  static unsigned int16 sum = 0;
  unsigned int16 temp = 0;

  /*Measurements at approx 30 milliseconds.*/
  if((i < 16) && (analog_count > MILLISECONDS(30))) {
    /*Reads taken near the beginning of PWM Period*/
    if(get_timer4() < 10) {
      analog_count = 0;
      sum += read_adc();
      i++;
    }
  }
  /*Average 16 reads and return value*/
  else if(i == 16) {
    temp = sum >> 4;
    i = 0;
    sum = 0;
  }
 
  /*Always returns 0 until 16 reads
  are complete and averaged.*/
  return temp;
}

void time_base(void) {
  /*Polls Timer 2 IF bit.  If Set,
  timer has rolled over.  Clear and
  increment variable timers.*/
  if(interrupt_active(INT_TIMER2)) {
    clear_interrupt(INT_TIMER2);
    analog_count += 1;
    load_count += 1;
  }
}

short int vary_load(void) {
  static short int flag = 1;
  unsigned int16 temp;
  /*Approximately 5 seconds and
  duty cycle is updated to simulate
  changing load on batteries.*/
  if(load_count > MILLISECONDS(5000)) {
    load_count = 0;
    if(flag) {
      flag = FALSE;
      temp = 512;
    }
    else {
      flag = TRUE;
      temp = 1020;
    }
    set_pwm2_duty(temp);
  }
  return flag;
}

void console(void) {
  char str[8];
  unsigned int16 temp;
  /*Display the adc value of battery
  and tell me whether or not this
  is functioning under HI / LO load*/
  if(temp = average_voltage()) {
    if(vary_load())
      strcpy(str, "HI");
    else
      strcpy(str, "LO");
    printf("battery adc value == %Lu, battery load == %s\r\n", temp, str);
  }
}

void main(void) {
  initialize();
  while(TRUE) {
    time_base();
    vary_load();
    console();
  }
}
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Oct 29, 2014 10:42 am     Reply with quote

Battery monitoring has moved away from voltage measurement to charge measurement: so called "coulomb counting". For the most part this is because of exactly the sort of issues you are having: modern batteries don't have the sort of voltage response that older types do. Many rechargables, for example, have a very flat voltage characteristic for the vast majority of their useful life, the voltage only dropping at very low charge levels.

The basic idea is that, knowing the batteries capacity, you measure current (not voltage) and integrate over time to determine charge state. There are ICs that do all that for you, and there's common bus types and protocols, such as PMbus, a variant of I2C. These ICs are a far better bet than any pure voltage measuring approach. They are at their best when working with rechargables, when they track the battery's state and are used as part of the charge control loop and for tracking battery health, but they can be pretty useful with the newer chemistry primary batteries too.
SuperDave



Joined: 22 May 2008
Posts: 63
Location: Madison, TN

View user's profile Send private message Visit poster's website

PostPosted: Wed Oct 29, 2014 10:53 am     Reply with quote

I'm not sure how you "reduce the maximum load supplied " but I can offer some other thoughts.

The data sheet on the DL123, available here
http://ww2.duracell.com/en-US/Global-Technical-Content-Library/Product-Data-Sheets.jspx?icn=Prim/PrimNav/Product-Data-Sheets&cc=Primary
shows a max life of about one hour at a constant drain of 1 Amp. Thus, 2.5 Amps is way above any spec the manufacture expects. Even their pulsed response of 3 secs on, 7 secs off is only 1.2 Amps. The battery voltage will be much more stable if run within its design parameters, or you have another set or two in parallel. As designed you're losing over six tenths of a volt inside the battery at 2.5 Amps. (1.2 Volts with two in series!)

Not sure why you're dividing the voltage by 4 (instead of 2) and losing a bit of resolution though that's not a big problem. Even more confused why you seem to be summing a lot of values. For a voltage that's drifting slowly (i.e. modestly stable), one reading should have plenty of both precision and accuracy.

On the firmware side I'd be more inclined to have a timer interrupt set a flag and have main() execute a routine (and reset the flag) when the flag is detected rather than poll an interrupt register. Coding it using interrupts as they were intended is more efficient, easier to understand and thus easier to maintain. Setting a flag, and JUST setting a flag, keeps the interrupt short so that it doesn't interfere with other processes. That's probably not important in the code you supplied but could become important when you add the rest of the firmware.
VernonAMiller



Joined: 11 Sep 2014
Posts: 25
Location: Contoocook, NH

View user's profile Send private message

PostPosted: Wed Oct 29, 2014 11:29 am     Reply with quote

I agree with RF_Developer about the battery monitoring chip. That's the way to go. All of the projects I've worked on for the past 15 years or so have had a battery-backed cache of some sort, and we have been using one or another of the single-chip battery management solutions with great success.

Honestly, though we have never had trouble with the battery management chip, we have had lots of trouble with I2C (many of the chips are I2C based), even with knowledgeable designers. Which is why I'm not really a huge fan of I2C. If you use one of these chips, please make sure you design the I2C connection correctly (proper termination and filtering) and test it thoroughly in noisy environments and under margins (heat, cold, over- and under-voltage).

VAM
stinky



Joined: 05 Mar 2012
Posts: 99
Location: Central Illinois

View user's profile Send private message

PostPosted: Wed Oct 29, 2014 12:50 pm     Reply with quote

    RF_Developer:

Quote:
...at their best when working with rechargables, when they track the battery's state and are used as part of the charge control loop and for tracking battery health, but they can be pretty useful with the newer chemistry primary batteries too.


I'm always impressed by the observations made here. Thank you. You've sold me, dedicated hardware is the correct tool. I've skimmed a few datasheets and it seems that most are being marketed as part of a charge controller for secondary cells. I'm currently interested in Primary cells, so I'm not going to measure the rate of charge. Which makes me wonder, how can I detect a "fresh" set of batteries since I don't get to watch some charging routine occur that can count coulombs in?
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Oct 29, 2014 1:45 pm     Reply with quote

Something else to consider - as batteries discharge, the internal resistance tends to go up. This often results in a high impedance path through the battery even if significant charge is left in them (remember the old 9v transistor radios?). Putting a decent size cap across the battery can help keep the impedance down which really shows up where the average current is low, but spikes are needed (like the 9v transistor radios - if you put a 220ufd cap across the battery, you could often double the life of the battery).

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
VernonAMiller



Joined: 11 Sep 2014
Posts: 25
Location: Contoocook, NH

View user's profile Send private message

PostPosted: Wed Oct 29, 2014 1:52 pm     Reply with quote

You are right that most solutions center on rechargeable cells. However, I know that Maxim and TI both make solutions for alkaline cells as well.

Check this link at Maxim:
http://datasheets.maximintegrated.com/en/ds/MAX6775-MAX6781.pdf

Or these at TI:
http://www.ti.com/lit/ds/symlink/tps80010.pdf
http://www.ti.com/lit/ds/symlink/bq2052.pdf

The Maxim parts and the second TI part are more for monitoring; the first TI part includes built-in boost and buck converters as well as a load generator for testing the battery voltage under a known load.

I'm sure there are more.

VAM
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

TI bq2052 Gas Gauge
PostPosted: Thu Oct 30, 2014 5:48 am     Reply with quote

About two years ago I bought the TI bq2052 development kit direct from TI and the software came on 3" floppies. I emailed them and asked if I could download the software and they replied that the bq2052 was obsolete and no longer supported, even though the development kit was still being promoted on their web site. I emailed back and asked if there was any replacement part for lithium primary cells and never got a reply.

I have grown to really loathe TI.
_________________
The search for better is endless. Instead simply find very good and get the job done.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Oct 30, 2014 6:18 am     Reply with quote

yet another thing to consider...

You're using two batteries in series so you should monitor BOTH batteries.
It is possible that one might be 'funny' and not properly charge or deliver current as it should.
Quite a problem with Ni-Cd packs...one cell goes bad and the 'pack' is tossed when only that cell should be replaced.

Also...

consider just testing under a 'full load' condition. If it passes then it should be OK for lower current demands. I did that with our remote energy control system backup supplies as it sure simplified the testing and code.

And...

if you're in doubt about battery capacity, simply use bigger batteries! They won't cost much more, aren't that much bigger, gives a more reliable system. Maybe toss on a 'supercap' (high Farad value), especially if the system needs a lot of current for a short duration.

hth
Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group