Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Does this continuous simultaneous ADC sampling look reasonable?

  1. #1
    Junior Member
    Join Date
    May 2014
    Posts
    8

    Does this continuous simultaneous ADC sampling look reasonable?

    Hi everybody,

    I am new to teensy and am trying to understand the ADC library. For my application I need to sample two analog channels that represent the currents through a stepper motor coils and track the position of the stepper. Below is a skeleton program that samples two channels continuously.

    1. Does the code look reasonable? Any red flags? Any suggestion? I think that ~10k samples/sec should be more than enough.

    2. I run built this with Arduino IDE for Teensy 3.2. Will same code work also on Teensy 4.0?


    Thanks
    Z.

    Code:
    // Skeleton program for reading two input analog channels.
    
    #include <stdio.h>
    #include <ADC.h>
    
    const int adcPin1 = A9;
    const int adcPin2 = A3;
    
    ADC *adc = new ADC();
    
    elapsedMicros time;
    
    void setup() {
      Serial.begin(9600);
      pinMode(LED_BUILTIN, OUTPUT);
    
      pinMode(adcPin1, INPUT);
      pinMode(adcPin2, INPUT);
    
      adc->setReference(ADC_REFERENCE::REF_3V3, ADC_0);
      adc->setReference(ADC_REFERENCE::REF_3V3, ADC_1);
    
      adc->setAveraging(4, ADC_0);
      adc->setAveraging(4, ADC_1);
    
      adc->setResolution(12, ADC_0);
      adc->setResolution(12, ADC_1);
    
      adc->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED, ADC_0);
      adc->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED, ADC_1);
    
      adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_0); 
      adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_1); 
    
      // We use adc0_isr to read also adc1.
      adc->enableInterrupts(ADC_0);
    
      // NOTE: this return a error status if pins are not supported.
      adc->startSynchronizedContinuous(adcPin1, adcPin2);
      delay(100);
    }
    
    // TODO: should these be volaitile?
    int isr_count = 0;
    ADC::Sync_result result;
    
    void loop() {
      // Take a snapshot of isr values and reset isr_count
      int _isr_count;
      ADC::Sync_result _result;
      __disable_irq();
      {
        _isr_count = isr_count;
        _result = result;
        isr_count = 0;
      }
      __enable_irq();
    
      // Print snapshot
      char buffer[60];
      sprintf(buffer, "%d %5d %5d", _isr_count, _result.result_adc0, _result.result_adc1);
      Serial.println(buffer);
    
      adc->printError();  // Print adc errors, if any
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      delay(1000);
    }
    
    void adc0_isr(void) {
      isr_count++;
      // NOTE: if sampling 16 bits, need t clear the high
      // 16 bits of result's fields to undo the 16 bit to 32 bit sign extension.
      result = adc->readSynchronizedContinuous();
      // TODO: insert stepper position tracking here.  
    }

  2. #2
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    652
    I assume the same code would work on T4 but remember there are a few differences. The T4 does not have an external Vref input (the internal 3.3V is the only option) and also it uses a 12-bit ADC (but maybe 10 bits in practice) while the T3.2 uses a 16 bit ADC (but maybe 12-13 in practice).

  3. #3
    Junior Member
    Join Date
    Dec 2018
    Location
    PNW
    Posts
    11
    Last time I downloaded teensyduino the ADC library had not been ported to the T4

  4. #4
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    652
    Oops, sorry you are correct, as far as I know the ADC lib has not yet been ported to T4.

  5. #5
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Is there another supported library to use the T4's ADCs under the Arduino IDE?

  6. #6
    Junior Member
    Join Date
    Dec 2018
    Location
    PNW
    Posts
    11
    You can use the analog read function. I have not tried to see how fast they are yet, It might be able to handle 10K samples without any problem. That isn't too high for a teensy. Actually reading your code now, I notice some things:

    I would get rid of the continuous reads, and the synchronized read isn't magic, it just reads one then the other. Try reading each individually with the T4 and see if it is fast enough
    Is your 10k sample/sec for each channel or both together? Why so many? Does the timing of the reads matter?
    Did this work on the T3.2? I don't see anything actually triggering the ISR
    You do not want a stepper tracker code in your ISR. Keep that short.
    What does your buffer do? You never write anything to it

    For this, if you actually want 10K samples per second and want the ease of the ADC library right now, stick with one of the T3's (with the PDB). They are amazing little devices and everything works great. With the ADC library you can get 100K's samples per second. If you want the 4, try analog read, read the manual (very dense read), or peruse the forum for bits of code people have pasted about the ADC's.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •