Frequency meter, print on serial monitor
Download the .zip file below. Unzip it and open it in Arduino IDE. Compile and upload.
/*Whistling sound switch; author: ELECTRONOOBS
* Subscribe: http://www.youtube.com/c/ELECTRONOOBS
*
* Activate any Arduino loop just by whistling. The circuit is very easy.
* Check the entire tutorial here: http://www.electronoobs.com/eng_arduino_tut19.php *
*
* Input pin is D8
* Relay output is D13
* PWM buzzer output is D3
*/
//We create a variable for the time width value of the input signal
unsigned long last_pulse_time_counter, present_time;
//We create 1 variables to store the previous value of the input signal (if LOW or HIGH)
byte last_PIN_state;
//To store the final width value we create this variables (this will be half of the period)
//Variables
float Period = 0;
float Frequency_micro = 0;
float Frequency = 0;
int Pulse_amount = 0;
int pulse_is_measured = 0;
int sum_count = 0; //Increaase the count amount by one in each loop only if the range is correct
float freq_sum = 0;
float freq_mean = 0;
void setup() {
/*
* Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board.
* The chips used on the Arduino board (the ATmega8 and ATmega168) have three ports:
-B (digital pin 8 to 13)
-C (analog input pins)
-D (digital pins 0 to 7)
//All Arduino (Atmega) digital pins are inputs when you begin...
*/
PCICR |= (1 << PCIE0); //enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); //Set pin "D8" trigger an interrupt on "any" state change.
//Start the serial in order to see the result on the monitor
//Remember to select the same baud rate on the serial monitor
Serial.begin(250000);
}
void loop() {
/* Ok, so in the loop the only thing that we do in this example is to print
* the received values on the Serial monitor. The PWM values are read in the ISR below.
*/
if(pulse_is_measured) //Only when a full pulse is measured we enter the loop
{
pulse_is_measured = 0; //We reset "the pulse is detected" for the next loop
Frequency_micro = 1/Period; //Invert the period and get the frequency (in Hertz by us)
Frequency = Frequency_micro*1000000; //Multiply by one million and get frequency (in Hertz by seconds)
sum_count = sum_count+1; //Increaase the count amount by one in each loop only if the range is correct
freq_sum = freq_sum + Frequency; //calculating a mean
freq_mean = freq_sum/sum_count;
if(sum_count >= 200) //I want 200 detected pulses with the same frequency range in a raw to
{ //be detected before I give the mean.
Serial.print("Freq: "); //Print the values
Serial.println(freq_mean);
sum_count=0; //Reset the values
freq_mean = 0;
freq_sum = 0;
}
}//end of if pulse is measured
}//end of loop
//This is the pulse width interruption routine
//----------------------------------------------
ISR(PCINT0_vect){
//First we take the present_time value in micro seconds using the micros() function
present_time = micros();
///////////////////////////////////////Signal input
if(PINB & B00000001){ //We make an AND with the pin state register, We verify if pin 8 is HIGH???
if(last_PIN_state == 0){ //If the last state was 0, then we have a state change...
last_PIN_state = 1; //Store the current state into the last state for the next loop
Period = present_time - last_pulse_time_counter; //We make the time difference. Channel 1 is current_time - timer_1.
last_pulse_time_counter = present_time; //Set pulse_time_counter to current value.
pulse_is_measured = 1; //We indicate that one full width was measured
}
}
else if(last_PIN_state == 1){ //If pin 8 is LOW and the last state was HIGH then we have a state change
last_PIN_state = 0; //Store the current state into the last state for the next loop
}
}