FreqCount.End stops Teensy loop and can't recover back to the loop

Status
Not open for further replies.

waynegal

Member
I am using an HF Transceiver to sample the RF and measure the frequency. I am using the Frequency Count library ( FreqCount.h) from PJRC site

with the following code.

if (FreqCount.available()) {
count = FreqCount.read();
count =count*1000;
previous_count =count;
running[ant].Frq = count;


if (count = 0) {
running[ant].Frq = 4000000;
FreqCount.end();
FreqCount.Begin();
}
}


The Code does measure the frequency, but the if (count = 0) stops the code loop. What I am trying to achieve is to measure the incoming frequency, but with the FreqCount.end() to stop measuring and remember the last measured frequency. At present removing the source frequency lead from pin 13 renders all to zero. I have tried every possible solutions except the correct one.
 
The correction allowed the code to enter the if command.

this part of the code works

if (count = 0) {
running[ant].Frq = 4000000;
FreqCount.end();
FreqCount.Begin();
}


when it executes the running[ant].Frq = 4000000; works, but FreqCount.end does not cause the display of the last measured value

Getting closer
 
I am using a frequency generator as a source for pin 13 on a Teensy 3.2. I am using the Frequency Count library ( FreqCount.h) from PJRC site



Code:
if (FreqCount.available()) {
count = FreqCount.read();
count =count*1000;
previous_count =count;
running[ant].Frq = count;


if (count == 0) {
count = last measured value;
FreqCount.end();

}
}

What I am trying to achieve is to measure the incoming frequency, but with the FreqCount.end() to stop measuring and remember the last measured frequency. At present removing the source frequency lead from pin 13 renders all to zero.

Do I have to modify the library FreqCount.h to latch last measured value?
 
I presume that you want to have the variable "previous_count" hold the value before the count went to zero.
In which case, this code
Code:
count = FreqCount.read();
count =count*1000;
previous_count =count;
always sets previous_count to the new value of count. Try rearranging those statements a bit:
Code:
previous_count =count;
count = FreqCount.read();
count =count*1000;

Pete
 
I presume that you want to have the variable "previous_count" hold the value before the count went to zero.
In which case, this code
Code:
count = FreqCount.read();
count =count*1000;
previous_count =count;
always sets previous_count to the new value of count. Try rearranging those statements a bit:
Code:
previous_count =count;
count = FreqCount.read();
count =count*1000;

Pete

Everthing goes to zero no matter how variables are arranged. We need a latching routine in its own function possibly
 
Did you miss post #2?

if (count = 0) {
running[ant].Frq = 4000000;
FreqCount.end();
FreqCount.Begin();
}


if(count = 0) will allways evaluate to FALSE and the next three statements never get executed.

if(count == 0) will execute when count is not zero.
 
if(count = 0) will always assign count = 0. The compiler should emit a warning because while technically valid, doing this inside an evaluation is weird, and probably not what any programmer intends to do.

Always remember that = is assignment, and == is comparison.
 
I think I've been overthinking this problem--partially because @waynegal didn't post enough code to show what will be done with the measured frequency.

If the frequency is just to be used for a display for the program user, it doesn't need to be update more than 10 times a second. If it will be used to control an antenna tuner, you may need results more often--but probably not more than a few hundred times a second.

To simplify, there's no need to stop the frequency counter after you start it unless you absolutely have to do something else with pin 13. You can just read the value and use it as you wish---store it, display it, use it to control the temperature of your hot tub---whatever! ;-)

Here's the sample code to show how to do that. It worked OK up to the 2MHz limit of my el-cheapo function generator.
(I assume that your hardware presents a clean, near-square-wave signal in the 0 to 3.3V range to pin 13).

Code:
/* **********************************************
 *   Based on FreqCount - Example with serial output
 * http://www.pjrc.com/teensy/td_libs_FreqCount.html
 *
 * This example code is in the public domain.
 * 
 * Revised to put frequency counting in a function
 * You can do anything you want with the return value
 * Compiled for TA3.6.  Frequency input on pin13 assumed by library
 */
#include <FreqCount.h>

const char compileTime [] = "T3.6 FreqCount Measurement Test Compiled on " __DATE__ " " __TIME__;
void setup() {
  Serial.begin(57600);
  delay(500);
  Serial.println();
  Serial.println(compileTime);
  FreqCount.begin(1);  // count for 1 millisecond
}
uint32_t lastfreq;

void loop() {
  uint32_t  startmicro;
  char ch;
  // get frequency with any character received
  if(Serial.available()){
    ch = Serial.read();
    startmicro = micros();
    lastfreq = GetFreq() * 1000; //correct for 1mSec counting interval but lose resolution 
    // Since lastfreq is a global, you can use it anywhere you want in  your program.
    Serial.printf("F = %lu  Call1 took %lu microseconds\n",lastfreq, micros()-startmicro);
    // if you call GetFreq again within 1mSec, the routing has to wait for a new value
    startmicro = micros();
    lastfreq = GetFreq() * 1000; //correct for 1mSec counting interval but lose resolution 
    Serial.printf("F = %lu  Call2 took %lu microseconds\n",lastfreq, micros()-startmicro);
  }
}


// This function returns the last read frequency
// If you call it with less than 1 millisecond between
// calls, the function waits for the next valid count
uint32_t GetFreq(void){
  while(!FreqCount.available());  // wait until a valid frequency is available
  return FreqCount.read(); // this resets the available flag 
}
 
I think I've been overthinking this problem--partially because @waynegal didn't post enough code to show what will be done with the measured frequency.

If the frequency is just to be used for a display for the program user, it doesn't need to be update more than 10 times a second. If it will be used to control an antenna tuner, you may need results more often--but probably not more than a few hundred times a second.

To simplify, there's no need to stop the frequency counter after you start it unless you absolutely have to do something else with pin 13. You can just read the value and use it as you wish---store it, display it, use it to control the temperature of your hot tub---whatever! ;-)

Here's the sample code to show how to do that. It worked OK up to the 2MHz limit of my el-cheapo function generator.
(I assume that your hardware presents a clean, near-square-wave signal in the 0 to 3.3V range to pin 13).

Code:
/* **********************************************
 *   Based on FreqCount - Example with serial output
 * http://www.pjrc.com/teensy/td_libs_FreqCount.html
 *
 * This example code is in the public domain.
 * 
 * Revised to put frequency counting in a function
 * You can do anything you want with the return value
 * Compiled for TA3.6.  Frequency input on pin13 assumed by library
 */
#include <FreqCount.h>

const char compileTime [] = "T3.6 FreqCount Measurement Test Compiled on " __DATE__ " " __TIME__;
void setup() {
  Serial.begin(57600);
  delay(500);
  Serial.println();
  Serial.println(compileTime);
  FreqCount.begin(1);  // count for 1 millisecond
}
uint32_t lastfreq;

void loop() {
  uint32_t  startmicro;
  char ch;
  // get frequency with any character received
  if(Serial.available()){
    ch = Serial.read();
    startmicro = micros();
    lastfreq = GetFreq() * 1000; //correct for 1mSec counting interval but lose resolution 
    // Since lastfreq is a global, you can use it anywhere you want in  your program.
    Serial.printf("F = %lu  Call1 took %lu microseconds\n",lastfreq, micros()-startmicro);
    // if you call GetFreq again within 1mSec, the routing has to wait for a new value
    startmicro = micros();
    lastfreq = GetFreq() * 1000; //correct for 1mSec counting interval but lose resolution 
    Serial.printf("F = %lu  Call2 took %lu microseconds\n",lastfreq, micros()-startmicro);
  }
}


// This function returns the last read frequency
// If you call it with less than 1 millisecond between
// calls, the function waits for the next valid count
uint32_t GetFreq(void){
  while(!FreqCount.available());  // wait until a valid frequency is available
  return FreqCount.read(); // this resets the available flag 
}

The code works great. If you remove the source frequency; the frequency count goes to zero. I want to capture and hold the last read frequency before the source is removed.
 
Status
Not open for further replies.
Back
Top