Forum Rule: Always post complete source code & details to reproduce any issue!
Page 12 of 17 FirstFirst ... 2 10 11 12 13 14 ... LastLast
Results 276 to 300 of 420

Thread: ADC library update, now with support for Teensy 3.1

  1. #276
    Junior Member
    Join Date
    May 2016
    Posts
    7
    Thanks for looking into it. If I invert polarity to ADC_1; battery negative to A12/ADC1_DP0 and battery positive to A13/ADC1_DM0, the counts are positive.

  2. #277
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    gofaster,

    I've looked into it and I've fixed the second problem you had. Indeed at 16 bits, synch analog differential returned half the correct value. This is now fixed at the github repo (see first page).

    I can't replicate the first problem, however. I've checked at different resolutions and it works well. I don't have a Teensy 3.2, only 3.1's, but I don't think that's the problem. Are you sure your wiring is fine? Remember that the result is V(A12)-V(A13).
    Please double and triple check, if it's still wrong I'd look for somebody with a Teensy 3.2 to check, in case is a hardware problem.

  3. #278
    Junior Member
    Join Date
    May 2016
    Posts
    7
    Hi Pedvide -

    First, please accept my apologies for the false alarm. I triple checked this time and pulled the Teensy out of the fixture to verify. Indeed I had done a mental flip when I soldered the jumpers to the A12/A13 pads.
    The patch does fix the SynchRead values. Thanks again for taking the time to look into this and for developing this library!

  4. #279
    Junior Member
    Join Date
    Sep 2014
    Posts
    3
    Hi, folks. I have some questions about the Teensy 3.1/3.2 ADC capabilities. In particular, I need ~1ns resolution on the input signal, but not a high sample rate (400 to 800 KHz is fine, which the Teensy can do). I can add an external sample/hold to achieve the 1ns resolution, but I would have to synchronize it to the ADC somehow. Is there any way to know when a new sample is starting? I just need an edge to trigger the external S/H. Thanks.

  5. #280
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,576
    Hard to imagine how you'll get 1 ns timing resolution from a microcontroller that runs well below 1 GHz.

  6. #281
    Junior Member
    Join Date
    Sep 2014
    Posts
    3
    If the A/D clock is stable enough, just drive a cheap analog switch that has time-to-off of ~1ns, into a 10pF hold cap, and from there an opamp can drive the Teensy. Getting the RC time constant into the hold cap below 1ns is not hard. A GPIO could be used to drive the analog switch enable, though I would prefer to use continuous sampling mode.

  7. #282
    Quote Originally Posted by WaywardGeek View Post
    If the A/D clock is stable enough, just drive a cheap analog switch that has time-to-off of ~1ns, into a 10pF hold cap, and from there an opamp can drive the Teensy. Getting the RC time constant into the hold cap below 1ns is not hard. A GPIO could be used to drive the analog switch enable, though I would prefer to use continuous sampling mode.
    Granted that you get some sort of sample and hold that take less than 1ns and somehow you can read the sample, process and do something with it in only 1 clock step.
    Problem is that if I'm not wrong one clock step in teensy at 96Mhz takes 10.4166667 nanoseconds.

  8. #283
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    So let me see if I understand what you want:
    You want your measurements to start at a given time with a precision +-1ns, and repeat them at a +-500 kHz rate?
    You have some external circuitry to signal the Teensy when to start the measurement, I assume.
    On the other hand you say that you'd like to use the continuous mode. So the problem is to start the measurements at the right time.

    The main thing to check is how long does the sampling phase take (the input voltage is "stored" in a capacitor before being converted).
    A fast measurement takes about 1 us, if the sampling takes 10% of that, it's already 100 ns, so the value you are converting is some sort of average sample of 100 ns.

    The programming datasheet has information about how long this phase takes, see page 680 ff. The fastest sampling possible is 6 ADCK for single measurements (or 1st in continuous) and 4 ADCK for continuous. For the standard speed of 96 MHz, F_BUS=48 MHz, and at the fastest settings ADCK=24 MHz, the sampling takes either 250 ns or 167 ns.
    The conversion step takes 20 ADCK + 5 F_BUS = 0.94 us, the total time is therefore about 1.11 us.

    I'd say it's not doable.

  9. #284

    Using ADC library with platformio

    I'm trying to move a sketch over to platformio and use CLion as the IDE, but when I build the project the ADC.h header wasn't found.

    So, I downloaded from github and moved it into the lib/ subdirectory, but now it complains about the F_BUS macro not being defined:

    Code:
    --------------------------------------------------------------------------------
    arm-none-eabi-g++ -o .pioenvs/teensy31/src/main.o -c -std=gnu++98 -fno-rtti -fdata-sections -ffunction-sections -Wno-unused-parameter -fno-exceptions -Wextra -fno-delete-null-pointer-checks -fmessage-length=0 -mthumb -Wno-missing-field-initializers -c -fno-builtin -O2 -fomit-frame-pointer -Wall -MMD -mcpu=cortex-m4 -DMBED_BUILD_TIMESTAMP=1464364165.29 -DTARGET_TEENSY3_1 -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_RTOS_M4_M7 -DTARGET_K20DX256 -DTARGET_CORTEX_M -DTARGET_LIKE_MBED -DTARGET_LIKE_CORTEX_M4 -DTARGET_M4 -D__MBED__=1 -DTARGET_Freescale -D__CORTEX_M4 -DARM_MATH_CM4 -DTARGET_K20XX -D__MK20DX256__ -DPLATFORMIO=021100 -I.pioenvs/teensy31/FrameworkArduino -I.pioenvs/teensy31/FrameworkMbedInc248832578 -I.pioenvs/teensy31/FrameworkMbedInc-213564679 -I.pioenvs/teensy31/FrameworkMbedInc-250686161 -I.pioenvs/teensy31/FrameworkMbedInc-1845648957 -I.pioenvs/teensy31/FrameworkMbedInc-666725808 -I.pioenvs/teensy31/FrameworkMbedInc357213333 -I.pioenvs/teensy31/FrameworkMbedInc1049033388 -I.pioenvs/teensy31/FrameworkMbedInc-194069199 -I.pioenvs/teensy31/Led -I.pioenvs/teensy31/SerialPanel -I.pioenvs/teensy31/ADC -Isrc src/main.cpp
    In file included from .pioenvs/teensy31/ADC/ADC.h:44:0,
    from src/main.cpp:5:
    .pioenvs/teensy31/ADC/ADC_Module.h:302:2: error: #error "F_BUS must be 108, 60, 56, 54, 48, 40, 36, 24, 4 or 2 MHz"
    #error "F_BUS must be 108, 60, 56, 54, 48, 40, 36, 24, 4 or 2 MHz"
    Is anyone familiar with how to install this ADC library into a platformio based project?

    Or please point me in the right direction if I should be asking elsewhere!

  10. #285
    Please post your issue to https://community.platformio.org with demo sketch.

    Thanks.

    Regards,

    Ivan @ PlatformIO

  11. #286
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    Well in any case you should start with an easier sketch like Blink.
    F_CPU is passed to the compiler as a flag (see how arduino does it), F_BUS is then derived from F_CPU (usually it's half)

  12. #287
    It works without any problems for me.

    ```
    $ mkdir /tmp/teensy
    $ platformio init -d /tmp/teensy -b teensy31
    $ git clone https://github.com/pedvide/ADC.git /tmp/teensy/lib/ADC
    $ cp /tmp/teensy/lib/ADC/examples/readPin/readPin.ino /tmp/teensy/src/readAllPins.ino
    $ platformio run -d /tmp/teensy
    ```

    The result: http://pastebin.com/xNY8C33D

    P.S: I've jsut created an issue and we will add this library to our registry.

  13. #288
    Quote Originally Posted by ikravets View Post
    It works without any problems for me.

    ```
    $ mkdir /tmp/teensy
    $ platformio init -d /tmp/teensy -b teensy31
    $ git clone https://github.com/pedvide/ADC.git /tmp/teensy/lib/ADC
    $ cp /tmp/teensy/lib/ADC/examples/readPin/readPin.ino /tmp/teensy/src/readAllPins.ino
    $ platformio run -d /tmp/teensy
    ```

    The result: http://pastebin.com/xNY8C33D

    P.S: I've jsut created an issue and we will add this library to our registry.
    Thanks Ivan.

    I've added a question on your PlatformIO community, because I'd like to make this library global, and keep it up-to-date outside of my specific project. -- https://community.platformio.org/t/i...obal-scope/478

  14. #289
    Junior Member
    Join Date
    Jul 2016
    Posts
    3
    Hi, Thanks a lot for your job! I have just one question:
    I have upload on teensy3.2 your exemple called "ringBufferDMA.ino" (https://github.com/pedvide/ADC/blob/...gBufferDMA.ino). I don't understand why once the Buffer is full, only the first half become full and the second stay the same. Here is an exemple of what i get on my consol withe a buffer_size =2. I convert the value, read and print.
    Buffer: Address, Value
    1FFF8200, 306
    1FFF8202, 373
    Start DMA

    Conversion:
    ADC0_ISR
    read(): 657
    Buffer: Address, Value
    1FFF8200, 657
    1FFF8202, 373

    Conversion:
    ADC0_ISR
    read(): 373
    Buffer: Address, Value
    1FFF8200, 582
    1FFF8202, 373

    Conversion:
    ADC0_ISR
    read(): 638
    Buffer: Address, Value
    1FFF8200, 638
    1FFF8202, 373

    Conversion:
    ADC0_ISR
    read(): 373
    Buffer: Address, Value
    1FFF8200, 774
    1FFF8202, 373

    Why the second half (here 373) is never changed?

    thank you for your help

    Maxime D

  15. #290
    Junior Member
    Join Date
    Jul 2016
    Posts
    3
    I have another noob question,
    What is the difference between a ringBuffer object and a DMAringBuffer object?

    Thanks in advance

  16. #291
    Quote Originally Posted by MaximeD View Post
    ... I don't understand why once the Buffer is full, only the first half become full and the second stay the same.
    I noticed that the GitHub repo has an issue ticket logged for that -- https://github.com/pedvide/ADC/issues/12

  17. #292
    Junior Member
    Join Date
    Jul 2016
    Posts
    3
    Quote Originally Posted by ohhorob View Post
    I noticed that the GitHub repo has an issue ticket logged for that --
    Thank you Ohhorob, I discover GitHub not long ago, I didn't notice the Issue ticket, now I know

  18. #293
    Junior Member
    Join Date
    Aug 2016
    Posts
    3
    Hi All,

    Firstly, thank you very much for this library and hard work Pedvide, it truelly is excellent. Long time lurker on this thread as I'm trying to improve the sample rate I'm seeing on my teensy. Ideally I'm trying to get to 10KHz(ish) but currently I run into issues with data rate above 4KHz.

    I've modified some sample code and added in interrupt based sampling. I've also used FlexiTimer2 (also MsTimer2 to see if it made a difference) to run a blink interupt to give the ADC something to sample.

    The issue I run into is that at higher interupt rates I stop getting reliable readings (shown in the included picture).
    Is this an issue with using the ADC in an interupt routine at a high rate, or is it that I'm running up against the Teensy sampling limit?

    I've tried reading the rest of this thread but I can't seem to find anyone with a similar issue.

    Running up to date Teensyduino and teensy 3.2
    Click image for larger version. 

Name:	Capture.jpg 
Views:	72 
Size:	41.2 KB 
ID:	7800

    /* Example for synchonized measurements using both ADC present in Teensy 3.1
    You can change the number of averages, bits of resolution and also the comparison value or range.
    */

    #include<TimerOne.h>
    #include<ADC.h>
    #include<MsTimer2.h>
    #include<FlexiTimer2.h>
    const int led = LED_BUILTIN;
    const int readPin = A1;
    const int readPin2 = A3;
    int count;
    bool x = HIGH;
    ADC *adc = new ADC(); // adc object
    int value = 0;
    int value2 = 0;
    unsigned long blinkCopy; // holds a copy of the blinkCount
    volatile unsigned long blinkCount = 0; // use volatile for shared variables
    int ledState = LOW;
    ADC::Sync_result result;
    const int led_pin = 13;
    void get_ADC();
    void flash();

    void setup()
    {
    pinMode(led_pin, OUTPUT);
    pinMode(readPin, INPUT);
    pinMode(readPin2, INPUT);
    Timer1.initialize(500); //250microseconds = 4Khz
    Timer1.attachInterrupt(get_ADC);
    Serial.begin(9600);

    adc->setAveraging(1); // set number of averages
    adc->setResolution(8); // set bits of resolution
    adc->setConversionSpeed(ADC_VERY_HIGH_SPEED); // change the conversion speed
    adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED); // change the sampling speed
    adc->setAveraging(1, ADC_1); // set number of averages
    adc->setResolution(8, ADC_1); // set bits of resolution
    adc->setConversionSpeed(ADC_VERY_HIGH_SPEED, ADC_1); // change the conversion speed
    adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED, ADC_1); // change the sampling speed
    adc->startSynchronizedContinuous(readPin, readPin2);

    FlexiTimer2::set(500, 1.0/1000, flash); // call every 500 1ms "ticks"
    // FlexiTimer2::set(500, flash); // MsTimer2 style is also supported
    FlexiTimer2::start();
    }

    void loop()
    {

    }

    void get_ADC(void)
    {
    result = adc->readSynchronizedContinuous();
    result.result_adc0 = (uint16_t)result.result_adc0;
    Serial.println(result.result_adc0 * 3.3 / adc->getMaxValue(ADC_0), DEC);
    }

    void flash()
    {
    static boolean output = HIGH;

    digitalWrite(led_pin, output);
    output = !output;
    }
    Appreciate any help given.

  19. #294
    Senior Member
    Join Date
    Mar 2013
    Posts
    651
    Quote Originally Posted by golden2620 View Post
    Hi All,

    Firstly, thank you very much for this library and hard work Pedvide, it truelly is excellent. Long time lurker on this thread as I'm trying to improve the sample rate I'm seeing on my teensy. Ideally I'm trying to get to 10KHz(ish) but currently I run into issues with data rate above 4KHz.

    I've modified some sample code and added in interrupt based sampling. I've also used FlexiTimer2 (also MsTimer2 to see if it made a difference) to run a blink interupt to give the ADC something to sample.

    The issue I run into is that at higher interupt rates I stop getting reliable readings (shown in the included picture).
    Is this an issue with using the ADC in an interupt routine at a high rate, or is it that I'm running up against the Teensy sampling limit?

    I've tried reading the rest of this thread but I can't seem to find anyone with a similar issue.

    Running up to date Teensyduino and teensy 3.2
    Click image for larger version. 

