Author Topic: Sensing in Attiny85 driven buck converter?  (Read 10037 times)

0 Members and 1 Guest are viewing this topic.

Offline ArtlavTopic starter

  • Frequent Contributor
  • **
  • Posts: 750
  • Country: mon
    • Orbital Designs
Sensing in Attiny85 driven buck converter?
« on: September 03, 2014, 11:07:15 pm »
I'm trying to make a battery charger buck converter, driven by attiny85.
Based on the AVR458 reference design by Atmel.

However, i can't quite get it to work.
The problem is in current sensing, and to some degree, voltage too.

Schematic:

Layout:


I'm using 1.1V reference voltage instead of 2.5V, everything else is about the same as in AVR458.

The voltage sensing is running read_volt_amp in a loop.
It senses the voltage directly, and current differentially with x20 gain.
Code: [Select]
void read_volt_amp(void)
{
 volatile uint32_t res;

 if(half==0){
  ADCSRA|=(1<<ADIF);
  ADCSRA|=(1<<ADSC);
  while((ADCSRA&(1<<ADIF))==0){}
  ADCSRA|=(1<<ADIF);
 
  res=ADCW;
  //res=res*484UL;
  //res=res/100UL;
  //res=res*175UL;
  //res=res/100UL;
  cur_amp=(cur_amp+res)/2UL;

  half=1;
  ADMUX=(1<<REFS1)|(1<<MUX1)|(1<<MUX0);
 }else{
  ADCSRA|=(1<<ADIF);
  ADCSRA|=(1<<ADSC);
  while((ADCSRA&(1<<ADIF))==0){}
  ADCSRA|=(1<<ADIF);
 
  res=ADCW;
  res=res*115UL;
  res=res/10UL;
  cur_volt=(cur_volt+res)/2UL;

  half=0;
  ADMUX=(1<<REFS1)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0);
 }
}

void setup_adc(void)
{
 ADMUX=(1<<REFS1);
 ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
}

There is no control as of now, the PWM is fixed so there is a constant current (150mA) going through a test load, a 9V LED.

Problem is, the current read by the ADC can:
-A, vary within +-10
-B, is higher or lower than what is expected (consistent, but non-linear).
The higher the ADC prescaler, the weirder the current read-out is.
Without the half-half reading (that is, reading all in one go), the current reads 0, always.
If you remove voltage reading, it does read, but reads the same weird value.
If you read the current once, on a signal instead of a loop, then it gives the correct value.

Voltage reads correct all the time, with a bit of a noise on it (that fits the ripple actually seen).

I don't get it.
Is it some noise in the circuitry?
Is it software issue?

Being based on a reference design, i expected it to just work.

 

Offline georges80

  • Frequent Contributor
  • **
  • Posts: 916
  • Country: us
Re: Sensing in Attiny85 driven buck converter?
« Reply #1 on: September 04, 2014, 01:02:43 am »
You should set and wait on ADSC for the conversion.

      ADCSRA |= _BV(ADSC);      // start A/D conversion

      while (ADCSRA & _BV(ADSC))   // wait for A/D conversion to complete
         ;

Software control of a buck driver will never be as good as a dedicated switcher IC. I created a tiny based LED driver (software buck) many years ago - it worked ok if voltage was stable etc. Otherwise there was flicker. A software control loop has fixed PWM step sizes (8 bit PWM) and also takes time to respond to transients.

It's a neat project to play with, but I eventually moved to dedicated switcher IC's that were then controlled (current driver and/or PWM) by the tiny.

From experience working in semiconductor companies, NEVER assume that an application note is 'correct'... They are generally created by app engineers working for the marketing dept... Treat them more as 'conceptual designs' that you likely need to refine.

cheers,
george.
 

Offline hlokk

  • Contributor
  • Posts: 41
  • Country: au
Re: Sensing in Attiny85 driven buck converter?
« Reply #2 on: September 04, 2014, 02:21:56 am »
I haven't gone through the circuit in any detail, but if you're using a different reference voltage, its not quite clear where you've set that in your code. http://arduino.cc/en/Reference/AnalogReference

Also, as the arduino at least (and presuming the attiny), make sure your voltages are referenced to ground. If you're measuring across the LED and the series resistor is below that then measuring the LED or resistor may short the resistor out? (Cant remember which way it goes). It may be obvious from your circuit diagram and code that you have this sorted though (didn't get a chance to fully go over)
 

Offline ArtlavTopic starter

  • Frequent Contributor
  • **
  • Posts: 750
  • Country: mon
    • Orbital Designs
