Forum Rule: Always post complete source code & details to reproduce any issue!
Page 20 of 20 FirstFirst ... 10 18 19 20
Results 476 to 500 of 500

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

  1. #476
    Senior Member
    Join Date
    Jan 2020
    Posts
    129
    Hello!

    I'm trying to do calculations while waiting for conversions to finish.
    Is it guaranteed that ADC0 will read sensor A0 and sensor A2? And
    ADC1 will always read A1 and A3 in this code? If not, is there a way
    I can change the code to do that?



    Code:
    void loop()
    {
    
    adc->startSynchronizedSingleRead(A0, A1);
    
    //Calculations on previous sensor pair
    from second time through the loop (A2, A3);
    
    while (adc->adc0->isConverting() || adc->adc1->isConverting());
    g_sensorValue[0] = 1023 - (adc->adc0->readSingle());
    g_sensorValue[1] = 1023 - (adc->adc1->readSingle());
    adc->startSynchronizedSingleRead(A2, A3);
    
    //Calculations on previous sensor pair (A0, A1);
    
    while (adc->adc0->isConverting() || adc->adc1->isConverting());
    g_sensorValue[2] = 1023 - (adc->adc0->readSingle());
    g_sensorValue[3] = 1023 - (adc->adc1->readSingle());
    
    }

  2. #477
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,675
    Looking at the code, I think it is reasonably safe to assume that:
    Code:
    bool ADC::startSynchronizedSingleRead(uint8_t pin0, uint8_t pin1)
    {
        // check pins
        if (!adc0->checkPin(pin0))
        {
            adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
            return false;
        }
        if (!adc1->checkPin(pin1))
        {
            adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
            return false;
        }
    
        // check if we are interrupting a measurement, store setting if so.
        adc0->adcWasInUse = adc0->isConverting(); // is the ADC running now?
        if (adc0->adcWasInUse)
        { // this means we're interrupting a conversion
            // save the current conversion config, the adc isr will restore the adc
            __disable_irq();
            //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
            adc0->saveConfig(&adc0->adc_config);
            __enable_irq();
        }
        adc1->adcWasInUse = adc1->isConverting(); // is the ADC running now?
        if (adc1->adcWasInUse)
        { // this means we're interrupting a conversion
            // save the current conversion config, the adc isr will restore the adc
            __disable_irq();
            //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
            adc1->saveConfig(&adc1->adc_config);
            __enable_irq();
        }
    
        // no continuous mode
        adc0->singleMode();
        adc1->singleMode();
    
        // start both measurements
        adc0->startReadFast(pin0);
        adc1->startReadFast(pin1);
    
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        return true;
    }
    But what I have not looked at is if those pins are Valid for those ADCs on every Teensy... But you should be able to verify that for whichever teensy you are using by either looking at code, or Reference Manual or easier yet I believe he has a summary of which pins are valid for which ADC...

  3. #478
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    646
    > trying to do calculations while waiting for conversions

    Yes, it makes sense to do calculations on A2,A3 values after starting a read on A0,A1. And vice versa.

    > ADC0 will read sensor A0 ...

    Yes, ADC0 is always assigned to the first pin in the parameter list.

  4. #479
    Senior Member
    Join Date
    Jan 2020
    Posts
    129
    Quote Originally Posted by KurtE View Post
    Looking at the code, I think it is reasonably safe to assume that.

    But what I have not looked at is if those pins are Valid for those ADCs on every Teensy... But you should be able to verify that for whichever teensy you are using by either looking at code, or Reference Manual or easier yet I believe he has a summary of which pins are valid for which ADC...
    Thanks, the pins are valid on the teensy 4 which Iím using and he did specify that.

    Iím getting some strange values ocassionally and itís because of my code but wanted to make sure it wasnít something else before I spend hours looking for a solution.

  5. #480
    Senior Member
    Join Date
    Jan 2020
    Posts
    129
    Quote Originally Posted by jonr View Post
    > trying to do calculations while waiting for conversions

    Yes, it makes sense to do calculations on A2,A3 values after starting a read on A0,A1. And vice versa.

    > ADC0 will read sensor A0 ...

    Yes, ADC0 is always assigned to the first pin in the parameter list.
    Thanks 🙏 Just needed to be sure

  6. #481
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    106
    Very nice work

    Can analogSyncRead() be called from an ISR? For example, can it be used in a function that was launched by the timer ?

    Thank you

  7. #482
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,675
    My guess is it probably can. I have not used the syncRead before, but I have done analogReads on an IntervalTimer...

    For example with my never finish Well monitoring code, that reads in 4 analog values for 4 different current sensors trying to do a quick and dirty RMS to figure out if a pump is running or not.
    My later version I would actually do this with DMA/Timer reads into buffers for two of them, and when this completes I would start it up again on the other two while processing the first two.

    I would do this on an IntervalTimer where I would verify the previous analog Reads completed, and then start up the next set and then do a quick and dirty calculation of RMS. My DMA timed reads would maybe give me 50 sample per the 60 hz sine wave and maybe enough for a couple of complete cycles like 150 samples...

  8. #483
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    106
    Sorry, I meant to post that on the thread for the adc library

  9. #484
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    106
    Hi, nice work.

    1) What setup is needed before calling the fast read function?

    2) Can analogSyncRead() be called from an ISR?

    I notice it appears to disable and enable interrupts. Is there any provision to save and restore the previous interrupt enable state?.

  10. #485
    Hallo Teensy friends

    I connected 4 potentiometers to the analog inputs of Teensy 4.1. Each potentiometer has a pin on 3.3V and GND. The ADC result is very noisy and unstable. I've already tried everything, for example RC filters at the input, but without improvement. I changed averaging and resolution without much improvement. What else can I try?

    My last idea is an external ADC chip e.g. MCP 3208 without analog inputs on the Teensy But I would like to use the analog inputs on the Teensy


    Code:
    //init analog Inputs
    	pinMode(14, INPUT_DISABLE);
    	pinMode(16, INPUT_DISABLE);
    	pinMode(17, INPUT_DISABLE);
    	pinMode(22, INPUT_DISABLE);
    	analogReadResolution(12);
    	analogReadAveraging(16);
    
    
    // adc polling every 25ms
    void read_pots (void)
    {
      pot_1 = (analogRead(A0) >> 5);
      pot_2 = (analogRead(A2) >> 5);
      pot_3 = (analogRead(A3) >> 5);
      pot_4 = (analogRead(A8) >> 5);
      
      if(pot_1 != pot_1_old){
      pot_1_old = pot_1;
      pot_1_change = true;
      }
      if(pot_2 != pot_2_old){
      pot_2_old = pot_2;
      pot_2_change = true;
      }
      if(pot_3 != pot_3_old){
      pot_3_old = pot_3;
      pot_3_change = true;
      }
      if(pot_4 != pot_4_old){
      pot_4_old = pot_4;
      pot_4_change = true;
      }
    }
    My last idea is an external ADC chip e.g. MCP 3208 without analog inputs on the Teensy? But I would like to do without it.

  11. #486
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    646
    Two things:

    1) take a few thousand samples and use an average or trimmed mean

    2) do a comparison more like "if ((new_ad + 32 < old_ad) || (new_ad > old_ad + 32)) ..."

    Code:
    // take mean of samples on each side of the median - adjustable,  no dither
    
    double trimmed_mean(const uint16_t array[], const unsigned count, const unsigned n)
    {
      qsort(array, count, sizeof(array[0]), compare_u16);
    
      unsigned sum = 0;
      unsigned n2 = 0;
    
    #if 0
      // classic method is to trim n of the most extreme samples from each end - try n = 20% of count
      for (unsigned i = n; i < (count - n); ++i) {
        sum += array[i];
        ++n2;
      }
    #else
      // weight each side method - try n = 1 for a tight histogram
      const int median = array[count / 2];
    
      for (unsigned i = 0; i < count; ++i) {
        if (((int)array[i] >= median - (int)n) && ((int)array[i] <= median + (int)n)) {
          sum += array[i];
          ++n2;
        }
      } // for
    #endif
    
      //Serial.printf("med %d,n2 %d  %g\n", median, n2,(double)sum / n2);
    
      return (double)sum / n2;
    }

  12. #487
    Thanks for your tip

    I think the right way would be to find the cause of the spikes. With 12-bit resolution, a little noise is normal. But at 7Bit it is not normal (see my test results).

    12Bit resolution


    10Bit resultion


    8Bit resultion


    All tests with Everanging 16

  13. #488
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    646
    Say that analogRead() returns 127 and then 128. What do you expect your code to do?

  14. #489
    I want to set envelope parameter from 0-127 in my Synth. These must be stable.

  15. #490
    My Prototyp

  16. #491
    read pots
    Code:
    //-----------------------------------------------------
    // read Pots (ADC resolution 12Bit )
    //-----------------------------------------------------
    void read_pots (void)
    {
      pot_1 = (analogRead(A0) >> 5);
      pot_2 = (analogRead(A2) >> 5);
      pot_3 = (analogRead(A3) >> 5);
      pot_4 = (analogRead(A8) >> 5);
      
      if(pot_1 != pot_1_old){
      pot_1_old = pot_1;
      pot_1_change = true;
      pot_change = true;
      }
      if(pot_2 != pot_2_old){
      pot_2_old = pot_2;
      pot_2_change = true;
      pot_change = true;
      }
      if(pot_3 != pot_3_old){
      pot_3_old = pot_3;
      pot_3_change = true;
      pot_change = true;
      
      }
      if(pot_4 != pot_4_old){
      pot_4_old = pot_4;
      pot_4_change = true;
      pot_change = true;
      }
    }

  17. #492
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    646
    OK, now step through your code in the case where analogRead() returns 127 and then 128. What values do you get for pot_1 and what happens?

  18. #493
    Ok I understand this. But..the max return value cannot be greater than 127 !?

  19. #494
    Now I have improved the ADC query.

    Code:
    //-----------------------------------------------------
    // read Pots
    //-----------------------------------------------------
    void read_pots (void)
    {
      pot_1 = (analogRead(A0) >> 5);
      if (pot_1 >= 127){
    	  pot_1 = 127;
      }
      pot_2 = (analogRead(A2) >> 5);
      if (pot_2 >= 127){
    	  pot_2 = 127;
      }
      pot_3 = (analogRead(A3) >> 5);
      if (pot_3 >= 127){
    	  pot_3 = 127;
      }
      pot_4 = (analogRead(A8) >> 5);
      if (pot_4 >= 127){
    	  pot_4 = 127;
      }
      
      if(pot_1 != pot_1_old){
      pot_1_old = pot_1;
      pot_1_change = true;
      pot_change = true;
      }
      if(pot_2 != pot_2_old){
      pot_2_old = pot_2;
      pot_2_change = true;
      pot_change = true;
      }
      if(pot_3 != pot_3_old){
      pot_3_old = pot_3;
      pot_3_change = true;
      pot_change = true;
      
      }
      if(pot_4 != pot_4_old){
      pot_4_old = pot_4;
      pot_4_change = true;
      pot_change = true;
      }
    }

  20. #495
    But.. the adc noise is not better (:. Now i have installed 100nF caps on the pots.
    It's not an improvement. Now I want to try to reduce the sample rate.

    Can I do that in Teensy 4.1 board ?

  21. #496
    ADC noise and potentiometer query
    Video: https://youtu.be/Cuzt2-V0pK0

  22. #497
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,155
    Did you try ResponsiveAnalogRead? (https://github.com/dxinteractive/ResponsiveAnalogRead) This library is fantastic in getting stable reads from pots and similar slow devices.

  23. #498
    I want to try it and I will report. Tanks ..

  24. #499
    Hi luni. Thank you for your great tip with ResponsiveAnalogRead. The ADC noise is very low and my potentiometer settings are very stable.

Posting Permissions

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