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 Oscilloscope: Turn Your Board into a Signal Analyzer

Arduino Oscilloscope: Turn Your Board into a Signal Analyzer

March 11, 2026 /Posted byJayesh Jain / 0

An Arduino oscilloscope DIY project is one of the most educational builds you can undertake as an electronics enthusiast. While it won’t replace a professional bench oscilloscope, a carefully constructed Arduino-based signal analyzer is genuinely useful for debugging audio circuits, PWM signals, sensor outputs, and low-frequency waveforms — and it costs a fraction of even the cheapest dedicated scope. In this guide, we cover everything from ADC fundamentals to complete display implementations.

Table of Contents

  • How an Arduino Oscilloscope Works
  • Understanding ADC Limits and Sampling Rate
  • Project 1: Basic Serial Plotter Oscilloscope
  • Project 2: Standalone TFT Display Oscilloscope
  • Implementing Triggering for Stable Waveforms
  • Input Protection and Voltage Dividers
  • Performance Tips and Limitations
  • Frequently Asked Questions

How an Arduino Oscilloscope Works

A real oscilloscope continuously samples an input voltage, stores the samples in a buffer, and renders them as a time-domain waveform on screen. Your Arduino does exactly the same thing — just slower. The ATmega328P’s ADC converts an analog voltage (0–5V on most boards) to a 10-bit digital value (0–1023). By sampling at a known rate and plotting successive samples, you reconstruct the shape of the input waveform.

The key constraint is the Nyquist theorem: to accurately represent a signal, your sampling rate must be at least twice the signal’s highest frequency. The Arduino Uno’s ADC defaults to a 125kHz clock with a 13-cycle conversion time, giving about 9,600 samples per second (9.6kSPS). That means you can faithfully display signals up to roughly 4.8kHz — enough for audio fundamentals, PWM waveforms, and most sensor outputs, but nowhere near the megahertz range of real scopes.

With prescaler tuning (reducing the ADC clock divider from 128 to 16), you can push the ATmega328P to around 77kSPS at the cost of reduced accuracy (effectively 8-bit resolution). On faster platforms like the Arduino Nano RP2040 Connect, the RP2040’s ADC can reach 500kSPS, dramatically extending the useful frequency range.

Recommended: Arduino Nano RP2040 Connect with Header — The RP2040’s fast ADC and dual cores make it the best Arduino-compatible platform for a DIY oscilloscope with useful bandwidth.

Understanding ADC Limits and Sampling Rate

Before writing a single line of code, understand what your hardware can actually deliver:

ADC Prescaler Configuration

On AVR-based boards, the ADC clock is derived from the system clock (16MHz for Uno) divided by a prescaler. The default prescaler is 128, giving 16MHz/128 = 125kHz ADC clock. At 13 cycles per conversion: 125,000/13 ≈ 9,615 SPS.

// Fast ADC: prescaler 16 → ~76,923 SPS (reduced accuracy)
ADCSRA = (ADCSRA & ~0x07) | 0x04; // Set prescaler to 16

// Fastest: prescaler 4 → ~307,692 SPS (noisy, 6-bit effective)
ADCSRA = (ADCSRA & ~0x07) | 0x02; // Set prescaler to 4

Free-Running Mode

For maximum throughput, enable free-running mode where the ADC continuously converts without waiting for software to start each conversion:

ADMUX = (1<<REFS0) | 0; // AVCC reference, channel A0
ADCSRA |= (1<<ADATE);   // Auto-trigger enable
ADSRB = 0;               // Free-running mode
ADCSRA |= (1<<ADSC);    // Start first conversion

In free-running mode, read ADCW (the combined ADC result register) directly for maximum speed. This is how high-performance Arduino oscilloscope libraries operate.

Project 1: Basic Serial Plotter Oscilloscope

The simplest Arduino oscilloscope uses the Arduino IDE’s built-in Serial Plotter (Tools → Serial Plotter). No additional hardware needed — just your Arduino and a signal source.

const int ADC_PIN = A0;
const int SAMPLE_RATE = 4000; // Hz
const unsigned long INTERVAL_US = 1000000UL / SAMPLE_RATE;

