Go Down

Topic: Can a pin handle a voltage greater than Vcc if it is just sinking to ground? (Read 894 times) previous topic - next topic

jerseyguy1996

I am putting together a project that will run off of a 3.3V LiPo battery.  I understand that at full power they are about 4.2V and they can be discharged down to about 2.7V.  As such I am running a mega328 at 8MHZ and 3.3V.  My regulated 3.3V will come from a step-down/boost converter (TPS61201DRCT).  The mega328 will be reading values from a GPS module.  The manufacturer of the GPS module makes it very clear in the data sheet that any shutdown should be done in an orderly manner, rather than just pulling the plug on it.  Because of this I want to be able to monitor the battery voltage and shut everything down before the monitor circuit in the battery shuts everything down for me.  I originally was going to use the TPS62237DRYT which is just a step-down converter for my regulated 3.3V.  Using that I could just perform an analog read on the internal voltage reference because Vcc would drop as the battery crossed the 3.3V threshold.  Now that I am considering the boost converter that won't work because it will keep supplying a regulated 3.3V even as the battery drains through 3.3V.  Now I am thinking of reading the battery voltage directly through a voltage divider but my problem with that is that the voltage divider will be a constant drain on the battery....even when the device is not turned on.  Instead I was thinking of running the divider to a digital pin....setting it as an output and writing it to low whenever I want to take a measurement which should be akin to connecting it to ground and then setting it back to an input when the ADC read is complete.  The problem there is that I will have 3.3V on Vcc and potentially as high as 4.2V on that digital pin.  What would be the impact of this?  I have put together a schematic below to illustrate my idea.


example by jg1996business, on Flickr
Arduino Uno;
Mega328

johnwasser

From the ATmega328P datasheet:

28.1 Absolute Maximum Ratings
Voltage on any Pin except RESET with respect to Ground ................................-0.5V to VCC+0.5V
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

jerseyguy1996


From the ATmega328P datasheet:

28.1 Absolute Maximum Ratings
Voltage on any Pin except RESET with respect to Ground ................................-0.5V to VCC+0.5V


So it won't work.  Any other ideas on how to read the battery voltage without constantly draining the battery through a voltage divider?
Arduino Uno;
Mega328

johnwasser


Any other ideas on how to read the battery voltage without constantly draining the battery through a voltage divider?


You can measure the internal 1.1V analog reference relative to AVcc (which will be your battery voltage).  By working backward you can calculate the battery voltage.  You have to set the analog multiplexer register directly to set the analog input to the reference.  Note that the reference is only accurate to 10% (1.0V to 1.2V) so to get accurate results you need to measure the internal reference.  Write a sketch to enable the internal analog reference and do an analogRead(). Then measure the voltage at the Aref pin.  It should be your 1.0 to 1.2V.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Coding Badly


Based on this... http://www.atmel.com/images/doc2508.pdf ...if the resistors are large enough, the processor will not be damaged.  I assume that, when the voltage is above 3.3, the clamping diodes on A0 and D2 would conduct thus defeating the intent.

Does the voltage divider have that much of an effect?  Is a few milliampere drain going to cause a problem?

Coding Badly

You can measure the internal 1.1V analog reference relative to AVcc (which will be your battery voltage).


Would that violate the specifications (AVcc = 4.2 V, Vcc = 3.3 V)?

Personal opinion: I suspect that it would work.  Especially if the digital pin driver is disabled.

retrolefty



From the ATmega328P datasheet:

28.1 Absolute Maximum Ratings
Voltage on any Pin except RESET with respect to Ground ................................-0.5V to VCC+0.5V


So it won't work.  Any other ideas on how to read the battery voltage without constantly draining the battery through a voltage divider?


Well if you would return to your first idea of powering the 328P directly from the battery below is a proof of concept sketch that Coding Badly and I worked on a couple of years ago that allows a sketch to directly determine the actual value of the voltage applied to it's Vcc/Avcc pins. It uses the known internal band-gap reference as a way to 'back calculate' what the applied Vcc must be at any given time.
Of course that still leaves you with a means of how you are going to disconnect the battery once you have performed all the orderly shutdown tasks.

Code: [Select]

// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"

int battVolts;   // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc

void setup(void)
   {
    Serial.begin(38400);
    Serial.print("volts X 100");
    Serial.println( "\r\n\r\n" );
    delay(100);
   }
   
void loop(void)
   {
    battVolts=getBandgap();  //Determins what actual Vcc is, (X 100), based on known bandgap voltage
    Serial.print("Battery Vcc volts =  ");
    Serial.println(battVolts);
    Serial.print("Analog pin 0 voltage = ");
    Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
    Serial.println();    
    delay(1000);
   }

int getBandgap(void) // Returns actual value of Vcc (x 100)
   {
       
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    // For mega boards
    const long InternalReferenceVoltage = 1115L;  // Adjust this value to your boards specific internal BG voltage x1000
       // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc reference
       // MUX4 MUX3 MUX2 MUX1 MUX0  --> 11110 1.1V (VBG)         -Selects channel 30, bandgap voltage, to measure
    ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
 
#else
    // For 168/328 boards
    const long InternalReferenceVoltage = 1056L;  // Adjust this value to your boards specific internal BG voltage x1000
       // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
       // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
    ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
     
#endif
    delay(50);  // Let mux settle a little to get a more stable A/D conversion
       // Start a conversion  
    ADCSRA |= _BV( ADSC );
       // Wait for it to complete
    while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
       // Scale the value
    int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L; // calculates for straight line value
    return results;

   }



