Teensy 3 and ADC : is there a way to sample in "normal stop mode" ?

Status
Not open for further replies.

davidt

Member
Hi,

I'm trying to get the most of a teensy LC ADC, and reading the datasheet :

31.6.2.3 Noise-induced errors : Operate the MCU in Wait or Normal Stop mode [...] immediately after initiating (hardware- or software-triggered
conversions) the ADC conversion

I had a look at pepvide's ADC library (which I'm using now), and I think it has no provision to do that.
I can only see it looping like this : while( isConverting() ) yield();

Did I miss something ?
If not : what would you think of some method tailored for maximum accuracy that would put the mcu in stop mode while the conversion is being done ?
Looking at both ADC and Snooze libraries, I tend to think I could get by mixing a bit of ADC::analogRead and Snooze::enter_stop to come up with ADC::highAccuracyanalogRead ...
Do you think (a) this would be worth the pain ; (b) this would work ?

David
 
I imagine it should work yes.

I'd say it probably is worth it actually. It's fairly common practice actually to reduce clock speed and enter a sleep mode while taking high accuracy ADC readings.
There's always averaging data though
 
Currently only "VLPW" Very Low Power Wait Mode is used in Snooze which is combination of going to 2 MHz BLPI Clock mode and then VLPR (Very Low Power Run) before sleeping which can be used for this, deepSleep or hibernate (LLS, VLLSx) won't work I believe though i could be wrong. This will definitely effect the high speed ADC conversion while sleeping since the bus speed is only at 2 MHz. Though I haven't really looked at using the adc in sleep mode it would interesting to know if it works well. I did read that this technique is good for getting the most bits out of the Teensy adc since the internal noise is reduced because clocks and such are off.

There is no code to really look at for this currently in Snooze but I can help when you get more familar with it. I plan on adding these special sleep mode hardware stuff eventually to Snooze for the LC since it has some really cool features in this regards.
 
You could use the startSingleRead, then go to the MCU state you want and check with
Code:
while( isConverting() ) {yield();}
until it's done and return the MCU to whatever state you want.

However a perhaps better way is to use the ADC asynchronous clock with setConversionSpeed(speed), where speed=ADC_ADACK_2_4, ADC_ADACK_4_0, ADC_ADACK_5_2 and ADC_ADACK_6_2. The numbers are the frequency of the ADC clock (ADCK) in MHz and are independent on the bus speed. This should isolate the ADC a bit better and it's already implemented.
 
I did read about the ADC clock, and indeed planned on using those ADC_ADAC* speeds.

If I understand Freescale's recommandation properly, the idea is to bring the MCU to a "complete" stop while the conversion is in progress.
Looping on isConverting() and yield() is too much activity already.
Of course, a "complete stop" actually means "as complete as possible yet being able to wake up when conversion is finished".
So I was hoping to implement something like :
1- configure ADC
2- kick in conversion, requesting an interrupt to be raised when finished
3- bring mcu to full stop -- no polling of any kind, so long serialEvent, etc.
4- conversion finished, interrupt fired
5- mcu wakes up and picks up where it left off
6- mcu reads ADC conversion result, and ... etc.

Steps 1 and 2 are already performed by functions such as startSingleRead, etc. These are code snippets I'm likely to reuse somehow.
What I don't know yet, is :
-will enabling interrupt (in your library's sense) be enough to wake up a stopped mcu ?
-how do I implement step 3 in order for step 5 to happen as desired ...
 
I can't really help you with that, as I have no experience with those modes. The rest of your code flow seems correct to me.
Good luck with it, and please post the code if it works, or I guess even if it doesn't.
 
Status
Not open for further replies.
Back
Top