Search This Blog

Monday, 6 April 2015

You have to see this Rich ADC library for Teensy 3.1 !!!

Several months ago, while working on my Robotic shield for the Teensy 3.1,  I had stumbled across this extremely rich and robust implementation of an ADC library, here  on the Teensy forum.
(https://forum.pjrc.com/threads/25532-ADC-library-update-now-with-support-for-Teensy-3-1 )  Edit: updated as per author of library (15/04/06)

Written by a user of the Teensy, Pedro Villanueva started this library just over a year ago, but has implemented  most, if not all, functions of the Teensy 3.1 including use of both ADC available in the Teensy 3.1, as well as differential readings on the two built-in differential channels (A10-A11 and A12-A13).
 
Along with this library, he has written a simple ring buffer implementation which will prove quite handy.  There are also a number of very informative and well thought out examples.



List of methods of the library:
int ADC::analogRead ( uint8_t pin )
Returns the analog value of the pin.
It waits until the value is read and then returns the result. If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.

int ADC::analogReadContinuous ( )
Reads the analog value of a continuous conversion.
Set the continuous conversion with with analogStartContinuous(pin) or startContinuousDifferential(pinP, pinN)
Returns the last converted value.

int ADC::analogReadDifferential ( uint8_t pinP, uint8_t pinN )
Reads the differential analog value of two pins (pinP - pinN).
It waits until the value is read and then returns the result. If a comparison has been set up and fails, it will return ADC_ERROR_DIFF_VALUE.

void ADC::disableCompare ( )
Disable the compare function.

void ADC::disableDMA ( )
Disable ADC DMA request.

void ADC::disableInterrupts ( )
Disable interrupts.

void ADC::enableCompare ( int16_t compValue, int greaterThan )
Enable the compare function to a single value.
A conversion will be completed only when the ADC value is >= compValue (greaterThan=1) or < compValue (greaterThan=0) Call it after changing the resolution Use with interrupts or poll conversion completion with isADC_Complete()

void ADC::enableCompareRange ( int16_t lowerLimit, int16_t upperLimit,
int insideRange, int inclusive )

Enable the compare function to a range.
A conversion will be completed only when the ADC value is inside (insideRange=1) or outside (=0) the range given by (lowerLimit, upperLimit),including (inclusive=1) the limits or not (inclusive=0). See Table 31-78, p. 617 of the freescale manual. Call it after changing the resolution Use with interrupts or poll conversion completion with isComplete()

void ADC::enableDMA ( )
Enable DMA request.
An ADC DMA request will be raised when the conversion is completed (including hardware averages and if the comparison (if any) is true).

void ADC::enableInterrupts ( )
Enable interrupts.
An IRQ_ADC0 Interrupt will be raised when the conversion is completed (including hardware averages and if the comparison (if any) is true).

double ADC::getMaxValue ( )
Returns the maximum value for a measurement, that is: 2^resolution.

int ADC::getResolution ( )
Returns the resolution of the ADC.

int ADC::isComplete ( )
Is an ADC conversion ready?
Returns  1 if yes, 0 if not. When a value is read this function returns 0 until a new value exists So it only makes sense to call it before analogRead(), analogReadContinuous() or analogReadDifferential()

int ADC::isConverting ( )
Is the ADC converting at the moment?
Returns  1 if yes, 0 if not

void ADC::setAveraging ( unsigned int num )
Set the number of averages.
Parameters
num can be 0, 4, 8, 16 or 32.

void ADC::setReference ( uint8_t type )
Set the voltage reference you prefer, default is vcc.
Parameters
type can be DEFAULT, EXTERNAL or INTERNAL

void ADC::setResolution ( unsigned int bits )
Change the resolution of the measurement.
Parameters
bits is the number of bits of resolution. For single-ended measurements: 8, 10, 12 or 16 bits. For differential measurements: 9, 11, 13 or 16 bits. If you want something in between (11 bits single-ended for example) select the inmediate higher and shift the result one to the right.

void ADC::startContinuous ( uint8_t pin )
Starts continuous conversion on the pin.
It returns as soon as the ADC is set, use analogReadContinuous() to read the value.

void ADC::startContinuousDifferential ( uint8_t pinP, uint8_t pinN )
Starts continuous conversion between the pins (pinP-pinN).
It returns as soon as the ADC is set, use analogReadContinuous() to read the value.

void ADC::stopContinuous ( )
Stops continuous conversion.

int ADC::startSingleRead(uint8_t pin)
Starts an analog measurement on the pin and enables interrupts. It returns inmediately, get value with readSingle(). If the pin is incorrect it returns ADC_ERROR_VALUE This function is interrupt safe. The ADC interrupt will restore the adc to its previous settings and restart the adc if it stopped a measurement. If you modify the adc_isr then this won't happen.

int ADC::startSingleDifferential(uint8_t pinP, uint8_t pinN)
Same as above but with differential measurements.

int ADC::readSingle() 
Reads the analog value of a single conversion. Set the conversion with with startSingleRead(pin) or startSingleDifferential(pinP, pinN).




References:

Teensy Forum: User Pedvide 
Github: Pedvide/ADC 
https://forum.pjrc.com/threads/24399-quot-Complete-quot-implementation-of-Teensy-3-0-ADC-as-a-library 
Freescale: K20 Sub-Family Reference Manual 
Freescale: App Note - ADC measurements done properly
Freescale: Using DMA to Emulate ADC Flexible Scan Mode on Kinetis K Series 
Freescale: App Note - AN2438/D 2/2003 ADC Definitions and Specifications