Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino Frequency Counter: Measure Signals Up to 8MHz

Arduino Frequency Counter: Measure Signals Up to 8MHz

March 11, 2026 /Posted byJayesh Jain / 0

Building an arduino frequency counter project is one of the most practical and educational electronics projects you can undertake. A frequency counter lets you measure the oscillation rate of any periodic signal — from slow 1 Hz sensor pulses to fast 8 MHz crystal oscillators — using nothing more than an Arduino and a few passive components. This guide walks you through the complete design, from theory to a working circuit with an LCD display, capable of measuring signals up to 8 MHz.

Table of Contents

  • How a Frequency Counter Works
  • Hardware You Need
  • Circuit Design and Input Conditioning
  • Arduino Frequency Counter Code
  • Adding a 16×2 LCD Display
  • Extending the Range Beyond 8 MHz
  • Calibration and Accuracy
  • Frequently Asked Questions

How a Frequency Counter Works

Frequency is defined as the number of complete cycles per second, measured in Hertz (Hz). A frequency counter works by counting the number of rising edges (or pulses) on a signal within a precise time window — typically one second — then displaying that count as frequency in Hz.

The Arduino achieves this using its hardware timer and external interrupt system:

  • Timer1 (16-bit) generates a precise 1-second gate window using the 16 MHz crystal oscillator on the board.
  • INT0 or INT1 (digital pins 2 and 3 on Uno) count the rising edges from the incoming signal during that window.
  • After each gate window, the count equals the frequency in Hz.

The theoretical maximum frequency the Arduino can count is limited by the interrupt latency. Each interrupt takes approximately 4 CPU cycles to service. At 16 MHz clock speed, the absolute maximum is around 8 MHz — though 4-6 MHz is more reliable in practice without prescaling tricks.

Hardware You Need

For a basic frequency counter capable of measuring up to 8 MHz, you need:

  • Arduino Uno or compatible board (16 MHz)
  • 16×2 LCD display (HD44780 compatible) or LCD with I2C backpack
  • 10 kΩ potentiometer (LCD contrast)
  • 100 kΩ resistor and 1N4148 signal diode (input protection)
  • 0.1 µF decoupling capacitor
  • BNC connector (optional, for proper signal connections)
  • Breadboard and jumper wires (for prototyping)

For a polished kit build, an all-in-one solution is available:

Recommended: Arduino Frequency Counter Kit with 16×2 LCD Display — Complete kit with PCB, all components, and a pre-tested LCD; ideal for students and hobbyists who want a clean, professional result without breadboarding.
Recommended: Arduino Uno R3 Beginners Kit — Includes an Uno board and a comprehensive selection of components; the LCDs, resistors, and breadboard in this kit are compatible with this frequency counter project.

Circuit Design and Input Conditioning

The input stage is the most critical part of the frequency counter. Raw signals from oscillators, function generators, or other circuits may have voltage levels incompatible with Arduino’s 5V logic. Connecting a 12V signal directly to an Arduino pin will destroy the microcontroller.

Input Protection Circuit

The simplest safe input conditioning circuit uses three components:

  1. A 100 kΩ resistor in series with the signal (limits current to the clamping diodes).
  2. A 1N4148 diode from the signal pin to VCC (clamps overvoltage to ~5.6V).
  3. A second 1N4148 diode from GND to the signal pin (clamps undervoltage to –0.6V).

This configuration protects the pin while allowing signals between 0V and 5V to pass correctly. The 100 kΩ resistor does introduce a voltage divider effect at high frequencies — but for signals already in the 0–5V range, this is acceptable up to 8 MHz.

Signal Conditioning for Non-TTL Signals

Sine waves, triangular waves, or any analogue signal from a function generator must be converted to a clean digital square wave before counting. Use a 74HC14 Schmitt trigger inverter between your input and the Arduino pin. The hysteresis built into the Schmitt trigger prevents false triggering on slow-rise signals or noisy inputs.

