ADC library, with support for Teensy 4, 3.x, and LC

Sorry I am not @christoph, but most of these are defines for registers and bits within registers...

They are defined in kinetish.h (in your install point)/hardware/teensy/avr/cores/teensy3

They are defined for the different registers and bits within..
Example VREF_TRM_CHOPEN is defined at line 3032 and has to do with VREFV1...

So if you look at for example the Teensy 3.6 reference PDF you will see that the VREF Trim register section 42.3.1 (VREF_TRM)
One of the bits is named CHOPEN - which you can then read about what its functionality is.
 
thanks KurtE I found the relevant stuff, near line # 3030 in kinetis.h (huge file!)

so now I know ... it's a PJRC-wide convention :)
 
read 2 differential analog signals simultaneously using teensy 3.2

Hello everyone
I try to read 2 differential analog signals simultaneously using teensy 3.2 and I used the following function:
analogSyncReadDifferential( A10, A11 , A12, A13,);

based on the function in the main library which is:
int analogReadDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);

I think that I have a mistake in parameters of the function, I tried a lot but I didn't have the right form of them
can anyone explain me the meaning of "adc_num = -1", please?

the code:
#include <ADC.h>
ADC *adc = new ADC(); // adc object
float lm35_voltage;
float lm35_temp;
float max_value0;
float max_value1;
float rslt0;
float rslt1;
int Gain=1;
void setup() {

pinMode(A10, INPUT); //Diff Channel 0 Positive
pinMode(A11, INPUT); //Diff Channel 0 Negative
pinMode(A12, INPUT); //Diff Channel 0 Positive
pinMode(A13, INPUT); //Diff Channel 0 Positive

Serial.begin(9600);

adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0);
adc->setReference(ADC_REFERENCE::REF_1V2, ADC_1);

//teensy 3.1 and 3.2 have an internal 1.2v reference

///// ADC0 ////

adc->enablePGA(Gain, ADC_0); // gain can be 1,2,4,8,16,32,64
// Use only for signals lower than 1.2 V and only in differential mode
adc->enablePGA(Gain, ADC_1);
delay(500);
}

void loop() {
// put your main code here, to run repeatedly:
max_value0= adc->getMaxValue(ADC_0);
max_value1= adc->getMaxValue(ADC_1);

Sync_result analogSynchronizedReadDifferential( A10, A11,A12,A13);

rslt0=ADC::Sync_result .result_adc0 = adc->analogSyncRead(A10, A11)*1.2/max_value0;
rslt1=ADC::Sync_result .result_adc1 = adc->analogSyncRead(A10, A11)*1.2/max_value1;



Serial.print("rslt0=");
Serial.println(rslt0);

Serial.print("rslt1=");
Serial.println(rslt1);


}
 
Last edited:
Not sure where you got some of those commands..... Try looking at the examples. You can sample any 2 pins simultaneously, that includes the differentials.

This should work, I don't have any Teensy's around since I'm at work.
Code:
#include <ADC.h>
ADC *adc = new ADC(); // adc object
float lm35_voltage;
float lm35_temp;
float max_value0;
float max_value1;
float rslt0;
float rslt1;
int Gain=1;
void setup() {

pinMode(A10, INPUT); //Diff Channel 0 Positive
pinMode(A11, INPUT); //Diff Channel 0 Negative
pinMode(A12, INPUT); //Diff Channel 0 Positive
pinMode(A13, INPUT); //Diff Channel 0 Positive

Serial.begin(9600);

adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0);
adc->setReference(ADC_REFERENCE::REF_1V2, ADC_1);

//teensy 3.1 and 3.2 have an internal 1.2v reference

///// ADC0 ////

adc->enablePGA(Gain, ADC_0); // gain can be 1,2,4,8,16,32,64
// Use only for signals lower than 1.2 V and only in differential mode
adc->enablePGA(Gain, ADC_1);
delay(500);
}

void loop() {
  delay(100);  //dont need to flood the PC with data....
// put your main code here, to run repeatedly:
max_value0= adc->getMaxValue(ADC_0);
max_value1= adc->getMaxValue(ADC_1);


rslt0 = adc->analogReadDifferential(A10, A11)*1.2/max_value0;
rslt1 = adc->analogReadDifferential(A12, A13)*1.2/max_value1;




Serial.print("rslt0=");
Serial.println(rslt0);

Serial.print("rslt1=");
Serial.println(rslt1);


}
 