void setup() {
  Serial.begin(115200);
  // Optional: reduce ADC prescaler for faster sampling
  ADCSRA = (ADCSRA & ~0x07) | 0x05; // Prescaler 32 ~ 19kSPS
}

void loop() {
  static unsigned long lastSample = 0;
  if (micros() - lastSample >= INTERVAL_US) {
    lastSample += INTERVAL_US;
    int value = analogRead(ADC_PIN);
    // Map to voltage (0–5V)
    float voltage = value * (5.0 / 1023.0);
    Serial.println(voltage);
  }
}

Open the Serial Plotter, set baud rate to 115200, and you’ll see a live waveform. This is excellent for visualizing audio from a microphone, PWM duty cycle changes, and temperature sensor outputs. The limitation is that the Serial Plotter’s X-axis is sample-count, not real time, so you need to calculate frequency from sample rate manually.

Recommended: Arduino Frequency Counter Kit with 16×2 LCD Display — A great companion project to your oscilloscope for measuring signal frequencies accurately.

Project 2: Standalone TFT Display Oscilloscope

A standalone scope with a TFT display is far more satisfying and practical. You get a portable device without needing a computer. The 2.4″ TFT touch screen shield for Arduino Uno makes this straightforward:

Hardware Setup

  • Arduino Uno or Mega
  • 2.4″ TFT display shield (plugs directly into Uno)
  • Input signal connected to A0 via a 1MΩ + 10kΩ voltage divider (see input protection section)

Core Display Logic

#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0_PIN // Careful: A0 used for input!
#define LCD_RESET A4

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define SCREEN_W 240
#define SCREEN_H 320
#define SCOPE_H 200
#define INPUT_PIN A5 // Shifted to A5 since A0 is LCD_RD

uint16_t buffer[SCREEN_W];
uint16_t prevBuffer[SCREEN_W];

void setup() {
  tft.reset();
  tft.begin(0x9341); // ILI9341 driver
  tft.setRotation(1);
  tft.fillScreen(0x0000); // Black background
  drawGrid();
}

void loop() {
  // Sample SCREEN_W points
  for (int i = 0; i < SCREEN_W; i++) {
    buffer[i] = map(analogRead(INPUT_PIN), 0, 1023, SCOPE_H - 1, 0);
  }
  
  // Erase old trace, draw new one
  for (int i = 0; i < SCREEN_W - 1; i++) {
    tft.drawLine(i, prevBuffer[i], i+1, prevBuffer[i+1], 0x0000);
    tft.drawLine(i, buffer[i], i+1, buffer[i+1], 0x07E0); // Green
    prevBuffer[i] = buffer[i];
  }
  prevBuffer[SCREEN_W-1] = buffer[SCREEN_W-1];
}

void drawGrid() {
  // Draw graticule lines
  for (int y = 0; y <= SCOPE_H; y += SCOPE_H/4)
    tft.drawFastHLine(0, y, SCREEN_W, 0x2104); // Dark grey
  for (int x = 0; x <= SCREEN_W; x += SCREEN_W/6)
    tft.drawFastVLine(x, 0, SCOPE_H, 0x2104);
}
Recommended: 2.4″ Inch Touch Screen TFT Display Shield for Arduino UNO MEGA — Plugs directly onto the Uno, includes touchscreen for future scope controls like timebase and voltage scaling.

Implementing Triggering for Stable Waveforms

Without triggering, your waveform will scroll and appear unstable. A trigger waits for the signal to cross a threshold in a specific direction before starting a capture, ensuring successive captures start at the same phase and the waveform appears stationary.

bool waitForTrigger(int threshold, bool risingEdge, unsigned long timeoutUs) {
  unsigned long start = micros();
  int prev = analogRead(INPUT_PIN);
  
  while (micros() - start < timeoutUs) {
    int current = analogRead(INPUT_PIN);
    if (risingEdge && prev < threshold && current >= threshold) return true;
    if (!risingEdge && prev > threshold && current <= threshold) return true;
    prev = current;
  }
  return false; // Timeout — draw anyway
}

