Here are a couple of details that help keep TeensyLC hibernate current
as low as possible. a) before hibernate delare pin 17 as output and
write a high or low to it to prevent the input of the buffer chip from
floating at an intermediate level due to leakages (this can cause up to
240 ua of extra Iq during hibernate). b) if you are using the atod
converter and any of the analog input(s) could be somewhere far from
the rails (not close to 0 or 3.3) during hibernate this can cause an
extra 70-100 ua of Iq. For a telemetry transmitter that hibernates most
of the time and sends two analog values over the radio once each minute,
low Iq was more important than conversion bandwidth. In my case a10 and
a11 were connected to very high dc impedance resistive dividers (2.2 meg
and 470k to minimize drain from the batteries being measured) fed from
batteries to monitor two voltages in the 0-18 volt range. A relatively
large capacitance (100n) was used at pins a10 and a11 to keep the
dynamic impedance low during conversions. Because a10 and a11 could
be below 3.3 or above 0 during hibernate the extra Iq mentioned above
was occurring. Fix is to tie pin 2 to a10 and pin 3 to a11 and use
those two pins as outputs to drag a10 and a11 very near ground during
hibernation. Upon wakeup pins 2 and 3 are declared as inputs followed
by a delay allowing the dividers and capacitors 5 time constants, the
conversions are done, and the pins re-stated as outputs that are low
again. Using these two pre cautions the Iq during hibernate (including
the drain of an LM2936-5 regulator) is typically 11-12 ua.
The hardware datasheet for the mcu used in the TeensyLC shows that the
input current into analog inputs is typically only 0.025 ua but I think
they forgot to look at Iq vs analog input voltage, and it is hard to
imagine why they did not do that and/or put the results in the data-
sheet when the extra current can be 10x sleeping current if the analog
input(s) are near mid-supply sleeping current. This extra Iq tapers
down to nil as you move away from mid-supply towards either supply rail.
Code:
//
// note input divider r's are 2.2 meg and 470 k
unsigned short int value1,value2,wrd1,wrd2;
unsigned int ch1,ch2;
// atod function
void atod() {
// release a10 and a11
pinMode(2,INPUT);
pinMode(3,INPUT);
// wait for 5 time const
delay(250);
// actual conversions
value1 = adc->analogRead(A10,ADC_0);
value2 = adc->analogRead(A11,ADC_0);
// limit results
if (value1<0) value1=0;
if (value2<0) value2=0;
if (value1>4095) value1=4095;
if (value2>4095) value2=4095;
// offset error comp both chan
ch1=(value1-1);
ch2=(value2-1);
if(ch1<0)ch1=0;
if(ch2<0)ch2=0;
// error scaling both chan
ch1=ch1*34330;
ch1=ch1>>15;
ch2=ch2*34315;
ch2=ch2>>15;
value1=ch1;
value2=ch2;
// re-clamp a10 and a11
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
digitalWrite(2,LOW);
digitalWrite(3,LOW);
wrd1=value1;
wrd2=value2;
}
int main() {
// declare pin 17 as output
pinMode(17, OUTPUT);
// put pin 17 buffer input at one rail
digitalWrite(17, LOW);
//
pinMode(A10, INPUT);
pinMode(A11, INPUT);
//
//
adc->setAveraging(32); // set number of averages
adc->setResolution(12); // set bits of resolution
adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED, ADC_0);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_LOW_SPEED, ADC_0);
//