RisalDash RisalDash

مشروع · قياسات · ADC

راسم جيب من طرف ADC واحد

لا تحتاج دائمًا جهازًا بثلاثمئة دولار. لسؤال «هل الإشارة حيّة؟ كم حجمها؟ ما تردّدها؟» يجيب ADC الـ 12-بت في ESP32 عن الثلاثة: عيّن الطرف دفعاتٍ، ونفّذ ثلاث حلقات رياضيّات، واقرأ Vpp وVrms والتردّد من لوحة حيّة. ليس Rigol — لكنّه أداة قياس حقيقيّة بحجم علبة كبريت.

مشروعقياساتADCESP32
مشروع راسم إشارة بـ ESP32: قياس Vpp وVrms والتردّد بطرف ADC واحد

أوّلًا: لا تحرق الطرف

يتحمّل ADC 0–3.3 V ولا شيء غيرها. إشارات الواقع تهبط تحت الصفر وتقفز — فواجهة الدخل أهمّ من الكود: مكثّف ربط إلى انحياز منتصف الجهد بمقاومتين (فيتأرجح AC حول 1.65 V)، وزوج ديودات كبح إلى 3V3 وGND لكلّ ما هو غير متوقّع. واستخدم طرف ADC1 (GPIO32–39) — إذ يتوقّف ADC2 لحظة تشغيل Wi-Fi.

الرياضيّات — ثلاث حلقات بلا FFT

لسؤال «ما هذه الإشارة» تتفوّق رياضيّات المجال الزمنيّ على 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

صدقًا عن معدّل العيّنات: يبلغ analogRead() العاديّ نحو 10 kSps — أي نظافة حتّى بضعة kHz وفق نايكويست: همهمة الكهرباء والصوت وموجات الحسّاسات. تريد أكثر؟ مسار I2S/DMA في ESP32 يتدفّق 50 kSps+ دون أن يلمس المعالج كلّ عيّنة — الرياضيّات نفسها ومخزن أكبر.

اللوحة

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 Hz مع ضجيج — فترى عدّاد التردّد يتتبّع الانجراف قبل توصيل أيّ سلك؛ ثمّ تستبدل حلقة العرض بـ analogRead(). أضِف مقسّم دليل البطاريّات فيقيس الطرف نفسه خطوط DC أيضًا.

ما يصلح له بصدق

المهمّةالحكم
هل الحسّاس/المذبذب حيّ؟✅ مثاليّ
همهمة الكهرباء، مدى الصوت✅ قياسات نظيفة
PWM: الدورة والتردّد حتّى ~5 kHz✅ يعمل
نواقل MHz وحوافّ ميكروثانية❌ محلّل منطقيّ / راسم حقيقيّ

شاهد الرياضيّات تتتبّع إشارةً منجرفة قبل توصيل أيّ شيء.