hi
I want to make very simple led blink module using a Attiny202, but I want to make it blink differently when its supply voltage is getting low. how can I measure the supply voltage? I know the esp32 can read its own supply voltage. is there a similar command for the Attiny202? ( or Attiny85 or 84 similar...)
the project needs to use the least possible power.
thanks
From the datasheet, here are the input multiplex entries for the ATmega328P ADMUX register:
The key one is the 1110 setting, which sets the ADC input to the internal "bandgap" 1.1V, which is fixed. This lets you measure the 1.1V source with reference to Vcc. Normally the bandgap voltage is used as a reference voltage, but this lets you use it as an input.
I don't think this option is widely available in other Atmel processors. You would need to download the datasheets of the other processors, find the ADC register descriptions, and see if they have the same input option.
This is useful if you are powering the processor directly from a battery at its Vcc pin, with no regulator, so Vcc is actually the battery voltage. Then you can measure battery voltage without wasting any power in resistive dividers, or even devoting a pin to the process. This works for the Uno, Nano and Pro Mini, but I don't know about the various ATtiny flavors.
Edit: This Github repo suggests this also works on the ATtiny84 and 85:
https://github.com/cano64/ArduinoSystemStatus
Don't know about the 202.
The 202 also supports reading the reference voltage, but it has a separate possible voltages, that you would also probably need to configure.
"But all the official Arduino boards have regulated power supplies!"
Also, potentially dangerous: I don't know what happens if you set Vref below the current analog inputs, even momentarily.
I dont see why it should be a problem - but thats an interesting point.
Also when you switch the reference the system may need time to re-stabilize.
To complete things, here's code from back in the day that shows this process for the 328P. For other processors the register settings could be different. Note that the 1.1V bandgap varies somewhat from chip to chip.
// 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(9600);
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);
delay(1000);
}
int getBandgap(void) // Returns actual value of Vcc (x 100)
{
// For 168/328 boards
const long InternalReferenceVoltage = 1059L; // 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);
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;
}
Ah. So on further consideration, it's not going to matter.
To measure Vcc, one sets the ADC Vref to Vcc and then reads an internal Aref. All the analog pins have to be below Vcc...
On the chips with multiple Aref capability, you'd need to remember the old setting, and possibly deal with "do an extra conversion after changing Vref" issues.
The code is just something I found somewhere. My understanding is the 1059L is just a calibration entry for the chip. It would be different for each chip since the bandgap voltage is only approximately 1.1V. I assume the author got it by finding the value that made the output of the sketch match the measured Vcc voltage. And AREF isn't brought out on the Pro Mini, and I assume the Attiny's.
As for the other corrections, could you explain what they are all about, and why they are needed?
Thanks very much for the explanation. It all makes sense. But can I talk you into putting the new version all into the .ino?
At what point of the following curves (Fig-1, Vcc-vs-Freq), you want to operate your Attiny85 MCU? If you provide the answer, codes could be developed and tested to
measure the Vcc voltage using Attiny85 Dev Board (Fig-2).
Figure-1:
Figure-2:
lowest possible frequency. the circuit will be laid out for 3V but will run until the battery dies. (Li coin)
A bit off topic, but what is the reason for including the zero bits in this kind of OR string:
ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) ... etc.
With the 328P at least, I've found that the processor draws materially less current at lower VCC voltages. So in one case I ended up using a 3.3V linear regulator to power a 3.3V 8MHz Pro Mini with power coming from an 18650. The reduced current draw at 3.3V versus 3.8V or 4.0V or 4.2V made up for the very low current drawn by the LDO. So using a regulator actually increased battery life.
This depends on the LDO being pretty good - low quiescent current, very low dropout voltage, and most important - the output has to follow the input voltage on down when the dropout level can no longer be satisfied.
I don't know if this is workable in your case because you're using a 3V coin cell. But if for example the ATTiny will work for you down to 2.4V, you could use a 2.8V regulator and still read the battery voltage, in effect, when VCC begins to drop below 2.8V.
Well, just something to think about.
Well, my point is that you ony have to include the 1 bits. You can shift left a 0 bit till the cows come home, and you're still ORring nothing into the final value. It just seems to be a curious thing to do.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.