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

Thread: FreqMeasure frequencies off by 2X

  1. #1

    FreqMeasure frequencies off by 2X

    I am running the FreqMeasureMulti example "Serial_Output" straight out of the box on a Teensy LC, and getting frequency measurements that are exactly half of what they should be (as measured on my scope). Now I know how to multiply by 2 as much as the next guy, but I thought this might point to a more fundamental problem.

    The Arduino IDE is configured as Board: "Teensy LC" and CPU Speed: "48 MHz".

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,764
    Is the scope measuring single transitions or cycles?

    Can you write a simple sketch to test and show? With an output toggled every 100 ms and that pin connected to the FreqMeas pin what does it read versus the scope?

    With Pin 13 LED to the Freq pin - Add code like below to your FreqMeasure sketch and you should see 5 Hz { change:: CYCLE_DELAY from 100 to 10 and it should give 50 Hz }

    Code:
    #define qBlink() {GPIOC_PTOR=32;} // toggle the pin 13 LED set to output
    
    elapsedMillis foo;
    void setup() {
      Serial.begin(9600);
      while (!Serial && millis() < 4000 );
      pinMode(LED_BUILTIN, OUTPUT);
      qBlink();
    // ...
      foo = 0;
    }
    
    #define CYCLE_DELAY 100 // added for single # change
    void loop() {
      if ( foo > CYCLE_DELAY ) {
        foo -= CYCLE_DELAY;
        qBlink();
      }
    // ...
    }
    Last edited by defragster; 12-31-2017 at 11:43 PM. Reason: Use #define

  3. #3
    The LED strobes at 5 Hz, which I think is as expected (100 ms on, 100 ms off).

  4. #4
    Sorry, I don't think I answered your first question either. Scope is measuring rising edge, so whole cycles. When I connect one of the FreqMeasure pins to 13, I measure 2.5 Hz, but visually the LED is clearly blinking at 5 Hz.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,764
    That's odd without a connection problem the Teensy should get it right. If you can post the complete sketch ( with added FreqMeasure code ) then Paul or others could reproduce it for attention - But probably not until next year

    Happy New Year!

  6. #6
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    1,775
    It is possible that there is a glitch in the FreqMeasureMulti library when using a Teensy LC, I hadn’t one at the hand to test when contributing the last updates. In fact, the timers in the LC are slightly different and they are also clocked in a different way. In order to fix it, I’d need to know some details: basically, this library doesn’t measure the frequency, but the pulse width time, which can then be converted in a frequency value in a second step. Thus, please let me know what the raw measured pulse tick value is, so that I can see if the pulse ticks are wrongly interpreted, or if the PW to frequency conversion is wrong. In ever case, everything is locked to a fixed bus or pll clock, so if the result is off by a factor, it will always be off by the same factor. As a workaround, a simple multiplication will help to get reliable results.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,764
    I have a T_LC beside me if I had the sketch . . .

  8. #8
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,572
    Running the examples FreqMeasureMulti Serial_Output, i added tone(13,5); to setup() and jumpered 13 to 6, and on LC it prints
    2.50, (no pulses), (no pulses)
    2.50, (no pulses), (no pulses)
    and on T3.2@96mhz
    5.00, (no pulses), (no pulses)
    5.00, (no pulses), (no pulses)

    i need to look at the library code, the LC TPM is clocked differently than T3 FTM counter.

    EDIT: LC TPM ticks at PLL/2 T3.* FTM ticks at F_BUS. so LC TPM is ticking @48mhz. it looks like library has some conditional code for KINETISL/F_PLL ????
    Last edited by manitou; 01-04-2018 at 11:36 PM.

  9. #9
    Thanks Manitou, looks like you reproduced what I am seeing.

    Just to be clear, I’m running the example:

    https://github.com/PaulStoffregen/Fr...ial_Output.ino

  10. #10
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,572
    FIXED
    as discussed in https://forum.pjrc.com/threads/48189...-the-Teensy-LC
    setting TPMx_CnSC needs to be disabled, wait, and then set, so in the lib's FreqMeasureMulti::isr for the KINETISL do

    csc[0] = 0; // disable
    asm volatile ("nop"); // wait

    csc[0] = (next_is_falling ? FTM_CSC_FALLING : FTM_CSC_RAISING) | FTM_CSC_CHF;


    i had used delayMicroseconds(1), but nop seems to work ....

    EDIT: i wonder if similar adjustment is needed in capture_read() of FreqMeasure lib
    https://github.com/PaulStoffregen/Fr...asureCapture.h
    EDIT: NOT, capture_read() is OK. setting CHF bit does not require disable/delay
    Last edited by manitou; 01-04-2018 at 11:08 AM.

  11. #11
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,572
    @elkayem, did you try the fix in post #10, adding two lines to library FreqMeasureMulti/FreqMeasureMulti.cpp (line 212 or there abouts).
    example works for me on LC with that fix.

  12. #12
    Quote Originally Posted by manitou View Post
    @elkayem, did you try the fix in post #10, adding two lines to library FreqMeasureMulti/FreqMeasureMulti.cpp (line 212 or there abouts).
    example works for me on LC with that fix.
    Just tried it. Brilliant! Yes, it works. I was never concerned about my code outputting the right result. I had a 2x in front of the frequency to correct this issue. But I knew this was a more fundamental issue, and you solved it.

    I notice you opened an Issue on GitHub to fix this once and for all, great!

    I confess, I don't really understand the fix you just posted. I suppose this means I need to start studying the Kinetis KL26 user manual...

    Thanks again for looking into this. I'm glad this community exists!

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,153
    I committed the fix on github. Thanks!

    https://github.com/PaulStoffregen/Fr...9fff860e6a30af

    I've been doing more testing here. This is a copy of the example, which reads all 6 pins.

    Code:
    /* FreqMeasureMulti - Example with serial output
     * http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
     *
     * This example code is in the public domain.
     */
    #include <FreqMeasureMulti.h>
    
    // Measure 3 frequencies at the same time! :-)
    FreqMeasureMulti freq1;
    FreqMeasureMulti freq2;
    FreqMeasureMulti freq3;
    FreqMeasureMulti freq4;
    FreqMeasureMulti freq5;
    FreqMeasureMulti freq6;
    
    void setup() {
      Serial.begin(57600);
      while (!Serial) ; // wait for Arduino Serial Monitor
      delay(10);
      Serial.println("FreqMeasureMulti Begin");
      delay(10);
      freq1.begin(6);
      freq2.begin(9);
      freq3.begin(10);
      freq4.begin(20);
      freq5.begin(22);
      freq6.begin(23);
    }
    
    float sum1=0, sum2=0, sum3=0, sum4=0, sum5=0, sum6=0;
    int count1=0, count2=0, count3=0, count4=0, count5=0, count6=0;
    elapsedMillis timeout;
    
    void loop() {
      if (freq1.available()) {
        sum1 = sum1 + freq1.read();
        count1 = count1 + 1;
      }
      if (freq2.available()) {
        sum2 = sum2 + freq2.read();
        count2 = count2 + 1;
      }
      if (freq3.available()) {
        sum3 = sum3 + freq3.read();
        count3 = count3 + 1;
      }
      if (freq4.available()) {
        sum4 = sum4 + freq4.read();
        count4 = count4 + 1;
      }
      if (freq5.available()) {
        sum5 = sum5 + freq5.read();
        count5 = count5 + 1;
      }
      if (freq6.available()) {
        sum6 = sum6 + freq6.read();
        count6 = count6 + 1;
      }
      // print results every half second
      if (timeout > 500) {
        if (count1 > 0) {
          Serial.print(freq1.countToFrequency(sum1 / count1));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.print(",  ");
        if (count2 > 0) {
          Serial.print(freq2.countToFrequency(sum2 / count2));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.print(",  ");
        if (count3 > 0) {
          Serial.print(freq3.countToFrequency(sum3 / count3));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.print(",  ");
        if (count4 > 0) {
          Serial.print(freq4.countToFrequency(sum4 / count4));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.print(",  ");
        if (count5 > 0) {
          Serial.print(freq5.countToFrequency(sum5 / count5));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.print(",  ");
        if (count6 > 0) {
          Serial.print(freq6.countToFrequency(sum6 / count6));
        } else {
          Serial.print("(no pulses)");
        }
        Serial.println();
        sum1 = 0;
        sum2 = 0;
        sum3 = 0;
        sum4 = 0;
        sum5 = 0;
        sum6 = 0;
        count1 = 0;
        count2 = 0;
        count3 = 0;
        count4 = 0;
        count5 = 0;
        count6 = 0;
        timeout = 0;
      }
    }

  14. #14
    Terrific, thanks Paul! I just pulled your latest version of the FreqMeasureMulti library.

Posting Permissions

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