Re: Sensing in Attiny85 driven buck converter?
« Reply #3 on: September 04, 2014, 05:31:32 am »
You should set and wait on ADSC for the conversion.
Tried to wait for ADSC to go low - works the same as with waiting for ADIF to go high.

Software control of a buck driver will never be as good as a dedicated switcher IC. I created a tiny based LED driver (software buck) many years ago - it worked ok if voltage was stable etc. Otherwise there was flicker. A software control loop has fixed PWM step sizes (8 bit PWM) and also takes time to respond to transients.
Sure, but it's an interesting idea to explore.
And for loads that does not vary much, like a battery being charged, it might work just fine.

From experience working in semiconductor companies, NEVER assume that an application note is 'correct'... They are generally created by app engineers working for the marketing dept... Treat them more as 'conceptual designs' that you likely need to refine.
Well, it does not make it less strange that the ADC fails to work like that.

I haven't gone through the circuit in any detail, but if you're using a different reference voltage, its not quite clear where you've set that in your code.
Um, ADMUX=(1<<REFS1); ?
I'm not using Arduino libs or their derivatives, just attiny85.

 

Offline hlokk

  • Contributor
  • Posts: 41
  • Country: au
Re: Sensing in Attiny85 driven buck converter?
« Reply #4 on: September 04, 2014, 06:35:10 am »
Um, ADMUX=(1<<REFS1); ?
I'm not using Arduino libs or their derivatives, just attiny85.
The arduino was just a link to show how its done on the arduino only, but seems you've set the reference to the inbuilt one. AFAIK the inbuilt ref isn't super precise, so might make sense to use an external reference if you need a lot of accuracy (but otherwise it should work).


