Hi jgustavoam. No, I wanted to use the frequency counter in a generic code. I rearranged the pins according to the Firebeetle ESP32-e card. As I said, there is a problem with the IDE monitor. I am attaching the code.
I defined pin D7 (13) for osc output. When I measure this pin with an oscilloscope, I can see the 12.5khz pulse output. When I combine the pin number D9(2), which I defined for the signal input, with the osc output, the frequency appears as 14.043khz on the monitor. Also, when I use pin 34 as input pin, I see the frequency of 14.043khz in the same way.
Code: Select all
#include "stdio.h" // Library STDIO
#include "driver/ledc.h" // Library ESP32 LEDC
#include "driver/pcnt.h"
#include <pitches.h>
#include <Tone32.h>
#include <SPI.h>
#include <Wire.h>
#include <LIS3MDL.h>
#include <LiquidCrystal_I2C.h>// Library ESP32 PCNT
//int PotV, x=0 , y=0 , z=0;
int k1=10, k2=20, k3=30, k4=40, k5=50, k6=60; // coefficent
int f[6],k[6]; // base frequencies
int fa[6],fb[6]; // intra group range
int Buzzer = 25;
int redLed = 16;
int greenLed = 17;
//int buttonState = 0;
const int PotPin = 35;
//const int BatPin = 36;
//int BatValue;
//int Voltage = 0;
LIS3MDL mag;
char report[80];
LiquidCrystal_I2C lcd(0x3f,16,2);
#define LCD_OFF // LCD_ON, if want use LCD 4 bits interface
#define LCD_I2C_OFF // LCD_I2C_ON, if want use I2C LCD (PCF8574)
//#ifdef LCD_I2C_ON // If I2C LCD enabled
//#define I2C_SDA 21 // LCD I2C SDA - GPIO_21
//#define I2C_SCL 22 // LCD I2C SCL - GPIO_22
//#include <LiquidCrystal_PCF8574.h> // Library LCD with PCF8574
//LiquidCrystal_PCF8574 lcd(0x3F); // Instance LCD I2C - adress x3F
//#endif // LCD I2C
#ifdef LCD_ON // LCD with 4 bits interface enabled
#include <LiquidCrystal.h> // Library LCD
LiquidCrystal lcd(4, 16, 17, 5, 18, 19); // Instance - ports RS,ENA,D4,D5,D6,D7
#endif // LCD
#define PCNT_COUNT_UNIT PCNT_UNIT_0 // Set Pulse Counter Unit - 0
#define PCNT_COUNT_CHANNEL PCNT_CHANNEL_0 // Set Pulse Counter channel - 0
#define PCNT_INPUT_SIG_IO GPIO_NUM_2 // Set Pulse Counter input - Freq Meter Input GPIO 2
#define LEDC_HS_CH0_GPIO GPIO_NUM_13 // Saida do LEDC - gerador de pulsos - GPIO_13
#define PCNT_INPUT_CTRL_IO GPIO_NUM_14 // Set Pulse Counter Control GPIO pin - HIGH = count up, LOW = count down
#define OUTPUT_CONTROL_GPIO GPIO_NUM_0 // Timer output control port - GPIO_0
#define PCNT_H_LIM_VAL overflow // Overflow of Pulse Counter
#define IN_BOARD_LED GPIO_NUM_26 // ESP32 native LED - GPIO 2
bool flag = true; // Flag to enable print frequency reading
uint32_t overflow = 1500; // Max Pulse Counter value
int16_t pulses = 0; // Pulse Counter value
uint32_t multPulses = 0; // Quantidade de overflows do contador PCNT
uint32_t sample_time = 1000000; // sample time of 1 second to count pulses
uint32_t osc_freq = 12543; // Oscillator frequency - initial 12543 Hz (may be 1 Hz to 40 MHz)
uint32_t mDuty = 0; // Duty value
uint32_t resolution = 0; // Resolution value
float frequency = 0; // frequency value
char buf[32]; // Buffer
esp_timer_create_args_t create_args; // Create an esp_timer instance
esp_timer_handle_t timer_handle; // Create an single timer
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // portMUX_TYPE to do synchronism
//----------------------------------------------------------------------------------------
void setup()
{
Serial.begin(115200);
while (!Serial) {
}
lcd.begin();
lcd.backlight();
//pinMode(buttonPin , INPUT);
pinMode(PotPin, INPUT);
pinMode(redLed , OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(Buzzer, OUTPUT);
// pinMode(BatPin, INPUT);
Wire.begin();
// buttonState = digitalRead(buttonPin);
Serial.println(" Input the Frequency - 1 to 40 MHz"); // Console print
#ifdef LCD_I2C_ON // If usinf I2C LCD
Wire.begin(I2C_SDA, I2C_SCL); // Begin I2C Interface
lcd.setBacklight(255); // Set I2C LCD Backlight ON
#endif
#if defined LCD_ON || defined LCD_I2C_ON // If using LCD or I2C LCD
lcd.begin(16, 2); // LCD init 16 x 2
lcd(1); // LCD print
#endif
init_frequencyMeter (); // Initialize Frequency Meter
}
void loop()
{
//BatValue = analogRead(BatPin); //BatValue High=4095
//Voltage = ((12.6/4095.0)*BatValue); //!! 12.6v için uygun dirençle voltaj bölünmeli; BatValue High=4095.
PotV = analogRead(PotPin);
PotV = map(PotV,0,4095,0,100);//manyetik büyüklük yerine geçecek pot değeri.
f[0]= k[0]*PotV; f[1]= k[1]*PotV; f[2]= k[2]*PotV;
f[3]= k[3]*PotV; f[4]= k[4]*PotV; f[5]= k[5]*PotV;
// calculation of intra group frequencies
// lower range .... upper range
fa[0] = f[0] * 0.9; fb[0] = f[0] * 1.1;
fa[1] = f[1] * 0.9; fb[1] = f[1] * 1.1;
fa[2] = f[2] * 0.9; fb[2] = f[2] * 1.1;
fa[3] = f[3] * 0.9; fb[3] = f[3] * 1.1;
fa[4] = f[4] * 0.9; fb[4] = f[4] * 1.1;
fa[5] = f[5] * 0.9; fb[5] = f[5] * 1.1;
if (flag == true) // If count has ended
{
flag = false; // change flag to disable print
frequency = (pulses + (multPulses * overflow)) / 2 ; // Calculation of frequency
printf("Frequency : %s", (ltos(frequency, buf, 10))); // Print frequency with commas
printf(" Hz \n"); // Print unity Hz
#if defined LCD_ON || defined LCD_I2C_ON // If using LCD or I2C LCD
if ((frequency >= fa[0]) && (frequency <= fb[0]))
{
lcd2();
}
else if((frequency >= fa[1]) && (frequency <= fb[1]))
{
lcd3();
}
else if ((frequency >= fa[2]) && (frequency <= fb[2]))
{
lcd4();
}
else if ((frequency >= fa[3]) && (frequency <= fb[3]))
{
lcd5();
}
else if ((frequency >= fa[4]) && (frequency <= fb[4]))
{
lcd6();
}
else if ((frequency >= fa[5]) && (frequency <= fb[5]))
{
lcd7();
}
else {
lcd8();
}
#endif
multPulses = 0; // Clear overflow counter
// Put your function here, if you want
delay (100); // Delay 100 ms
// Put your function here, if you want
pcnt_counter_clear(PCNT_COUNT_UNIT); // Clear Pulse Counter
esp_timer_start_once(timer_handle, sample_time); // Initialize High resolution timer (1 sec)
gpio_set_level(OUTPUT_CONTROL_GPIO, 1); // Set enable PCNT count
}
String inputString = ""; // clear temporary string
osc_freq = 0; // Clear oscillator frequency
while (Serial.available())
{
char inChar = (char)Serial.read(); // Reads a byte on the console
inputString += inChar; // Add char to string
if (inChar == '\n') // If new line (enter)
{
osc_freq = inputString.toInt(); // Converts String into integer value
inputString = ""; // Clear string
}
}
if (osc_freq != 0) // If some value inputted to oscillator frequency
{
init_osc_freq (); // reconfigure ledc function - oscillator
}
// ----------------- frequency osc end ------------------------------//
}
void lcd1()
{
lcd.setCursor(0,0);
lcd.print("LF SIGNAL DETECTION ");
lcd.setCursor(0,1);
lcd.print(" ..PLEASE WAIT..");
}
void lcd2(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 1" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd3(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 2" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd4(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 3" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd5(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 4" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd6(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 5" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd7(){
digitalWrite(greenLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("Gr: 6" );
lcd.print(" M:" );
lcd.print(PotV);
tone(Buzzer , 2000 , 100);
}
void lcd8(){
digitalWrite(redLed, HIGH);
lcd.setCursor(0,0);
lcd.print("S: ");
lcd.print( (ltos(frequency, buf, 1)));
lcd.print(" Hz");
lcd.setCursor(0,1);
lcd.print("M: " );
lcd.print(PotV);
tone(Buzzer , 100 , 500);
}
void init_osc_freq () // Initialize Oscillator to test Freq Meter
{
resolution = (log (80000000 / osc_freq) / log(2)) / 2 ; // Calc of resolution of Oscillator
if (resolution < 1) resolution = 1; // set min resolution
// Serial.println(resolution); // Print
mDuty = (pow(2, resolution)) / 2; // Calc of Duty Cycle 50% of the pulse
// Serial.println(mDuty); // Print
ledc_timer_config_t ledc_timer = {}; // LEDC timer config instance
ledc_timer.duty_resolution = ledc_timer_bit_t(resolution); // Set resolution
ledc_timer.freq_hz = osc_freq; // Set Oscillator frequency
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; // Set high speed mode
ledc_timer.timer_num = LEDC_TIMER_0; // Set LEDC timer index - 0
ledc_timer_config(&ledc_timer); // Set LEDC Timer config
ledc_channel_config_t ledc_channel = {}; // LEDC Channel config instance
ledc_channel.channel = LEDC_CHANNEL_0; // Set HS Channel - 0
ledc_channel.duty = mDuty; // Set Duty Cycle 50%
ledc_channel.gpio_num = LEDC_HS_CH0_GPIO; // LEDC Oscillator output GPIO 33
ledc_channel.intr_type = LEDC_INTR_DISABLE; // LEDC Fade interrupt disable
ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE; // Set LEDC high speed mode
ledc_channel.timer_sel = LEDC_TIMER_0; // Set timer source of channel - 0
ledc_channel_config(&ledc_channel); // Config LEDC channel
}
//----------------------------------------------------------------------------------
static void IRAM_ATTR pcnt_intr_handler(void *arg) // Counting overflow pulses
{
portENTER_CRITICAL_ISR(&timerMux); // disabling the interrupts
multPulses++; // increment Overflow counter
PCNT.int_clr.val = BIT(PCNT_COUNT_UNIT); // Clear Pulse Counter interrupt bit
portEXIT_CRITICAL_ISR(&timerMux); // enabling the interrupts
}
//----------------------------------------------------------------------------------
void init_PCNT(void) // Initialize and run PCNT unit
{
pcnt_config_t pcnt_config = { }; // PCNT unit instance
pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_IO; // Pulse input GPIO 34 - Freq Meter Input
pcnt_config.ctrl_gpio_num = PCNT_INPUT_CTRL_IO; // Control signal input GPIO 35
pcnt_config.unit = PCNT_COUNT_UNIT; // Unidade de contagem PCNT - 0
pcnt_config.channel = PCNT_COUNT_CHANNEL; // PCNT unit number - 0
pcnt_config.counter_h_lim = PCNT_H_LIM_VAL; // Maximum counter value - 20000
pcnt_config.pos_mode = PCNT_COUNT_INC; // PCNT positive edge count mode - inc
pcnt_config.neg_mode = PCNT_COUNT_INC; // PCNT negative edge count mode - inc
pcnt_config.lctrl_mode = PCNT_MODE_DISABLE; // PCNT low control mode - disable
pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // PCNT high control mode - won't change counter mode
pcnt_unit_config(&pcnt_config); // Initialize PCNT unit
pcnt_counter_pause(PCNT_COUNT_UNIT); // Pause PCNT unit
pcnt_counter_clear(PCNT_COUNT_UNIT); // Clear PCNT unit
pcnt_event_enable(PCNT_COUNT_UNIT, PCNT_EVT_H_LIM); // Enable event to watch - max count
pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL); // Setup Register ISR handler
pcnt_intr_enable(PCNT_COUNT_UNIT); // Enable interrupts for PCNT unit
pcnt_counter_resume(PCNT_COUNT_UNIT); // Resume PCNT unit - starts count
}
//----------------------------------------------------------------------------------
void read_PCNT(void *p) // Read Pulse Counter
{
gpio_set_level(OUTPUT_CONTROL_GPIO, 0); // Stop counter - output control LOW
pcnt_get_counter_value(PCNT_COUNT_UNIT, &pulses); // Read Pulse Counter value
flag = true; // Change flag to enable print
}
//---------------------------------------------------------------------------------
void init_frequencyMeter ()
{
init_osc_freq(); // Initialize Oscillator
init_PCNT(); // Initialize and run PCNT unit
gpio_pad_select_gpio(OUTPUT_CONTROL_GPIO); // Set GPIO pad
gpio_set_direction(OUTPUT_CONTROL_GPIO, GPIO_MODE_OUTPUT); // Set GPIO 32 as output
create_args.callback = read_PCNT; // Set esp-timer argument
esp_timer_create(&create_args, &timer_handle); // Create esp-timer instance
gpio_set_direction(IN_BOARD_LED, GPIO_MODE_OUTPUT); // Set LED inboard as output
gpio_matrix_in(PCNT_INPUT_SIG_IO, SIG_IN_FUNC226_IDX, false); // Set GPIO matrin IN - Freq Meter input
gpio_matrix_out(IN_BOARD_LED, SIG_IN_FUNC226_IDX, false, false); // Set GPIO matrix OUT - to inboard LED
}
//----------------------------------------------------------------------------------------
char *ultos_recursive(unsigned long val, char *s, unsigned radix, int pos) // Format an unsigned long (32 bits) into a string
{
int c;
if (val >= radix)
s = ultos_recursive(val / radix, s, radix, pos + 1);
c = val % radix;
c += (c < 10 ? '0' : 'a' - 10);
*s++ = c;
if (pos % 3 == 0) *s++ = ',';
return s;
}
//----------------------------------------------------------------------------------------
char *ltos(long val, char *s, int radix) // Format an long (32 bits) into a string
{
if (radix < 2 || radix > 36) {
s[0] = 0;
} else {
char *p = s;
if (radix == 10 && val < 0) {
val = -val;
*p++ = '-';
}
p = ultos_recursive(val, p, radix, 0) - 1;
*p = 0;
}
return s;
}