High speed sampling of all analog channels on Teensy 4.1

iluvteensy4.1

New member
Hello world,

I am working on a project to sample all 18 analog channels on the teensy 4.1 at at least 20-25khz, but preferably closer to 200khz, and dumping it to a txt file (csv works too just started with txt). Here is the code, I am using the ADC library. PLEASE HELP ME!! THANK YOU!!



Code:
#include <time.h>
#include <ADC.h>
//#include <ADC_util.h>
#include <SD.h>
#include <digitalWriteFast.h>
#include <iostream>
#include <string>


ADC *adc = new ADC(); // adc object
elapsedMicros t;

#define PINS 18
uint8_t adc_pins[] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17};
const int DAQtrigger = 9;
int value = 0;
int pin = 0;
int samples = 30000000;


String dataString{};                     //set up the data string

String timeString{};                      //set up the time string

void setup()
{

    pinMode(LED_BUILTIN, OUTPUT);          //initializing pins
    pinMode(DAQtrigger, INPUT);

    for (int i = 0; i < PINS; i++)        //loop to set all analog pins as inputs
    {
        pinMode(adc_pins[i], INPUT);
    }

    dataString.reserve(samples);         // set the size of the strings to the variable 'samples' (this will increase speed)
    timeString.reserve(samples);

    Serial.begin(115200);
    while (!Serial) {;        
  
    // Wait for serial port to connect. Needed for native USB port only
 
    }
    Serial.println("Initializing SD card...");

    // see if the card is present and can be initialized:
  
    while (!SD.begin(BUILTIN_SDCARD))          
    {
      Serial.println("Waiting for SD card...");
      digitalWrite(LED_BUILTIN, LOW);
      delay(500);
     }
    Serial.println("Card initialized.");
    digitalWrite(LED_BUILTIN, HIGH);

    ///// ADC0 ////
    adc->adc0->setAveraging(0);                                    // set number of averages
    adc->adc0->setResolution(6);                                   // set bits of resolution
    adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
    adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED);     // change the sampling speed

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
    adc->adc1->setAveraging(0);                                    // set number of averages
    adc->adc1->setResolution(6);                                   // set bits of resolution
    adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
    adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED);     // change the sampling speed
#endif


    delay(500);
    t = 0;
   
}

    
void loop()
{
 
  while (digitalReadFast(DAQtrigger) == 1)
  { 
    digitalWriteFast(LED_BUILTIN, LOW);                                     // signal that the teensy is recording (for debugging)
    
    for (int i = 0; i < PINS; i++)                                  //for loop to cycle through all the pins
    {
      value = adc->analogRead(adc_pins[i]);
      dataString += value;                                  //add the value of one pin to the string
      timeString += t;                                      //add time to string
      dataString += ",";                                           //add comma between values
      timeString += ",";
      }

      dataString+= "\n";
      timeString+= "\n";
  
  }
  while (digitalReadFast(DAQtrigger) == 0)
  {
    digitalWriteFast(LED_BUILTIN, HIGH);                                 //signal that data has stopped being recorded (for debugging)

    File dataFile = SD.open("datalog.txt", FILE_WRITE); 
    //Serial.println(dataString);                                     //print the datastring in serial port for debugging
    dataFile.println(dataString);                                  //save the string of data to the file on the SD card
    dataFile.close();                                  //close the file after data has been recorded
    //String dataString = "";                                             //reset the strings for the next sample
    
                                                   
    File timeFile = SD.open("timelog.txt", FILE_WRITE);
    timeFile.println(timeString);
    timeFile.close();
    //String timeString = "";

   for (int e = 0; e < 11; e++)
   {
   digitalWriteFast(LED_BUILTIN, LOW);
   delay(100);
   digitalWriteFast(LED_BUILTIN, HIGH);
   }
   
   

    }

}
 
Last edited by a moderator:
Hi, you may want to be more specific on what help you actually need. Is it not working? If so, what is not working? Is it too slow? Is it not compiling?
It also helps if you provide what version Arduino, what version Teensyduino and which OS you are using.

Paul
 
As PaulS mentioned it would help to know what help you are needing.

So far your code looks like it is semi just emulating using normal analog stuff..

Things I see, include I don't you should call pinMode(..., INPUT);
Maybe INPUT_DISABLE?

Lots of information up on the ADC thread: https://forum.pjrc.com/threads/25532-ADC-library-with-support-for-Teensy-4-3-x-and-LC
Although it looks like @pedvide has not updated the page to show the T4.1 with the 18 Analog pins.

There are two ADC units as you see, and not all pins are on both. In particular not all of of them are on the one you are using. AnalogRead in Arduino (outside of library knows this).
The ADC library does have tables for T4.1 So the pins map like:

Code:
#elif defined(ADC_TEENSY_4_1)
const uint8_t ADC::channel2sc1aADC0[] = {
    // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
    7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 1, 2, 31, 31, // 0-13, we treat them as A0-A13
    7, 8, 12, 11, 6, 5, 15, 0, 13, 14,               // 14-23 (A0-A9)
    1, 2, 31, 31,                                    // A10, A11, A12, A13
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31,          //
    31, 31, 9, 10                                    // A14, A15, A16, A17
};
#endif // defined
...
#elif defined(ADC_TEENSY_4_1)
const uint8_t ADC::channel2sc1aADC1[] = {
    // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
    7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 31, 31, 3, 4, // 0-13, we treat them as A0-A13
    7, 8, 12, 11, 6, 5, 15, 0, 13, 14,               // 14-23 (A0-A9)
    31, 31, 3, 4,                                    // A10, A11, A12, A13
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31,          //
    1, 2, 9, 10                                      // A14, A15, A16, A17
};
#endif
Tables by pin number... If the value for pin is 31, that ADC does not handle that pin...

You can speed up the reads, by using both ADCs at the same time. Either use the dual syncronous reads, or you can use the startRead for each one and then read in the values when ready...

Lots more options like DMA, ...
 
Back
Top