Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Measure Vcc over Bandgap Voltage in Battery powered devices

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic  
Author Message
MAK3

Bascom Member



Joined: 24 Sep 2010
Posts: 449
Location: Germany

germany.gif
PostPosted: Sat Oct 29, 2011 8:17 pm    Post subject: Measure Vcc over Bandgap Voltage in Battery powered devices Reply with quote

Hi,


This example show how to measure the Vcc over the Band Gap Voltage (Vbg)
'You especially want or need this when using a battery powered device where you want to react when battery is below a defined value
Then Vcc = Vbatt
'The Value of Vbg can be found in the datasheet and is 1.1 Volt but can differ between 1.0 and 1.2 Volt

So when you set the Reference Voltage for the ADC to Vcc then you can calculate
Vcc = Vbg * 1024/measured ADC Value
Vcc = 1.1Volt * 1024/measured ADC Value

For example measured ADC Value = 470 --> Vcc = 1.1 * 1024/470 = 2.39 Volt
For example measured ADC Value = 375 --> Vcc = 1.1 * 1024/375 = 3.00 Volt

Because the Vbg can differ you can measure the Vbatt with ad DMM and change the Vbg Value to the real value like 1.13 Volt in the following example

This example shows also how you can use the ADC Noise Canceler of an AVR

The serial out is only as debug interface to PC (this would need to much Flash of the ATTINY25)
Without the serial out debug interface enabled this example need 19% of Flash with enough room for your application (or use ATtiny45 or 85)

The Watchdog is activated already in Fuse Bits and the task of the Watchdog in this case is waking up the Attiny from powerdown mode
Because it is a battery powerd device it is sleeping most of the time, wake up after the watchdog interrupt fires run through the program and get back to sleep mode

My Circuit with ATTINY25 need 1mA in active mode and 4.7ľA in PowerDown mode which meets the specs in the Datasheet.
When the serial output is connected to a USB to UART device then the PowerDown mode rise to app. 80ľA.

Disconnect the ISP Programmer before measuring the current !


Code:
' FUSE BITS:
' Division/8 enabled, WDTON FuseBit enabled and we use the internal 8MHz Oscillator
' This example use the internal 8MHz clock with division/8 enabled resulting in 1MHz Clock

' This example show how to measure the Vcc over the Band Gap Voltage (Vbg)
' You especially want or need this when using a battery powered device where you want to react when battery is below a defined value
' The Value of Vbg can be found in the datasheet and is 1.1 Volt but can differ between 1.0 and 1.2 Volt

' So when you set the Reference Voltage for the ADC to Vcc then you can calculate
' Vcc = Vbg * 1024/measured ADC Value
' Vcc = 1.1Volt * 1024/measured ADC Value

' For example measured ADC Value = 470 --> Vcc = 1.1 * 1024/470 = 2.39 Volt
' For example measured ADC Value = 375  --> Vcc = 1.1 * 1024/375 = 3.00 Volt

' Because the Vbg can differ you can measure the Vbatt with ad DMM and change the Vbg Value to the real value like 1.13 Volt in the following example

' This example shows also how you can use the ADC Noise Canceler of an AVR

' The serial out is only as debug interface to PC  (this would need to much Flash of the ATTINY25)
' Without the serial out debug interface enabled this example need 19% of Flash with enough room for your application (or use ATtiny45 or 85)

' The Watchdog is activated already in Fuse Bits and the task of the Watchdog in this case is waking up the Attiny from powerdown mode
' Because it is a battery powerd device it is sleeping most of the time, wake up after the watchdog interrupt fires run through the program and get back to sleep mode

' My Circuit with ATTINY25 need 1mA in active mode and 4.7ľA in PowerDown mode which meets the specs in the Datasheet.
' When the serial output is connected to a USB to UART device then the PowerDown mode rise to app. 80ľA.


$regfile = "attiny25.dat"
$crystal = 1000000                                '1Mhz (8MHz/8 = 1Mhz)  'FuseBit : Division/8 enabled and we use internal 8Mhz Oscillator
$hwstack = 24
$swstack = 16
$framesize = 40

Const Adc_noise_canceler = 1                      '1 = use adc_noise_canceler , 0 = use getadc function

Const Use_serial_debug_out = 1



Config Watchdog = 8192                            'wakeup every 8 Seconds (WDTON FuseBit enabled !)
Start Watchdog
On adcc adc_interrupt

Enable Interrupts

'Power Savings setting
Set Acsr.acd                                      'switch off the power to the Analog Comparator
Set Didr0.ain0d                                   'digital input buffer on the AIN0 pin is disabled to reduce power consumption
Set Didr0.ain1d                                   'digital input buffer on the AIN1 pin is disabled to reduce power consumption
Set Prr.prusi                                     'Power Reduction USI
Set Prr.prtim0                                    'Power Reduction Timer0
Set Prr.prtim1                                    'Power Reduction Timer1
'The simplest method to ensure a defined level of an unused pin, is to enable the internal pull-up.
Set Portb.0                                       'Enable Pullup
Set Portb.1                                       'Enable Pullup
Set Portb.2                                       'Enable Pullup
'Set Portb.3                                       'Enable Pullup  'This is also the serial output
Set Portb.4                                       'Enable Pullup