// In loop():
if (!waitForTrigger(512, true, 50000)) {
  // No trigger in 50ms — display "!TRIG" on screen
}
// Now capture your samples

Set the trigger level to mid-scale (512 for a 0–5V signal centred at 2.5V) for most AC waveforms. Add touch input to adjust the trigger level and choose rising or falling edge for full scope control.

Input Protection and Voltage Dividers

The Arduino ADC input is rated for 0–5V (or 0–3.3V on 3.3V boards). Exceeding this destroys the ADC — and possibly the entire microcontroller. Always protect the input:

Basic Voltage Divider for ±20V Range

Use a resistor divider with clamping diodes. For a ±15V signal range on a 5V Arduino:

  • R1 = 100kΩ (input to junction)
  • R2 = 10kΩ (junction to GND)
  • This divides by 11, so ±15V input becomes ±1.36V at the ADC pin
  • Add 1N4148 diodes from the junction to 5V and GND for clamping
  • Add a 2.5V DC bias (via resistor divider from 5V) to centre the signal in the 0–5V ADC range

For high-voltage work (mains monitoring, automotive signals), use a dedicated front-end IC like the ACPL-C87A or a commercial probe attenuator, and never connect mains voltage directly to an Arduino under any circumstances.

Performance Tips and Limitations

  • Use direct register access instead of analogRead() — analogRead() takes ~104µs, direct ADC register reading takes ~13µs
  • Disable interrupts during sampling bursts to prevent timing jitter: noInterrupts(); /* sample loop */ interrupts();
  • Use DMA on RP2040 — the Nano RP2040 can use DMA to fill a sample buffer entirely in hardware, freeing the CPU for display rendering simultaneously
  • Pre-allocate buffers — dynamic memory allocation during sampling causes jitter and potential heap fragmentation
  • Acknowledge the bandwidth limit — publish the sample rate on-screen so users know what they’re looking at
Recommended: Arduino Mega 2560 R3 Board — More RAM (8KB vs 2KB on Uno) for deeper sample buffers, and more analog pins for a multi-channel scope.

Frequently Asked Questions

What is the maximum frequency an Arduino Uno oscilloscope can display?

At the default 9.6kSPS, the Nyquist limit is about 4.8kHz. With prescaler tuning to reach 77kSPS, you can display signals up to ~38kHz — though accuracy decreases. For anything above that, use the Nano RP2040 (500kSPS) or a dedicated scope.

Can an Arduino oscilloscope measure AC mains voltage?

Not directly and not safely. You would need a galvanically isolated front end. It is technically possible with an isolation transformer and a proper attenuator circuit, but the risk of electrocution from a mistake is severe. Use a proper isolated oscilloscope probe instead.

How do I increase the voltage range of my Arduino oscilloscope?

Use a resistor voltage divider with clamping diodes, as described in the input protection section. For signals above ±20V, use an op-amp attenuator circuit with a dedicated power supply. Always add clamp diodes to prevent over-voltage reaching the ADC pin.

What library should I use for the TFT display?

The Adafruit GFX library combined with the display-specific driver (MCUFRIEND_kbv for shields, Adafruit_ILI9341 for SPI modules) is the most well-documented choice. For maximum speed on AVR, consider the UTFT library which uses direct port manipulation.

Is there a ready-made Arduino oscilloscope I can buy?

Yes — the DSO138 and DSO150 are inexpensive dedicated scopes based on STM32 that offer 200kSPS and a proper analog front end. They cost more than a DIY Arduino project but significantly less than professional scopes and give much better performance.

Ready to build your own signal analyzer? Find all the Arduino boards, TFT displays, and components you need in our Arduino & Microcontrollers collection at Zbotic — with fast delivery across India.

Tags: ADC, Arduino, DIY, Electronics Project, Oscilloscope, Signal Analysis
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
ATtiny85 Microcontroller: Tiny...
blog attiny85 microcontroller tiny projects big results 594661
blog arduino finite state machine writing cleaner code for complex projects 594663
Arduino Finite State Machine: ...

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