Проект · Измерения · ADC
Карманный осциллограф из одного ADC-пина
Прибор за $300 нужен не всегда. Для «сигнал жив? какой размах? какая частота?» хватает собственного 12-битного ADC ESP32: burst-семплинг пина, три цикла математики — и Vpp, Vrms и частота читаются с живого дашборда. Это не Rigol — но настоящий измерительный инструмент размером со спичечный коробок.
Сначала: не спалить пин
ADC терпит 0–3.3 В и ничего больше. Реальные сигналы уходят в минус и стреляют пиками — поэтому входная обвязка важнее кода: разделительный конденсатор в резисторное смещение к середине питания (AC качается вокруг 1.65 В) и пара clamping-диодов на 3V3 и GND от всего неожиданного. И берите пин ADC1 (GPIO32–39) — ADC2 отключается, как только включается Wi-Fi.
Математика — три цикла, FFT не нужен
Для «что это за сигнал» time-domain математика бьёт FFT: min/max даёт Vpp, RMS без среднего — Vrms, а подсчёт восходящих переходов через ноль (после вычитания среднего) — частоту, устойчиво даже на шумной трассе:
// --- the scope maths: mean, Vpp, Vrms, zero-cross frequency ---
float mean = 0, mn = 99, mx = -99;
for (int i = 0; i < N; i++) { mean += buf[i]; if (buf[i] < mn) mn = buf[i]; if (buf[i] > mx) mx = buf[i]; }
mean /= N;
float sq = 0; int crossings = 0;
for (int i = 1; i < N; i++) {
float a = buf[i - 1] - mean, b = buf[i] - mean;
sq += b * b;
if (a < 0 && b >= 0) crossings++; // rising zero-crossings
}
vpp = mx - mn;
vrms = sqrtf(sq / (N - 1));
freq = crossings * SPS / N; // crossings per second Честно про sample rate: голый analogRead() даёт порядка 10 kSps — по
Найквисту это чисто до единиц кГц: сетевой фон, звук, сенсорные волны. Нужно больше? I2S/DMA-путь
ADC на ESP32 льёт 50 kSps+ мимо CPU — математика та же, буфер больше.
Дашборд
dash.layout("Scope", RICON_SIGNAL);
dash.stat("Frequency", &freq, "Hz");
dash.stat("Vpp", &vpp, "V");
dash.stat("Vrms", &vrms, "V");
dash.chart("Signal level", &level, "V"); // the live "screen"
dash.beginAP("RisalDash-Scope", "12345678");
// acquire a burst — real board:
// for (int i = 0; i < N; i++) buf[i] = analogRead(PIN) * 3.3f / 4095.0f; Пример из библиотеки (examples/04_Templates/Oscilloscope) работает на
синтетическом синусе 45–55 Гц с шумом — счётчик частоты отслеживает дрейф ещё до
подключения проводов; потом демо-цикл меняется на analogRead(). Добавьте делитель из
гайда по батареям — тот же пин меряет и DC-шины.
Для чего он честно годится
| Задача | Вердикт |
|---|---|
| Жив ли сенсор/генератор? | ✅ идеально |
| Сетевой фон, звуковой диапазон | ✅ чистые измерения |
| PWM: скважность и частота до ~5 кГц | ✅ работает |
| МГц-шины, микросекундные фронты | ❌ нужен логический анализатор / настоящий скоп |
Посмотрите, как математика ловит дрейфующий сигнал, ещё до проводов.