'Portb.5 is reset and have an external Pullup


#if Use_serial_debug_out = 1
   Open "comb.3:2400,8,n,1" For Output As #1
#endif

Dim B As Byte

Dim W As Word
Dim W_low_byte As Byte At W Overlay
Dim W_high_byte As Byte At W + 1 Overlay


#if Use_serial_debug_out = 1
  Dim Measurement As Single
#endif




'Use ADC Noise Canceler or use config ADC and getadc
#if adc_noise_canceler = 1
   For b = 1 to 4
      Adcsra = Bits(aden , Adie , Adps1 )         'Enable ADC, Interrupt Enable, Prescaler = 4 --> 1MH/4 = 250KHz
      Admux = &B0000_1100                         'VCC used as Voltage Reference, Mux = Vbg
      Power Adcnoise                              'Jump in Noise canceler mode
      'AVR will wakeup with ADC conversion complete Interrupt
   next
#else
   Config Adc = Single , Prescaler = Auto , Reference = Avcc       'Reference is Vcc

  'To get a good measurement we need to call getadc 4 times
   For B = 1 To 4
      W = Getadc(0 , 12)                            '12 --> Set Multiplexer to measure Band Gap Voltage
   Next
#endif




' Vcc = 1.1 Volt * 1024/ADC output Value

' 1.1 * 1024 = 1226.4 but Band Gap Voltage can be min = 1.0 Volt and max = 1.2 Volt
' In my case I changed the Value to get the same measurement as when I measure it with external DMM
' That's why I use 1158 (which is a Band Gap Voltage of 1.13 Volt)

#if Use_serial_debug_out = 1
     Measurement = 1158 \ W
#else
    'so something when W is below a defined value
#endif


#if Use_serial_debug_out = 1
   Print #1 , W
   Print #1 , "Vcc= " ; Fusing(measurement , "#.##")
#endif


'Wait is Only for testing
Wait 4                                            'This is only for easy measuring the current in active mode



'Prepare Powerdown
Reset Adcsra.aden                                 'Disable ADC
Set Prr.pradc                                     'Power Reduction ADC

Power Powerdown


End                                               'end program


adc_interrupt:
  W_low_byte = Adcl                                 'First read Low Byte
  W_high_byte = Adch
return



MAK3


Last edited by MAK3 on Mon Oct 31, 2011 12:52 pm; edited 2 times in total
Back to top
View user's profile
Ross_ValuSoft

Bascom Member



Joined: 20 Nov 2005
Posts: 275
Location: Melbourne, Australia

australia.gif
PostPosted: Mon Oct 31, 2011 12:44 am    Post subject: Reply with quote

Thanks for sharing.

However, perhaps you could edit your post to correct the error in this ...

Code:
' For example measured ADC Value = 470  --> Vcc = 1.1 * 1024/422 = 2.66Volt


Cheers,

Ross
Back to top
View user's profile
MAK3

Bascom Member



Joined: 24 Sep 2010
Posts: 449
Location: Germany

germany.gif
PostPosted: Mon Oct 31, 2011 9:10 am    Post subject: Reply with quote

ross_valusoft,

thanks, I changed it to
Code:
For example measured ADC Value = 470  --> Vcc = 1.1 * 1024/470 = 2.39 Volt


I should also add that not every AVR is able to measure the internal Bandgap Voltage (Vbg). For example with an Attiny13 you can not choose Vbg in the ADMUX (ADC multiplexer) setting and therefore you can not measure it internally.

MAK3
Back to top
View user's profile
Ross_ValuSoft

Bascom Member



Joined: 20 Nov 2005
Posts: 275
Location: Melbourne, Australia

australia.gif
PostPosted: Mon Oct 31, 2011 12:02 pm    Post subject: Reply with quote

Sorry to be a pest ... but it is still wrong in your code. Someone might only copy your code ...

Best wishes,

Ross (who sometimes proof-reads technical documents)
Back to top
View user's profile
MAK3

Bascom Member



Joined: 24 Sep 2010
Posts: 449
Location: Germany

germany.gif
PostPosted: Mon Oct 31, 2011 12:57 pm    Post subject: Reply with quote

Hi ross_valusoft,

Quote:
who sometimes proof-reads technical documents


Well done !

Best Regards,
MAK3
Back to top
View user's profile
Dave

Bascom Member



Joined: 05 Feb 2005
Posts: 314
Location: OR

usa.gif
PostPosted: Tue Sep 16, 2014 6:07 pm    Post subject: Reply with quote

MAK3

This is a great tip. Extremely useful. Thank you!

Dave
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here All times are GMT + 1 Hour
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
You cannot attach files in this forum
You cannot download files in this forum