An Arduino serial oscilloscope leverages the microcontroller's Analog-to-Digital Converter (ADC) and serial communication to plot voltage over time via the Arduino IDE Serial Plotter or third-party tools like SerialPlot. Here is the direct answer on its capabilities: it provides a 10-bit resolution (0-1023) and a maximum practical sampling rate of ~9 kHz on an ATmega328P (Uno/Nano). It is strictly a low-frequency diagnostic tool for DC, audio, and slow sensor ramps. It will not capture high-speed digital edges or RF signals, but it saves you from dragging a bench DSO to the workbench for basic 50Hz to 1kHz signal verification.
Meter Setup Block: Configuring the Arduino ADC
When using a microcontroller as a measurement tool, we must map traditional multimeter concepts to software and pin configurations. Here is your setup block before taking any readings.
Dial Position (Sample Rate & Baud)
On a DMM, the dial selects the function and range. On an Arduino serial oscilloscope, your 'dial' is the baud rate and the ADC clock prescaler. To achieve the maximum ~9,615 samples per second on an ATmega328P, you must set your serial baud rate to 115200 or higher in both the firmware and the Serial Plotter dropdown. If you leave the plotter at 9600 baud, your effective sample rate bottlenecks to roughly 800 Hz, severely limiting your bandwidth.
Lead Jacks (Analog Pins & Ground)
Your 'lead jacks' are the analog input pins (A0 through A5 on the Uno/Nano) and the GND pins. Unlike a bench oscilloscope with BNC connectors and 10MΩ input impedance, the Arduino ADC pins have an input impedance of roughly 100MΩ but rely on an internal sample-and-hold capacitor. You must connect your signal ground to the Arduino GND to establish a common reference; probing a floating signal without a shared ground will yield chaotic, noisy readings.
Range (Voltage Reference)
The 'range' setting dictates the maximum voltage the ADC can read before clipping (pegging at 1023). You control this via the analogReference() function. The DEFAULT setting uses the board's VCC (5V on a standard Uno, 3.3V on a 3.3V Pro Mini). The INTERNAL setting switches to the on-chip 1.1V bandgap reference, giving you much finer resolution for low-voltage signals like thermocouple outputs or shunt resistor drops.
| Signal Type | Arduino Range Setting | Expected Numerical Reading | True Voltage |
|---|---|---|---|
| 3.3V LDO Output | DEFAULT (5.0V VCC) | 675 - 677 | 3.30V |
| 1.5V AA Battery | INTERNAL (1.1V Ref) | 1023 (Clipped/Over-range) | 1.50V |
| 0.5V Shunt Drop | INTERNAL (1.1V Ref) | 465 - 467 | 0.50V |
| 2.5V PWM (Filtered) | DEFAULT (5.0V VCC) | 511 - 513 | 2.50V |
Probe Placement and Safety: CAT Ratings and Isolation
Before clipping probes to your circuit, you must understand the safety boundaries of microcontroller-based measurement. An Arduino is strictly a non-CAT (or at best, CAT I) device. It is designed for low-voltage, low-energy DC environments (under 30VDC).
Never connect an Arduino serial oscilloscope directly to mains voltage (120V/230V AC) or any circuit lacking galvanic isolation from the grid. The ATmega328P die will instantly vaporize, and the high voltage will travel backward through the USB ground line directly into your computer's motherboard, potentially causing a fire or lethal shock. For measuring mains-adjacent circuits (like a TRIAC dimmer output), you must use a properly rated bench oscilloscope with CAT II/III probes, or use an isolated ADC front-end like the ISO124 or a digital isolator chip. Always defer to Fluke's guide on measurement categories to understand why CAT ratings matter for transient overvoltages.
Probe Placement Procedure:
- Establish Common Ground: Connect a jumper wire from the Arduino GND pin to the ground rail of your breadboard or the ground terminal of your device under test (DUT). If the DUT is powered by a separate wall-wart, ensure the grounds are tied together.
- Signal Probe: Connect your signal wire to A0. Keep this wire as short as possible (under 3 inches) to prevent it from acting as an antenna for 50/60Hz mains hum.
- Verify Dead: If you are unsure of the voltage present, use a standard CAT-rated digital multimeter to verify the voltage is under 5V DC before connecting it to the Arduino's A0 pin.
Expected Readings: Good vs. Bad Values
What does a good reading look like numerically? If you feed a highly stable 2.500V DC reference into A0 of a 5V Arduino Uno using the DEFAULT reference, a good reading is a flat line oscillating only between 511 and 512. The ADC formula is Reading = (Vin / Vref) * 1023. Therefore, (2.5 / 5.0) * 1023 = 511.5. Because the ADC truncates decimals, you will see 511 and 512 alternating due to inherent thermal noise and quantization error.
Below is a diagnostic table for interpreting your Serial Plotter output.
| Symptom on Serial Plotter | Measured Value | Expected Value | Root Cause & Fix |
|---|---|---|---|
| Erratic, wide-band noise (±50 counts) | 450 to 550 | 511 (for 2.5V) | Floating ground or high-impedance source. Tie grounds together and add a 0.1µF bypass cap at A0. |
| Flatlined at maximum | 1023 | 716 (for 3.5V) | Signal exceeds Vref. Switch to a voltage divider or change analogReference() if applicable. |
| Reading is consistently 10% low | 460 | 511 (for 2.5V) | Source impedance is too high (>10kΩ). The internal sample-and-hold cap isn't charging fully. Add an op-amp buffer. |
| Perfect sine wave, but wrong frequency | 20Hz displayed | 10kHz actual | Aliasing. Your sample rate is lower than the signal frequency. See the Nyquist mistake below. |
Mistakes That Give Misleading Readings
Using an Arduino ADC as an oscilloscope introduces specific failure modes that a bench DSO automatically compensates for. Avoid these three critical mistakes to ensure your data is valid.
1. Ignoring the Nyquist Limit (Aliasing)
The Nyquist-Shannon sampling theorem dictates that your sample rate must be at least twice the highest frequency component of your signal. The Arduino Uno maxes out at roughly 9 kHz. If you attempt to measure an 8 kHz sine wave, the plotter won't show a flat line or an error; it will display a mathematically aliased 1 kHz wave. Rule of thumb: Never trust an Arduino serial oscilloscope for signals above 2 kHz. For PWM signals (which contain high-frequency harmonics), use a low-pass RC filter (e.g., 1kΩ resistor and 0.1µF capacitor) on A0 to smooth the PWM into a DC average before measuring.
2. High Source Impedance Errors
The ATmega328P datasheet specifies that the ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less. When the ADC takes a reading, it briefly connects the input pin to an internal 14pF sample-and-hold capacitor. If your signal source has a high impedance (like a 100kΩ thermistor voltage divider), the capacitor cannot charge fully within the 1.5 ADC clock cycles allocated for sampling. The result is a reading that is artificially lower than the actual voltage. Fix: Add a 100nF ceramic capacitor between A0 and GND to act as an external charge reservoir, or buffer the signal with an LM358 op-amp configured as a voltage follower.
3. ESP32 ADC Non-Linearity
If you upgrade from an Uno to an ESP32 for your serial oscilloscope, you gain a 12-bit ADC (0-4095) and built-in WiFi, but you inherit a notorious hardware flaw: the ESP32's ADC is highly non-linear near the 0 and 4095 extremes, and it suffers from significant noise. A 3.2V input might read as 3.1V, and a 0.1V input might read as 0.15V. Fix: Never use the ESP32 ADC for precision metrology without implementing software calibration using the esp_adc_cal library, or restrict your measurements to the linear middle-band (0.5V to 2.8V) using the 11dB attenuation setting.