Complete Connection Summary

  • Signal input → 100 kΩ → Arduino Pin 5 (ICP1, Timer1 input capture pin) or Pin 2 (INT0)
  • Clamping diodes connected between the Arduino pin, VCC, and GND
  • LCD: RS→D12, EN→D11, D4→D5, D5→D4, D6→D3, D7→D2 (if not using I2C backpack)
  • Potentiometer wiper → LCD V0 pin (contrast)

Arduino Frequency Counter Code

Method 1: External Interrupt Counter (Simple, Up to ~6 MHz)

// Arduino Frequency Counter using External Interrupt
// Measures up to ~6 MHz on Pin 2 (INT0)

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

volatile unsigned long pulseCount = 0;
unsigned long lastTime = 0;
float frequency = 0;

void countPulse() {
  pulseCount++;
}

void setup() {
  lcd.begin(16, 2);
  lcd.print("Freq Counter");
  attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);
  lastTime = millis();
}

void loop() {
  unsigned long currentTime = millis();
  
  if (currentTime - lastTime >= 1000) { // 1-second gate
    detachInterrupt(digitalPinToInterrupt(2));
    
    frequency = pulseCount / ((currentTime - lastTime) / 1000.0);
    pulseCount = 0;
    lastTime = currentTime;
    
    // Display result
    lcd.setCursor(0, 1);
    if (frequency >= 1000000) {
      lcd.print(frequency / 1000000.0, 3);
      lcd.print(" MHz   ");
    } else if (frequency >= 1000) {
      lcd.print(frequency / 1000.0, 3);
      lcd.print(" kHz   ");
    } else {
      lcd.print(frequency, 1);
      lcd.print(" Hz    ");
    }
    
    attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);
  }
}

Method 2: Timer1 Input Capture (Accurate, Up to 8 MHz)

For higher accuracy and frequencies up to 8 MHz, use the Timer1 Input Capture Unit (ICU) on pin D8 of the Arduino Uno. The ICU captures the exact timer value on each rising edge, eliminating interrupt latency errors.

// High-accuracy frequency counter using Timer1 ICP
// Measures period of input signal, calculates frequency
// Input: Pin 8 (ICP1) on Arduino Uno

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, A2);

volatile uint16_t captureVal[2];
volatile bool newCapture = false;
volatile uint8_t captureIdx = 0;

ISR(TIMER1_CAPT_vect) {
  captureVal[captureIdx & 1] = ICR1;
  captureIdx++;
  if (captureIdx >= 2) {
    newCapture = true;
    captureIdx = 0;
  }
}

void setup() {
  lcd.begin(16, 2);
  lcd.print("Freq Counter");
  
  // Configure Timer1 for input capture
  TCCR1A = 0;
  TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CS10); // No prescale, rising edge
  TIMSK1 = (1 << ICIE1); // Enable input capture interrupt
  
  sei();
}

void loop() {
  if (newCapture) {
    noInterrupts();
    uint16_t period = captureVal[1] - captureVal[0];
    newCapture = false;
    interrupts();
    
    if (period > 0) {
      float freq = 16000000.0 / period; // F_CPU / period_counts
      
      lcd.setCursor(0, 1);
      if (freq >= 1000000) {
        lcd.print(freq / 1000000.0, 4);
        lcd.print(" MHz ");
      } else if (freq >= 1000) {
        lcd.print(freq / 1000.0, 3);
        lcd.print(" kHz ");
      } else {
        lcd.print(freq, 2);
        lcd.print(" Hz  ");
      }
    }
  }
}

Adding a 16×2 LCD Display

The 16×2 LCD (HD44780) is the standard display for this project. Connect it in 4-bit mode to save Arduino pins. If you want to save even more pins, use an I2C LCD backpack module — it reduces the connection to just two wires (SDA and SCL), freeing up most of the Arduino’s I/O for other uses.

Format the frequency display to auto-scale between Hz, kHz, and MHz based on the measured value. Always display at least three significant figures for usability. Add a second line showing measurement period in microseconds for oscilloscope-like functionality.

Recommended: Arduino Mega 2560 R3 Board — For an expanded frequency counter with multiple input channels, data logging, and an SD card interface, the Mega’s extensive I/O and extra hardware timers make it the ideal platform.