Hi, I am not a very good coder and mostly copy and paste so sorry if this is obvious, I would like to use @kripthor code for his MicLoc project but I keep getting the error " 'channel2sc1aADC0' is not a member of 'ADC_Module' "

I have arduino 1.8.5 and downloaded the latest teensyduino and have install the pedvide ADC library.

Here is the code
Code:
/* Example for analogRead
*  You can change the number of averages, bits of resolution and also the comparison value or range.
*/


#include <ADC.h>

#define ADC_0 0
#define ADC_1 1


// Teensy 3.0 has the LED on pin 13
const int ledPin = 13;


void highSpeed8bitADCSetup(){
  
  /*
      0 ADLPC (Low-Power Configuration)
      0 ADIV (Clock Divide Select)
      0
      0 ADLSMP (Sample time configuration)
      0 MODE (Conversion mode selection) (00=8/9, 01=12/13, 10=10/11, 11=16/16 bit; diff=0/1)
      0
      0 ADICLK (Input Clock Select)
      0
  */
  ADC0_CFG1 = 0b00000000;
  ADC1_CFG1 = 0b00000000;
   /*
      0 MUXSEL (ADC Mux Select)
      0 ADACKEN (Asynchrononous Clock Output Enable)
      0 ADHSC (High-Speed Configuration)
      0 ADLSTS (Long Sample Time Select) (00=+20 cycles, 01=+12, 10=+6, 11=+2)
      0
  */
  ADC0_CFG2 = 0b10100;
  ADC1_CFG2 = 0b10100;

  
  /*
      0 ADTRG (Conversion Trigger Select)
      0 ACFE (Compare Function Enable)
      0 ACFGT (Compare Function Greater than Enable)
      0 ACREN (Compare Function Range Enable)
      0 ACREN (COmpare Function Range Enable)
      0 DMAEN (DMA Enable)
      0 REFSEL (Voltage Reference Selection) (00=default,01=alternate,10=reserved,11=reserved)
  */
  ADC0_SC2 = 0b0000000;
  ADC1_SC2 = 0b0000000;
 
  /*
      1 CAL (Calibration)
      0 CALF (read only)
      0 (Reserved)
      0
      0 ADCO (Continuous Conversion Enable)
      1 AVGS (Hardware Average Enable)
      1 AVGS (Hardware Average Select) (00=4 times, 01=8, 10=16, 11=32)
      1
  */
  
  ADC0_SC3 = 0b1000000;
  ADC1_SC3 = 0b1000000;

  
  // Waiting for calibration to finish. The documentation is confused as to what flag to be waiting for (SC3[CAL] on page 663 and SC1n[COCO] on page 687+688).
  while (ADC0_SC3 & ADC_SC3_CAL) {} ;
  while (ADC1_SC3 & ADC_SC3_CAL) {} ;

}


void setup() {



  pinMode(ledPin, OUTPUT);
  pinMode(A2, INPUT); //pin 23 single ended
  pinMode(A3, INPUT); //pin 23 single ended
  pinMode(A10, INPUT); //pin 23 single ended
  pinMode(A11, INPUT); //pin 23 single ended
  Serial.begin(115200);

  highSpeed8bitADCSetup();
  delay(500);
  Serial.println("end setup");
}



int value1 = ADC_ERROR_VALUE;
int value2 = ADC_ERROR_VALUE;
int value3 = ADC_ERROR_VALUE;
int value4 = ADC_ERROR_VALUE;


int startTime;
int stopTime;
int totalTime;
int i;
int samples = 100000;
int samplesPerSec;

ADC::Sync_result result;

#define CHANNEL_A0 5
#define CHANNEL_A1 14
#define CHANNEL_A2 8
#define CHANNEL_A3 9
#define CHANNEL_A4 13
#define CHANNEL_A5 12
#define CHANNEL_A6 6
#define CHANNEL_A7 7
#define CHANNEL_A8 15
#define CHANNEL_A9 4
#define CHANNEL_A10 0
#define CHANNEL_A11 19
#define CHANNEL_A12 3
#define CHANNEL_A13 147

#define highSpeed8bitAnalogReadMacro(channel1, channel2) ADC0_SC1A = channel1;ADC1_SC1A = channel2;while (1) {if ((ADC0_SC1A & ADC1_SC1A & ADC_SC1_COCO)) {break;}}value1 = ADC0_RA;value2 = ADC1_RA;

int highSpeed8bitAnalogRead(uint8_t channel1, uint8_t channel2){
        ADC0_SC1A = channel1;
        ADC1_SC1A = channel2;
        while (1) {
	  if ((ADC0_SC1A & ADC1_SC1A & ADC_SC1_COCO)) {
	    break;
	  }
        }
	value1 = ADC0_RA;
	value2 = ADC1_RA;
}

void loop() {

 // GPIOC_PTOR = 1<<5;

  startTime = micros();
  
  //__disable_irq();
  for(i=0;i<samples;i++) {
      
     highSpeed8bitAnalogReadMacro(ADC_Module::channel2sc1aADC0[11], ADC_Module::channel2sc1aADC1[10]);
     value3 = value1;
     value4 = value2;
     highSpeed8bitAnalogReadMacro(ADC_Module::channel2sc1aADC0[2], ADC_Module::channel2sc1aADC1[3]);
    
     
  }
  //__enable_irq();
  
  stopTime = micros();
  totalTime = stopTime-startTime;
  samplesPerSec = i*1000/totalTime;
  Serial.print("T: ");
  Serial.print(totalTime);
  Serial.print(" S/uSec: ");
  Serial.print(samplesPerSec);
  Serial.print(" V1: ");
  Serial.print(value1);
  Serial.print(" V2: ");
  Serial.print(value2);
  Serial.print(" V3: ");
  Serial.print(value3);
  Serial.print(" V4: ");
  Serial.print(value4);
  Serial.println();
  digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a second
  digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
  delay(100);  // wait for a second
 

}

Any help would be great! Thanks
 
You should probably substitute ADC_Module::channel2sc1aADC0 by ADC::channel2sc1aADC0. But I don't know why you want to use that example. Have you looked at the ADC library examples?
 
Thanks! that did it. I am only using his code because I am building something very similar to his build. I have not yet looked thru the examples, I am trying to get timing data to locate where a sound occurred but it is thru a solid so I need a pretty high sampling rate, I think the sound is going 2700m/s and the sensors are 5 feet apart in a square.
 
I can't even get the examples to compile in the arduino IDE.
Specifically, the VREF header file says some things are defined in kinetis.h, but the compiler must not be able to see that, because it says:
Code:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ADC/VREF.h:23:38: error: 'VREF_SC_MODE_LV_HIGHPOWERBUF' was not declared in this scope
Also, why does ringbuffer.h show:
Code:
// include new and delete
#include <Arduino.h>
?? Do I need to include kinetis.h somewhere? I've tried and it still doesn't work. I'm using a teensy 3.6.
 
I can't even get the examples to compile in the arduino IDE.
Specifically, the VREF header file says some things are defined in kinetis.h, but the compiler must not be able to see that, because it says:
Code:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ADC/VREF.h:23:38: error: 'VREF_SC_MODE_LV_HIGHPOWERBUF' was not declared in this scope
Also, why does ringbuffer.h show:
Code:
// include new and delete
#include <Arduino.h>
?? Do I need to include kinetis.h somewhere? I've tried and it still doesn't work. I'm using a teensy 3.6.

Note sure what Teensy or IDE version is in use? More 'verbose' output text might indicate the source of the issue.

Do you see a line like this - or an indication of multiple libraries?: Using library ADC in folder: I:\arduino-1.8.5\hardware\teensy\avr\libraries\ADC (legacy)

However With IDE 1.8.5 and TeensyDuino 1.40 (b3)- I opened : I:\arduino-1.8.5\hardware\teensy\avr\libraries\ADC\examples\ringBuffer and did a Verify build with no issues for T_3.2 or T_3.6.
 
Great you got it working - email posted showing it failed again until software update was done. I wonder what was out of sync?
 
VREF_SC_MODE_LV_HIGHPOWERBUF was added "recently" to kinetis.h (not sure when). So I guess he had a moderately old version of Teensyduino.
The comment on RingBuffer only says that I needed to include <Arduino.h> so I could use new and delete. It's not a command for the user!
 
VREF_SC_MODE_LV_HIGHPOWERBUF Problem

Hi,
I am working in Atom / Platformio 3.5.b03 on a Mac with a Teensy 3.6 project.