Lefty

jerseyguy1996




You can measure the internal 1.1V analog reference relative to AVcc (which will be your battery voltage).  By working backward you can calculate the battery voltage.  You have to set the analog multiplexer register directly to set the analog input to the reference.  Note that the reference is only accurate to 10% (1.0V to 1.2V) so to get accurate results you need to measure the internal reference.  Write a sketch to enable the internal analog reference and do an analogRead(). Then measure the voltage at the Aref pin.  It should be your 1.0 to 1.2V.


But AVcc won't be my battery voltage.  It will be the voltage coming out of the boost converter which will be 3.3V even when the battery is well below 3.3V.
Arduino Uno;
Mega328

jerseyguy1996




Well if you would return to your first idea of powering the 328P directly from the battery below is a proof of concept sketch that Coding Badly and I worked on a couple of years ago that allows a sketch to directly determine the actual value of the voltage applied to it's Vcc/Avcc pins. It uses the known internal band-gap reference as a way to 'back calculate' what the applied Vcc must be at any given time.
Of course that still leaves you with a means of how you are going to disconnect the battery once you have performed all the orderly shutdown tasks.



But I'm not running it directly from the battery.  The mega328 will get a regulated 3.3V from a step-down/boost converter. I've shown this on the schematic above on my original post. That means I can't just read the internal band gap voltage to get the voltage at Vcc because Vcc (assuming the boost converter is working properly) will be regulated to 3.3V regardless of the battery voltage.
Arduino Uno;
Mega328

retrolefty


You can measure the internal 1.1V analog reference relative to AVcc (which will be your battery voltage).


Would that violate the specifications (AVcc = 4.2 V, Vcc = 3.3 V)?

Personal opinion: I suspect that it would work.  Especially if the digital pin driver is disabled.


I believe bad currents start flowing when Vcc and AVcc are not the same, and creates a black hole that sucks us all in.
Datasheet says:
Quote
The ADC has a separate analog supply voltage pin, AVCC. AVCC must not differ more than ±0.3V
from VCC. See the paragraph "ADC Noise Canceler" on page 258 on how to connect this pin.


Lefty

retrolefty





Well if you would return to your first idea of powering the 328P directly from the battery below is a proof of concept sketch that Coding Badly and I worked on a couple of years ago that allows a sketch to directly determine the actual value of the voltage applied to it's Vcc/Avcc pins. It uses the known internal band-gap reference as a way to 'back calculate' what the applied Vcc must be at any given time.
Of course that still leaves you with a means of how you are going to disconnect the battery once you have performed all the orderly shutdown tasks.



But I'm not running it directly from the battery.  The mega328 will get a regulated 3.3V from a step-down/boost converter. I've shown this on the schematic above on my original post. That means I can't just read the internal band gap voltage to get the voltage at Vcc because Vcc (assuming the boost converter is working properly) will be regulated to 3.3V regardless of the battery voltage.


Just giving you an alternate look at the universe.  ;)

jerseyguy1996



Based on this... http://www.atmel.com/images/doc2508.pdf ...if the resistors are large enough, the processor will not be damaged.  I assume that, when the voltage is above 3.3, the clamping diodes on A0 and D2 would conduct thus defeating the intent.

Does the voltage divider have that much of an effect?  Is a few milliampere drain going to cause a problem?


Based on your link, it appears I could just bring the battery plus side to the analog pin directly through a current limiting resistor and read the voltage.  It will read 255 (or whatever the max value for 10-bit resolution is) until the voltage falls below 3.3V.  The internal clamping diodes will protect the pin as long as I supply enough current limiting to it.  Is this right?
Arduino Uno;
Mega328

jerseyguy1996






Well if you would return to your first idea of powering the 328P directly from the battery below is a proof of concept sketch that Coding Badly and I worked on a couple of years ago that allows a sketch to directly determine the actual value of the voltage applied to it's Vcc/Avcc pins. It uses the known internal band-gap reference as a way to 'back calculate' what the applied Vcc must be at any given time.
Of course that still leaves you with a means of how you are going to disconnect the battery once you have performed all the orderly shutdown tasks.



But I'm not running it directly from the battery.  The mega328 will get a regulated 3.3V from a step-down/boost converter. I've shown this on the schematic above on my original post. That means I can't just read the internal band gap voltage to get the voltage at Vcc because Vcc (assuming the boost converter is working properly) will be regulated to 3.3V regardless of the battery voltage.


Just giving you an alternate look at the universe.  ;)


Actually I would love to run it directly off the battery (which I think is what you are saying) but I am going to be running the GPS module and an SD card off of the same supply and they are only 3.3V tolerant (at least according to the datasheet absolute maximum ratings).  I figure running the mega328 at 3.3V gets me around having to do a bunch of logic level shifting for the communications.
Arduino Uno;
Mega328

jerseyguy1996

basically it would just look like this and I would rely on the pin protection diodes to limit the voltage to Vcc+.3


example2 by jg1996business, on Flickr
Arduino Uno;
Mega328

Coding Badly

It will read 255 (or whatever the max value for 10-bit resolution is) until the voltage falls below 3.3V.


1023.

Quote
The internal clamping diodes will protect the pin as long as I supply enough current limiting to it.  Is this right?


That is my understanding.  It is also my understanding that protection is obtianed by the diode conducting.  Which would be a constant drain on the battery just like the voltage divider (until the battery drops below 3.3V).  Which brings us full circle to my earlier question.  Is the voltage divider that much of a drain to be a problem?

Go Up