I followed the path of your sense resistor, and at 150mA it'll drop 15mA. For a 9v supply you then volt divide it by 100k/10k which gives you two voltages for 818.18mV (ADC2/PB4) high side and 816.82mV (ADC3/PB3) for the low side, then feed this into the MCU via a 4.7k resistor. Assuming a perfectly high impedance in the chip, you'll get those two values read by the Attiny85's ADC, which for 10 bit will give values of 762 and 760 so only 2 counts difference. Effectively you're taking a 15mV differential, then dividing that difference by around 10 meaning the ADC needs to differentiate between a mV or two to determine the current. 
The Voltage reading should be ok as its placed well in the ADC range (and ref'd to ground). If the Attiny85 doesn't have a perfectly high impedance (I'm guessing its on the order of 10-100M? then the 4.7k will act as a voltage divider, but you may not mind the accuracy/precision loss)

The reason for getting weird results when not sampling at the same time (half and half) as you say is that the current may be fluctuating a little (expected with a switchmode supply as there will always be output ripple, even if minor). So if the low side of the current resistor fluctuates a few mV then your current calculation readings will be garbage due to the precision of the ADC.

Seems like you'll need to use an amplifier or similar to get a different voltage for the current prior to feeding it into the ADC?


I tried following the code, but you haven't commented it at all ( :palm:). Its unclear what types "res", "cur_volt" and "cur_amp" are. Are these declared as unsigned longs as per the "UL"?
« Last Edit: September 04, 2014, 06:42:10 am by hlokk »
 

Offline ArtlavTopic starter

  • Frequent Contributor
  • **
  • Posts: 750
  • Country: mon
    • Orbital Designs
Re: Sensing in Attiny85 driven buck converter?
« Reply #5 on: September 04, 2014, 08:10:34 am »
which gives you two voltages for 818.18mV (ADC2/PB4) high side and 816.82mV (ADC3/PB3) for the low side, then feed this into the MCU via a 4.7k resistor. Assuming a perfectly high impedance in the chip, you'll get those two values read by the Attiny85's ADC, which for 10 bit will give values of 762 and 760 so only 2 counts difference. Effectively you're taking a 15mV differential, then dividing that difference by around 10 meaning the ADC needs to differentiate between a mV or two to determine the current. 
Attiny85 have a differential input mode with a gain of 20, which should produce a value of about 25.
In other words, about 6mA resolution.

But i'm getting 50 or 80, or 0, or garbage, depending on prescaler, whether voltage was read before, etc.

The reason for getting weird results when not sampling at the same time (half and half) as you say is that the current may be fluctuating a little (expected with a switchmode supply as there will always be output ripple, even if minor). So if the low side of the current resistor fluctuates a few mV then your current calculation readings will be garbage due to the precision of the ADC.
Voltage is read single-ended, relative to the ground.
The current is read differentially, between the two pins.
So timing or fluctuations shouldn't affect it.

If it was voltage reading sagging one end, then i should have seen an increase in current reading when it was read before the current, since voltage is read on the load side.
It would dip the lower half.
But i get 0 in that case.
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22356
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Sensing in Attiny85 driven buck converter?
« Reply #6 on: September 04, 2014, 08:26:27 am »
http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
Read page 168.  You've just measured the performance of the ADC.  Actually, you probably found better than typical, because they only guarantee +/-20 LSBs on that measurement, at a 5 times lower clock rate!

On the plus side, the x20 amplifier's bandwidth is so low that you're nearly guaranteed to have consistent samples.

On the minus side, according to the diagram, switching the mux will switch what the amplifier sees, so you need to wait until its output settles.

Did anyone ever mention before how awful ATmega series analog peripherals are?

Not that you can expect much from the circuit to begin with -- 30 LSBs (< 5 bits) isn't much of a signal for current when you're dealing with 10 bit acquisitions, let alone the seriously euphemistic expectations of 32 bit variables.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline hlokk

  • Contributor
  • Posts: 41
  • Country: au
Re: Sensing in Attiny85 driven buck converter?
« Reply #7 on: September 04, 2014, 08:29:37 am »
Voltage is read single-ended, relative to the ground.
The current is read differentially, between the two pins.
So timing or fluctuations shouldn't affect it.
If your voltage is fluctuation, you take a reading, then wait some amount of time, then take another reading then subtract one value from the other then you'll get readings all over the shop (unless the noise/ripple is much less than your resolution).

Perhaps its an issue with a register being overwritten, or a integer value creeping into a double calculation or vice versa (e.g. if you need floating point precision).

I think your best bet at troubleshooting is to disconnect the sense lines and put in a potentiometer rigged up to a low voltage supply and then adjust it to get say 1mV difference between the differential inputs on your Attiny85 and see if you get the same issues? If running all linear, stable parts confirmed with a multimeter and it works then you know the switching circuit is likely the problem not the MCU or your code.
 

Offline ArtlavTopic starter

  • Frequent Contributor
  • **
  • Posts: 750
  • Country: mon
    • Orbital Designs
Re: Sensing in Attiny85 driven buck converter?
« Reply #8 on: September 04, 2014, 08:59:07 am »
If your voltage is fluctuation, you take a reading, then wait some amount of time, then take another reading then subtract one value from the other then you'll get readings all over the shop (unless the noise/ripple is much less than your resolution).
Except that's not what i do.
Attiny85 have a hardware differential ADC input.
Sampling the difference, not two one after another.

You've just measured the performance of the ADC.  Actually, you probably found better than typical, because they only guarantee +/-20 LSBs on that measurement, at a 5 times lower clock rate!
So, basically the conclusion is that the AVR458 reference design is garbage, and i should put a proper current sense amplifier chip in there instead of trying to use attiny's ADC directly?

Did anyone ever mention before how awful ATmega series analog peripherals are?
I had suspicions like that. :)
But never actually had to take one to it's limits.
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22356
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Sensing in Attiny85 driven buck converter?
« Reply #9 on: September 04, 2014, 09:40:08 am »
So, basically the conclusion is that the AVR458 reference design is garbage, and i should put a proper current sense amplifier chip in there instead of trying to use attiny's ADC directly?

That would be one thing.  Another would be to get rid of it altogether. :)

Even if you get full dynamic range (zero to VCC = 0-1023 counts, and so on), you're still limited by the sample rate, which always requires that you need a massive inductor so that the analog bandwidth is slow enough not to run away between samples.  In other words, if the load suddenly goes open or shorted, for example, what's the soonest you can do anything about it?  In most practical cases, that's going to take maybe 3-6 samples worth of time, and no less than 2 (one for the sample, one for the PWM output to actually change).

The best possible case would be using it as a pulse width modulator and nothing else.  If you run SPI at full speed, you can get passable bandwidth from an external (8-12 bit) ADC.  Or you could use a different type of ADC, or external logic, to generate parallel data, and read that at high bandwidth through digital input ports (you'll need a few more pins, of course).  But by then, you might as well use a comparator to generate the PWM in a dumb manner, and now you don't have to worry about the outboard ADC, and boot time (10s of us to 10s of ms depending on POR and clock settings!), let alone possible software crashes (not that such a simple program should be able to crash, but if it happens, well... there you go).

If you need to implement a more complicated function, like a battery monitor or solar charger or artificial sunrise lights or whatever, you're always better off implementing the basic stuff in basic hardware (analog), and wrapping a digital control around that (ADCs/DACs).  You can get away with internal converters in this case, because the bandwidth will probably be low -- how often does the battery voltage / current setpoint need to be updated?  Probably a few times a second, whereas the inductor's current can be monitored in real time by analog circuits with MHz+ bandwidth -- something an MCU shouldn't be required to handle.

Ed: and then, you can use lower bandwidth op-amps for things like current sense -- common mode range is a tricky thing, even for purpose-made current sense devices.  Most don't look very good over 100kHz, right where all the switching ripple is.  A slow monitor doesn't need to worry about that, and it can all be filtered clean.

Quote
I had suspicions like that. :)
But never actually had to take one to it's limits.