Extending the Range Beyond 8 MHz

The Arduino Uno’s 16 MHz clock limits direct counting to roughly 8 MHz. For higher frequencies, two approaches work well:

Prescaler Divider (74HC390 or 74HC4040)

Insert a frequency divider IC between your input signal and the Arduino. A 74HC390 divides by 2, 5, or 10; a 74HC4040 provides binary division up to ÷4096. Divide the incoming frequency by 10, count the result on the Arduino, then multiply by 10 in software. This extends the range to 80 MHz with a ÷10 prescaler.

Arduino Nano RP2040 Connect

The RP2040 microcontroller runs at 133 MHz and has hardware PIO (Programmable I/O) state machines that can count at speeds approaching 100 MHz without burdening the CPU. If you need a single-chip solution for high-frequency measurement, upgrade to the RP2040.

Recommended: Arduino Nano RP2040 Connect with Header — The RP2040’s 133 MHz dual-core processor and hardware PIO enable frequency counting well beyond 8 MHz, ideal for RF and high-speed signal measurement projects.

Calibration and Accuracy

The accuracy of your frequency counter depends directly on the accuracy of the Arduino’s crystal oscillator. Standard Arduino Uno crystals are accurate to ±50 ppm — that is ±0.005%, or a maximum error of 50 Hz when measuring 1 MHz signals. This is adequate for most hobbyist applications.

Improving Accuracy

  • Reference calibration: Measure a known-accurate reference signal (GPS 1 PPS output = exactly 1 Hz) and apply a software correction factor.
  • TCXO: Replace the ceramic resonator on cheap boards with a temperature-compensated crystal oscillator (TCXO) module for 1–5 ppm accuracy.
  • Longer gate time: Increase the gate window from 1 second to 10 seconds. Accuracy improves proportionally, but updates become slower.
  • Multiple measurements: Average 5–10 readings and discard outliers for stable, accurate results on noisy signals.

Understanding Resolution

With a 1-second gate, resolution is 1 Hz — you cannot distinguish between 1000 Hz and 1001 Hz. With a 10-second gate, resolution improves to 0.1 Hz. For audio frequency work (20 Hz to 20 kHz), a 1-second gate gives 0.005% to 5% resolution — perfectly acceptable.

Frequently Asked Questions

What is the maximum frequency the Arduino Uno can measure?

Using the external interrupt method, reliably up to about 6 MHz. Using the Timer1 Input Capture Unit (pin D8), up to approximately 8 MHz. Beyond that, you need a prescaler divider IC or a faster microcontroller like the RP2040.

Can I measure the frequency of an AC mains supply (50 Hz) with this?

Yes, but you need a mains-safe isolation circuit — never connect mains voltage directly to an Arduino. Use a small signal transformer or optocoupler to generate a 0–5V TTL-level replica of the 50 Hz waveform, then feed that to the frequency counter input.

Why does my frequency reading fluctuate?

Fluctuation is usually caused by noise on the input signal triggering false edges. Add a Schmitt trigger (74HC14) in the input stage, add a 100 pF capacitor across the input to GND for RF noise filtering, and increase the Schmitt trigger hysteresis threshold if you are working with slow-rise signals.

Can I use this to tune a crystal oscillator?

Yes. Measure the crystal oscillator output, compare to the nominal frequency, and adjust the series/parallel capacitors to pull the frequency to specification. This is a standard crystal trimming procedure in radio equipment.

Does this project work with the Arduino Nano?

Yes. The Arduino Nano uses the same ATmega328P chip as the Uno and runs at 16 MHz, so all the code and timing is identical. The input capture pin is still D8 on the Nano.

Find all the components you need for your frequency counter project in our Arduino boards and kits collection at Zbotic.in — with fast delivery across India.

Tags: arduino electronics project india, arduino frequency counter, arduino input capture, arduino timer1, frequency counter project, measure frequency arduino
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Joystick Module PS2: Arduino R...
blog joystick module ps2 arduino robot and game controller 594839
blog arduino analog front end signal conditioning for sensors 594846
Arduino Analog Front End: Sign...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now