Name:	Capture.jpg 
Views:	72 
Size:	41.2 KB 
ID:	7800



    Appreciate any help given.
    Whats the source you are reading?

  20. #295
    Junior Member
    Join Date
    Aug 2016
    Posts
    3
    I'm sampling pin 14 + 15 (A0 & A1) as I need to read simultaneously, but I'm only using 15 (A1) at the moment. There's just a wire between that and Pin 13, the LED, so that I'm reading something. Didn't want to generate a signwave/pwm in case the additional processing requirements impinged on the sample rate.

  21. #296
    Senior Member
    Join Date
    Mar 2013
    Posts
    651
    Quote Originally Posted by golden2620 View Post
    I'm sampling pin 14 + 15 (A0 & A1) as I need to read simultaneously, but I'm only using 15 (A1) at the moment. There's just a wire between that and Pin 13, the LED, so that I'm reading something. Didn't want to generate a signwave/pwm in case the additional processing requirements impinged on the sample rate.
    Hmm, if your using the serial then try upping the baud rate..
    You can easily get sampling speeds as low as 5uS or less. So you need to look at things other then the ADC
    Last edited by Donziboy2; 08-02-2016 at 11:11 AM.

  22. #297
    Junior Member
    Join Date
    Aug 2016
    Posts
    3
    Quote Originally Posted by Donziboy2 View Post
    Hmm, if your using the serial then try upping the baud rate..
    You can easily get sampling speeds as low as 5uS or less. So you need to look at things other then the ADC
    The Baud rate has had no affect on the data quality so far, I have increased it to its maximum, although IIRC somewhere Paul was saying that the Teensy does what it wants with the baud rate? Might be making that up.

    While i've seen plenty of claims that the Teensy will do 5uS sampling, I've not come across anyone that's actually doing it successfully, if you know of anyone/any threads please point me in the right direction.

    *Edit*
    Is there maybe a more efficient way of storing data than just flinging values onto the serial port?
    Last edited by golden2620; 08-02-2016 at 02:45 PM. Reason: Additional question

  23. #298
    Senior Member
    Join Date
    Apr 2016
    Location
    St. Petersburg, FL
    Posts
    149
    I'm using the dual synced ADC-12bit and cannot get it to go any faster than 16usec. A timer is set up to run at 16usec and generates an interrupt that triggers the ADC. If I run the timer any faster then the period of capture for 640 samples gets longer because it starts to miss an event.

  24. #299
    Senior Member
    Join Date
    Mar 2013
    Posts
    651
    Quote Originally Posted by golden2620 View Post
    The Baud rate has had no affect on the data quality so far, I have increased it to its maximum, although IIRC somewhere Paul was saying that the Teensy does what it wants with the baud rate? Might be making that up.

    While i've seen plenty of claims that the Teensy will do 5uS sampling, I've not come across anyone that's actually doing it successfully, if you know of anyone/any threads please point me in the right direction.

    *Edit*
    Is there maybe a more efficient way of storing data than just flinging values onto the serial port?
    Im reading 8 analog pins(12bit) for an E-gocart project, IIRC i'm reading 2 pins synchronously in around 8.6uS.


    Here is a test code I used to get my numbers(looks to be the same as Post #105 of the thread), you can change the 3.27V I use in the formulas to match what you 3v3 rail is on your teensy.
    Code:
    #include <ADC.h>
    
    const int aThrottle = A10;    //Throttle
    const int aCurrent = A18;  //Current
    const int aBusV = A11;   //BusV
    const int aBattV = A19;  //BattV
    const int aMotorT = A12;   //MotorTemp
    const int aHST = A20;  //HS-Temp
    
    
    ADC *adc = new ADC(); // adc object
    
    
    void setup() {
    
        pinMode(LED_BUILTIN, OUTPUT);
        pinMode(aThrottle, INPUT);
        pinMode(aCurrent, INPUT);
        pinMode(aBusV, INPUT);
        pinMode(aBattV, INPUT);
        pinMode(aMotorT, INPUT);
        pinMode(aHST, INPUT);
    
    
        Serial.begin(9600);
    
        ///// ADC0 ////
        //adc->setReference(ADC_REF_INTERNAL, ADC_0); change all 3.3 to 1.2 if you change the reference
    
        adc->setAveraging(1); // set number of averages
        adc->setResolution(12); // set bits of resolution
    
        // it can be ADC_VERY_LOW_SPEED, ADC_LOW_SPEED, ADC_MED_SPEED, ADC_HIGH_SPEED_16BITS, ADC_HIGH_SPEED or ADC_VERY_HIGH_SPEED
        // see the documentation for more information
        adc->setConversionSpeed(ADC_HIGH_SPEED); // change the conversion speed
        // it can be ADC_VERY_LOW_SPEED, ADC_LOW_SPEED, ADC_MED_SPEED, ADC_HIGH_SPEED or ADC_VERY_HIGH_SPEED
        adc->setSamplingSpeed(ADC_HIGH_SPEED); // change the sampling speed
    
        ////// ADC1 /////
        adc->setAveraging(1, ADC_1); // set number of averages
        adc->setResolution(12, ADC_1); // set bits of resolution
        adc->setConversionSpeed(ADC_HIGH_SPEED, ADC_1); // change the conversion speed
        adc->setSamplingSpeed(ADC_HIGH_SPEED, ADC_1); // change the sampling speed
    
    
    
        delay(500);
        Serial.println("end setup");
    }
    
    int value[16] = {0};
    int value2[16] = {0};
    int value3[16] = {0};
    int value4[16] = {0};
    int value5[16] = {0};
    int value6[16] = {0};
    int testtime;
    
    ADC::Sync_result result;
    
    void loop() {
      
    int i;
    
    elapsedMicros sinceStart; // start the clock
    
    for (i = 0; i < 16; i++) {
        result = adc->analogSynchronizedRead(aThrottle, aCurrent);
        value[i] = result.result_adc0;
        value2[i] = result.result_adc1;
        result = adc->analogSynchronizedRead(aBusV, aBattV);
        value3[i] = result.result_adc0;
        value4[i] = result.result_adc1;
        result = adc->analogSynchronizedRead(aMotorT, aHST);
        value5[i] = result.result_adc0;
        value6[i] = result.result_adc1;
    
    }
    
    testtime = sinceStart;   //how long it took to read all 6 pins 16 times.
    Serial.print("Full read time was ");
    Serial.print(testtime);
    Serial.println(" us");
    
    //First ADC array                        
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aThrottle);
        Serial.print(", value ADC0: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value[i]*3.27/adc->getMaxValue(ADC_0), DEC);   //using 3.27 as the true voltage value
            Serial.print(" ");  
    }
    
    //Second ADC array
        Serial.println(" ");
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aCurrent);
        Serial.print(", value ADC1: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value2[i]*3.27/adc->getMaxValue(ADC_1), DEC);  
            Serial.print(" ");
    }
    
    //Third ADC array
        Serial.println(" ");
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aBusV);
        Serial.print(", value ADC0: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value3[i]*3.27/adc->getMaxValue(ADC_0), DEC);
            Serial.print(" ");  
    }
    
    //Forth ADC array
        Serial.println(" ");
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aBattV);
        Serial.print(", value ADC1: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value4[i]*3.27/adc->getMaxValue(ADC_1), DEC);
          Serial.print(" ");  
    }
    
    //Fifth ADC array
        Serial.println(" ");
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aMotorT);
        Serial.print(", value ADC0: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value5[i]*3.27/adc->getMaxValue(ADC_0), DEC);
          Serial.print(" ");  
    }
    
    //Sixth ADC array
        Serial.println(" ");
        Serial.print("Pin: ");   //Copy and paste hell from here on out...
        Serial.print(aHST);
        Serial.print(", value ADC1: ");
    
    for (i = 0; i < 16; i++) {
        Serial.print(value6[i]*3.27/adc->getMaxValue(ADC_1), DEC);
          Serial.print(" ");  
    }
    
    Serial.println(" ");
      delay(1000);
    }

  25. #300
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    MaximeD,

    I'll rewrite RingBuffer and DMARingBuffer soon. They never really worked well.
    The new design will be:
    RingBuffer: Purely software circular buffer, baed on interrupts
    DMARingBuffer: Hardware based Ping-pong buffer

Posting Permissions

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