Well, an 'optimal' circuit (and program), designed fully around the limitations of the chip, could still do a lot better than what's here.  But that would still be many times inferior to a proper controller chip.

Tim
« Last Edit: September 04, 2014, 09:43:00 am by T3sl4co1l »
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline eneuro

  • Super Contributor
  • ***
  • Posts: 1528
  • Country: 00
Re: Sensing in Attiny85 driven buck converter?
« Reply #10 on: September 04, 2014, 06:40:26 pm »
If you need to implement a more complicated function, like a battery monitor or solar charger or artificial sunrise lights or whatever, you're always better off implementing the basic stuff in basic hardware (analog), and wrapping a digital control around that (ADCs/DACs).  You can get away with internal converters in this case, because the bandwidth will probably be low
Do we realy need Mhz bandwidth for battery charging?
I use ATTiny85 with TL431I voltage reference and Hall current sensor & simply voltage divider @ 250Khz ADC clock, where ADC mesurement takes about 13 clocks, so without any reference voltage changing I can sample current and voltage close to 10000 times per second and in the time when ADC conversion takes place do needed corrections and calculations at 16Mhz internal oscilator  ;)

It is only battery charger and more important is have temperature stable voltage reference I think, so I've choosen industrial version of TL431I while this charger will be used in winter too to keep in full charge lead acid car battery at 13.5V voltage and it looks like even in desulfator mode (without any inductor) this voltage at 10kHz PWM is stable as expected while TL431I is used as AVref on ATTiny PB0 pin  8)
« Last Edit: September 04, 2014, 06:42:19 pm by eneuro »
12oV4dWZCAia7vXBzQzBF9wAt1U3JWZkpk
“Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I have really worked, is mine”  - Nikola Tesla
-||-|-
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22356
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Sensing in Attiny85 driven buck converter?
« Reply #11 on: September 04, 2014, 07:49:57 pm »
Well, the internal control loop usually has ~MHz bandwidth, which is normal for analog error amps.  The minimum will be on par with the switching frequency (give or take a pole-zero pair, the controller usually has a dominant pole not too many times the switching frequency).  Doing it significantly lower than the switching frequency will give you... problems.

An external loop can be as slow as needed, which for a battery, can be in the millihertz.

Is that not what I said?....Aren't we just agreeing?

I would ask you this: how does your battery charger / desulfator respond to a short circuit?  Would you care to demonstrate for us?  If not... well... >:D  As well, 10kHz is ridiculously low for a switching application -- almost in the domain of iron cored chokes -- it's painful to the ears, and bulky to build.  Suppose you wanted to build a smaller one with otherwise the same design, would you be able to?  How would it respond to transients or shorts?

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline eneuro

  • Super Contributor
  • ***
  • Posts: 1528
  • Country: 00
Re: Sensing in Attiny85 driven buck converter?
« Reply #12 on: September 04, 2014, 08:22:14 pm »
I would ask you this: how does your battery charger / desulfator respond to a short circuit?
MCU in this charger is powered from charged battery voltage, so mains 230VAC interrupts does not affect its program flow without storing anything in EEPROM.
There are 2 fuses- 1st small at 230VAC transformer mains and 2nd 15A on its secondary-while two IRFZ44N with 18mRDSON each in pararell and thick 5mm copper tracks should win in the case of shortcircuit on transformer secondary  while those mosfets are rated close to 50A (ID)  >:D
This 2nd fuse may be burned if reverse polarity attched to car battery, but if someone doesn't care about it is better one will have to change this fuse and think about it next time  :-DD

As well, 10kHz is ridiculously low for a switching application
It depends on inductor used and desired output ripple.
Some guys use even 100Hz desulfators, other 1kHz with 5% PWM  ;)
BTW: In desulfator mode inductor is shorted and 20Vmax 10kHz pulses "keep alive" old battery when needed  under steady safe 13.5V  .
« Last Edit: September 04, 2014, 08:28:09 pm by eneuro »
12oV4dWZCAia7vXBzQzBF9wAt1U3JWZkpk
“Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I have really worked, is mine”  - Nikola Tesla
-||-|-
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22356
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Sensing in Attiny85 driven buck converter?
« Reply #13 on: September 04, 2014, 09:32:06 pm »
MCU in this charger is powered from charged battery voltage, so mains 230VAC interrupts does not affect its program flow without storing anything in EEPROM.

Non sequitur?  I mean shorted output.  The beefy ampy sparky end.

If it's supplied by the battery, then how quickly does it shut down?  Does it shut down at all gracefully -- i.e., do transistors get shorted out, or are they turned off within microseconds?

Quote
There are 2 fuses- 1st small at 230VAC transformer mains and 2nd 15A on its secondary-

A noble effort, but only useful for protecting the wiring -- transistors die in 10 us, fuses blow in 10 000 us.

Quote
while two IRFZ44N with 18mRDSON each in pararell and thick 5mm copper tracks should win in the case of shortcircuit on transformer secondary  while those mosfets are rated close to 50A (ID)  >:D

Why would the transformer go short circuit?  The transformer is one of the most reliable parts of your circuit (and the last thing to be afraid of, besides possible surges from the line side).

Beefy transistors are no guarantee of safe operation, in fact the higher current capacity can make things worse, for themselves and for everything around.

A 50A transistor means short circuit currents of at least 50A, if it's accidentally left on during a fault condition.  That's 500W at 10V, which will blow silicon sooner than the fuse will open.

Quote
This 2nd fuse may be burned if reverse polarity attched to car battery, but if someone doesn't care about it is better one will have to change this fuse and think about it next time  :-DD

Ouch, reverse polarity car battery, that's probably orders of magnitude worse than my challenge, a mere short circuit.  And you said the fuse is on the transformer secondary, not the output terminals, correct?  So it won't do anything -- cold cranking current directly into the output transistors / diodes, yikes!

Quote
As well, 10kHz is ridiculously low for a switching application
It depends on inductor used and desired output ripple.
Some guys use even 100Hz desulfators, other 1kHz with 5% PWM  ;)
BTW: In desulfator mode inductor is shorted and 20Vmax 10kHz pulses "keep alive" old battery when needed  under steady safe 13.5V  .

That sounds all kinds of nasty...

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline eneuro

  • Super Contributor
  • ***
  • Posts: 1528
  • Country: 00
Re: Sensing in Attiny85 driven buck converter?
« Reply #14 on: September 04, 2014, 10:14:23 pm »
Non sequitur?  I mean shorted output.  The beefy ampy sparky end.
If it's supplied by the battery, then how quickly does it shut down?  Does it shut down at all gracefully -- i.e., do transistors get shorted out, or are they turned off within microseconds?
It is supplied from battery but the same it charges  and a few lines of code when disconnected will shutdown PWM while even MCu will have VCC above BOD terminals voltage will drop to 0V (below 7V required to switch PWM ON ) when someone will try to put together output terminals taken from the battery ;)
Quote

avol= adc_get(VOLADC );
avol*= ADC_OVERSAMPLE_MUL; // For volatge oversampling
                // Under voltage and shortted wires detection
                if( avol<ADC_VMIN || avol>adcvacumax ) {
                        if(avol<ADC_VMIN || avol>ADC_VMAX ) {
                                acu_duty/= 4;
                        } else {
                                acu_duty/= 2;
                        }
                        pwm_duty( (uint8_t)acu_duty );
                        avol_fuse= 1;
                } else {
                        avol_fuse= 0;
                        pwm_duty( (uint8_t)acu_duty );
                }

Ouch, reverse polarity car battery, that's probably orders of magnitude worse than my challenge, a mere short circuit.  And you said the fuse is on the transformer secondary, not the output terminals, correct?  So it won't do anything -- cold cranking current directly into the output transistors / diodes, yikes!
Output terminals are.. on transformer secondary too  >:D
Even without fuse on terminals outputs, those short output wires would got hot first and.... disapeared  :-DD

This "reference" design works more than 2 years without any problems and nothing burned so far.
I had to take look into its schematics concept and forgot that mosfet internal diodes will block reverse connected battery, so the most difficult (and expensive) silicons to repair are quite safe anyway  :-/O

« Last Edit: September 04, 2014, 10:40:22 pm by eneuro »
12oV4dWZCAia7vXBzQzBF9wAt1U3JWZkpk
“Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I have really worked, is mine”  - Nikola Tesla
-||-|-
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf