New to this forum and Teensy. The goal, using Teensy 4.0, is a frequency counter that can read frequency up to 35 MHz with an accuracy to the nearest 100 Khz. It should be reasonably responsive to frequency changes as it's reading the frequency resulting from someone turning a knob on an instrument. I'm not an accomplished C programmer and had no Teensy knowledge other than some basic capacilities, so depended heavily on the CoPilot AI program to get to the point I'm at now.
I'm using the FreqCount library and counting the injected signal using pin 9 of the Teensy. The issue at the moment is getting the counter to read to the nearest 100 kHz number. The problem seems to be that the read is not returning enough digits to accomplish that. Also need to work on the calibration correction as the error seems to be not a constant value but rather a percentage of the frequency. Any and all comments and suggestions are welcome.
At this point, the Teensy is able to measure the frequency of an input down to around 300mv, either sine or square wave. The output display is an OLED graphics module. The current sketch follows:
I'm using the FreqCount library and counting the injected signal using pin 9 of the Teensy. The issue at the moment is getting the counter to read to the nearest 100 kHz number. The problem seems to be that the read is not returning enough digits to accomplish that. Also need to work on the calibration correction as the error seems to be not a constant value but rather a percentage of the frequency. Any and all comments and suggestions are welcome.
At this point, the Teensy is able to measure the frequency of an input down to around 300mv, either sine or square wave. The output display is an OLED graphics module. The current sketch follows:
C:
#include <FreqCount.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <math.h>
// OLED
U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10,7,6);
// --- smoothing buffer ---
//const int N = 8;
const int N = 256; // very stable
uint32_t buf[N];
int idx = 0;
//Inj freq is actual freq + 5645 KHz
int IF = 5645;
bool filled = false;
double smoothValue(uint32_t v) {
buf[idx++] = v;
if (idx >= N) {
idx = 0;
filled = true;
}
int count = filled ? N : idx;
uint64_t sum = 0;
for (int i = 0; i < count; i++) sum += buf;
return (double)sum / count;
}
void setup() {
Serial.begin(115200);
u8g2.begin();
u8g2.setFont(u8g2_font_logisoso24_tf);
// Teensy 4.0 FreqCount backend uses a 1ms gate internally,
// so we scale raw counts by 1000 to get Hz.
FreqCount.begin(1000);
}
void loop() {
if (FreqCount.available()) {
uint32_t raw = FreqCount.read();
double s = smoothValue(raw);
double hz = s * 1000.0;
double mhz = hz / 1e6;
// slow update timing
static uint32_t lastUpdate = 0;
if (millis() - lastUpdate < 300) return;
lastUpdate = millis();
char out[20];
// calibration: counter reads 0.0001 MHz high → subtract 0.0001
const double CAL_OFFSET = -0.0001;
// mhz += CAL_OFFSET;
mhz = round(mhz * 10000.0) / 10000.0;
//Put IF freq correction here
//mhz = mhz - IF;
snprintf(out, sizeof(out), "%8.4f", mhz);
u8g2.clearBuffer();
u8g2.setCursor(0, 40);
u8g2.print(out);
u8g2.sendBuffer();
Serial.println(out);
}
}
Last edited: