RisalDash RisalDash

Проект · Измерения · ADC

Карманный осциллограф из одного ADC-пина

Прибор за $300 нужен не всегда. Для «сигнал жив? какой размах? какая частота?» хватает собственного 12-битного ADC ESP32: burst-семплинг пина, три цикла математики — и Vpp, Vrms и частота читаются с живого дашборда. Это не Rigol — но настоящий измерительный инструмент размером со спичечный коробок.

ПроектИзмеренияADCESP32
Проект осциллографа на ESP32: Vpp, Vrms и частота на одном ADC-пине

Сначала: не спалить пин

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 кГц✅ работает
МГц-шины, микросекундные фронты❌ нужен логический анализатор / настоящий скоп

Посмотрите, как математика ловит дрейфующий сигнал, ещё до проводов.