Today I started to install some libraries needed with Platformio's library manager, which should make it easier to have them all updated in the future.


Now I run into a problem with the Teensy_ADC library.

In the project library folder was a version mentioning (c) 2016 (probably downloaded Sept 2017) --> The code compiled fine, everything was working

The actual Teensy_ADC library installed by Platformio library manager is @ 25f2a270bb and seems [Up-to-date]
For using this library I had to take out the previous used (c) 2016 library from the library folder and included a
Code:
lib_deps = Teensy_ADC
in platformio.ini

But now compiling gives me an error:

Code:
In file included from .piolibdeps/Teensy_ADC_ID355/ADC_Module.cpp:36:0:
.piolibdeps/Teensy_ADC_ID355/VREF.h:23:38: error: 'VREF_SC_MODE_LV_HIGHPOWERBUF' was not declared in this scope
inline void start(uint8_t mode = VREF_SC_MODE_LV_HIGHPOWERBUF, uint8_t trim = 0x20) {
^

*** [.pioenvs/host/lib/Teensy_ADC_ID355/ADC_Module.o] Error 1

A closer look at the Packages shows that the framework-arduinoteensy is version @ 1.136.0 saying it is [Up-to-date]
But the ADC-library IN the package is quite old from January 2017, (c) 2016



My questions are:

is the framework-arduinoteensy out of date?

or should I just delete all those (old) libraries in the Framework?
or the whole framework-arduinoteensy?

or is it a Platformio problem and I have to ask there?

EDIT:
Further investigations show that the same compiling error rises, also when downloading the newest library from
https://github.com/pedvide/ADC.git
cancelling the lib_deps in platformio.ini and put the library into the lib-folder of the project.

Thank you for any help!
 
Last edited:
The right way to use Teensy is to install a supported version of the Arduino IDE (for example 1.8.5) and then download and install the latest version of Teensyduino on top of that.
You can then see all the libraries that are supported in the add library menu.
Any alternative packaging (including platformio) is likely to have better answers at those support forums.
 
Those errors indicate that the latest version on Teensyduino is not installed. I can't help you because I have no idea about that platform, sorry.
 
Thank yo for your replys!

I installed Arduino 1.8.5 and Teensyduino 1.4

Wanted to try the internal_reference Sketch of ADC library, but it did not work with the "right way to use Teensy" method.
After installing the library by hand it is compiling and working perfect.

Seems quite common, that someone has to install new versions of libraries by hand, especially for larger project developments (over longer period)

But you led me to the right direction:
I put the Teensyduino core files and copied them to the Platformio framework-arduinoteensy folder and now everything works
(The framework-arduinoteensy is a little bit out of date)

Just some compiler warnings about the new.h and the 'void operator delete'....

Put the solution here, hoping that it will help someone else one day.
 
Hello Pedvide, noticed you made some updates in the last month so I figure I would check out the new ADC Clock speeds. Here is what excel's IF formulas produce using the ADC_Module.h data. I have not highlighted the out of spec values yet. Are the values correct, did I miss anything?

ADC Library updated.JPG

Here is the stock Teensy ADCK values for comparison.

Teensy Stock ADCK.JPG

I will publish an updated Google Doc with these values and the stuff on this doc together once I confirm the values are correct.

Edit.. Fixed 2 rows on the excel that were rounded.
 
Last edited:
Hi everyone,
I'm looking for advice before starting to actually code the teensy 3.1 with the adc library. I have 8 piezos connected (for example snare is on A0 (ADC0) and hihat on A17 (ADC1)). The signal looks like this:
piezo.png

I am trying to detect the peak so that I can transform this information to velocity (midi). From what I see, all the information I need is within the first 5ms, after that it's already falling quickly. My question is if I wait for a signal that is above a threshold and then sampling the value for 5ms keeping only the highest one, what will happen if another hit happens in the exact same moment (in theory of course)? What is the best strategy here?

Thank you for any hints on this matter,
Have an excellent day!
 
It seems that the Teensy 3.6 CPU only provides 1 differential channel pair. This sucks.

The Teensy 3.5, however, seems to provide several differential channel pairs, especially it offers at least one for both ADC0 and ADC1, separately.
According to https://www.nxp.com/docs/en/reference-manual/K64P144M120SF5RM.pdf, page 245, the following pins can be used for differential measurements:
J1, J2
K1, K2
L1, L2
M1, M2 <-- this is also available on Teensy 3.6

Looking at the code, it seems that Teensy 3.5 and 3.6 are treated equally, meaning the library currently does not support analogSyncReadDifferential() on Teensy 3.5. :(
Is the ADC library still being updated? The last commit is more than 6 months old and there are several open issues..

Did we get an answer to this? I would also like to use the A12,A13 with Teensy 3.6.
 
I'm trying to use this ADC library in my sound projects. Should it be possible to run the Teensy sound library on ADC_0, whilst reading values from potentiometers etc on ADC_1? If the answer to this is yet, is it possible to set the reference voltage of the ADCs individually? The audio library seems to override the reference voltage of ADC_1. I've put this into some very simple example code below. It would be very useful to know if I'm wasting my time on this approach :) Thanks!

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h> 
#include <ADC.h>

ADC adc;
AudioInputAnalog audio_input; // remove this and the 3V3 reference on ADC_1 is maintained

// the setup routine runs once when you press reset:
void setup()
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  adc.setReference( ADC_REFERENCE::REF_1V2, ADC_0 );
  adc.setReference( ADC_REFERENCE::REF_3V3, ADC_1 );
}

void loop()
{
  adc.setReference( ADC_REFERENCE::REF_3V3, ADC_1 );
  int sensorValue = adc.analogRead( A16, ADC_1 );
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}
 
I've solved this issue now (copying this from another thread I started for the sake of anyone else who has this issue)

Think I've fixed it! The issue was this sequence of events.

1. ADC class is constructed, setting its voltage reference to 3.3V for both ADCs
2. Audio library initialises, setting voltage reference to 1.2V for both ADCs
3. My setup code runs, attempts to set ADC_1 to 3.3V, but this function early outs, because it thinks it's already set to that value (ADC_module.cpp line 238 https://github.com/pedvide/ADC/blob/...ADC_Module.cpp)

To avoid changing the interface to the ADC class (adding a flag to force_set or similar), I simply set the reference twice. Once to 1.2V, to reset the analog_reference_internal member, and then to 3.3V, see code below.

I think ideally, the audio library would be changed to update the ADC states, or the ADC class would provide an interface to force set the reference voltage. Anyway, I'm happy to have found this..

Code now looks like this

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h> 
#include <ADC.h>

ADC adc;
AudioInputAnalog audio_input;

// the setup routine runs once when you press reset:
void setup()
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  // Audio library has overriden this, so need to reset the reference voltages
  adc.setReference( ADC_REFERENCE::REF_1V2, ADC_1 ); // NOTE: ADC CODE CHECKS FOR SETTING SAME VALUE, SO SET IT TO SOMETHING ELSE FIRST
  adc.setReference( ADC_REFERENCE::REF_3V3, ADC_1 );
}

// the loop routine runs over and over again forever:
void loop()
{
  int sensorValue = adc.analogRead( A16, ADC_1 );
  sensorValue;
  // print out the value you read:
  Serial.println(sensorValue);
  delay(100);        // delay in between reads for stability
}
 
tried clean compile got this error
Code:
Using board 'teensy36' from platform in folder: /Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/avr
Using core 'teensy3' from platform in folder: /Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/avr
Detecting libraries used...
"/Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO=141 -DARDUINO=10805 -DF_CPU=180000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3" "/var/folders/x7/kkt0r44517sf3j8wrqpz0vvh0000gn/T/arduino_build_222200/sketch/sketch_mar31bt36.ino.cpp" -o "/dev/null"
"/Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO=141 -DARDUINO=10805 -DF_CPU=180000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/Users/shawnalfaro/Downloads/MAC/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3" "/var/folders/x7/kkt0r44517sf3j8wrqpz0vvh0000gn/T/arduino_build_222200/sketch/sketch_mar31bt36.ino.cpp" -o "/var/folders/x7/kkt0r44517sf3j8wrqpz0vvh0000gn/T/arduino_build_222200/preproc/ctags_target_for_gcc_minus_e.cpp"
/Users/shawnalfaro/Downloads/ADC-master/sketch_mar31bt36/sketch_mar31bt36.ino:36:20: fatal error: atomic.h: No such file or directory
compilation terminated.
Error compiling for board Teensy 3.6.

atomic.h is in the same folder,maybe im just tired
 
Back
Top