الحسّاسات والمشغّلات للمتحكّمات · الفصل 4 — المداخل التماثلية وملاءمة الإشارةמבואות תקביליים והתאמת אותות · 33.102⌂📚🏠
الفصل 4

المداخل التماثلية وملاءمة الإشارة

מבואות תקביליים והתאמת אותות
الصفّان الحادي عشر والثاني عشر · 6 ساعات تعليمية

معظم الكمّيات في العالم الحقيقي تماثلية: الحرارة، الضوء، الضغط والجهد تتغير بشكل مستمر. المتحكّم لا يفهم إلا الأعداد، ولذلك يحوّل الجهد في مدخله التماثلي إلى عدد صحيح. في هذا الفصل نتعرّف على المحوّل التماثلي-الرقمي، نقرأ مدخلا تماثليا في البرنامج، نحوّل مقاومة الحسّاس إلى جهد بمُجزِّء الجهد، نخفّف الضجيج بالمتوسّط في البرنامج، وفي النهاية نحوّل القراءة إلى وحدات يفهمها المستخدم، مثل °C و cm.

في نهاية هذا الفصل سنعرف أن:
  • نشرح أخذ العيّنات والتكميم، ونحسب Nmax ودقّة التمييز للوحة Uno وللوحة ESP32.
  • نحوّل القيمة الخام إلى جهد بالصيغة V = N·VrefNmax وبالعكس، ونتجنّب أخطاء الحساب بالأعداد الصحيحة.
  • نوصل حسّاسا مقاوما في مُجزِّء جهد ونختار له مقاومة ثابتة ملائمة.
  • نصغّر جهدا أكبر من جهد المرجع بمُجزِّء جهد قبل أن نقرأه.
  • نخفّف الضجيج بحساب متوسّط عدّة قراءات في البرنامج.
  • نحوّل القراءة إلى وحدات هندسية حسب مدى الحسّاس في ورقة البيانات، بالتناسب أو بالدالة map().
  • نقارن بين Uno و ESP32 والراسبيري باي: المحوّل ومدى القيم ودقّة التمييز، ونقرأ حسّاسا في الراسبيري باي ببايثون.

הממיר התקבילי-ספרתי – المحوّل التماثلي-الرقمي (Analog-to-Digital Converter)

الحسّاس التماثلي يعطي جهدا يمكن أن يأخذ أي قيمة داخل مداه، مثلا 1.37 V أو 1.3712 V. أما المتحكّم فيعمل بالأعداد الثنائية فقط. الجسر بينهما هو وحدة داخل المتحكّم تُسمّى المحوّل التماثلي-الرقمي.

المحوّل التماثلي-الرقمي (ממיר תקבילי-ספרתי, ADC): هو دائرة تقيس الجهد في مدخلها وتعطي عددا صحيحا يتناسب معه. هذا العدد يُسمّى القيمة الخام (ערך גולמי) ونرمز له بالحرف N.

يعمل المحوّل بخطوتين:

01.252.53.755tVالإشارة التماثليةالقيمة بعد التكميم
أخذ العيّنات والتكميم في محوّل من 3 بتات: الإشارة (أزرق)، العيّنات (نقاط) والقيمة بعد التكميم (أحمر)
1234501234567VN0.625 V
المنحنى المميّز لمحوّل من 3 بتات و Vref = 5 V : ثماني درجات، عرض كل درجة 0.625 V

عدد البتات وجهد المرجع ودقّة التمييز – מספר סיביות, מתח ייחוס והפרדה:

عدد الدرجات يحدّده عدد البتات n (מספר סיביות): محوّل من n بتات يعطي 2n قيمة، من 0 حتى Nmax. أكبر جهد يقيسه المحوّل هو جهد المرجع Vref (מתח ייחוס)، والمسافة بين درجتين متجاورتين هي دقّة التمييز (רזולוציה, הפרדה): أصغر تغيّر في الجهد يميّزه المحوّل. القيمة الخام تتناسب مع الجهد: 0 V يعطي N = 0 ، و Vref يعطي N = Nmax.

المحوّل التماثلي-الرقمي · ממיר תקבילי-ספרתי
Nmax = 2n − 1
Δ V = Vref2n
V = N·VrefNmax
الرمزالمعنىوحدة القياس
n , Nعدد بتات المحوّل · القيمة الخام (من 0 حتى Nmax)—
V , Vrefالجهد في المدخل · جهد المرجع (أكبر جهد يقيسه المحوّل)[V]
Δ Vدقّة التمييز: عرض درجة واحدة[V]
اللوحةnNmaxVrefدقّة التمييز Δ V
Arduino Uno (ATmega328P)1010235 V4.88 mV
ESP321240953.3 V0.806 mV

لحساب القيمة الخام المتوقّعة لجهد معيّن نعكس الصيغة: N = V·NmaxVref ، ونأخذ الجزء الصحيح. ورقة بيانات ATmega328P تكتب 2n في المقام بدل Nmax ؛ الفرق لا يتعدّى قيمة خام واحدة، ونستعمل في الكتاب Nmax لأنه يعطي Vref بالضبط عند Nmax.

مثال 4.1
لوحة Uno تقرأ N = 614.
(أ) ما هو الجهد في المدخل؟
(ب) ما هي القيمة الخام التي نتوقّعها لجهد 1.2 V ؟
الحل:

(أ) نعوّض في الصيغة:

V = N·VrefNmax = 614·51023 = 3.001 V

(ب) نعكس الصيغة ونأخذ الجزء الصحيح:

N = V·NmaxVref = 1.2·10235 = 245.52 → N = 245
V = 3.001 V , N = 245
سؤال 4.1: حسّاس موصول بلوحة ESP32 يعطي 1.65 V. ما هي القيمة الخام التي نتوقّعها؟ وما هو الجهد إذا قرأنا N = 1000 ؟
ESP32: دقّة تمييز ESP32 أصغر بنحو 6.1 مرات من Uno. لكن محوّله غير خطّي قرب طرفي مداه (قرب 0 V وقرب الحد الأعلى)، ولذلك نفضّل العمل في وسط المدى. وأطراف ADC2 فيه لا تعمل عندما تكون شبكة WiFi مفعّلة، فنستعمل في مشاريع الشبكة أطراف ADC1 (من GPIO32 حتى GPIO39). أطراف ESP32 تعمل بجهد 3.3 V ولا تتحمّل 5 V.

تغيير جهد المرجع: في لوحة Uno نختار المرجع بالأمر analogReference(): DEFAULT يعني 5 V ، و INTERNAL مرجع داخلي 1.1 V (قيمة نموذجية حسب ورقة البيانات)، و EXTERNAL الجهد الموصول بالطرف AREF. مع 1.1 V تصبح Δ V = 1.11024 = 1.07 mV ، وهذا مفيد لحسّاس جهده صغير، لكن كل جهد فوق 1.1 V يُقرأ 1023.

تحذير: لا نوصل بالطرف AREF جهدا أقل من 0 V أو أكبر من 5 V ، ومع مرجع خارجي نكتب analogReference(EXTERNAL) قبل أول analogRead() وإلا قد يتلف المتحكّم. بعد تغيير المرجع نتجاهل القراءات الأولى لأنها غير دقيقة.

קריאת מבוא תקבילי בתוכנית – قراءة مدخل تماثلي في البرنامج (analogRead)

10k

في لوحة Uno ستة مداخل تماثلية، من A0 حتى A5. الأمر analogRead(A0) يُرجع القيمة الخام بين 0 و 1023. لا نحتاج إلى pinMode() للقراءة التماثلية. نبدأ بأبسط حسّاس تماثلي: المقاومة المتغيّرة (البوتنشيومتر)، وهي مُجزِّء جهد نغيّر نسبته باليد.

Arduino Uno5VA0GND10 kΩPOT
بوتنشيومتر 10 kΩ : الطرفان إلى 5V و GND ، والزالق إلى المدخل A0

الدالة map() وفخّ الأعداد الصحيحة – הפונקציה map() ומלכודת המספרים השלמים:

الدالة map(x, inMin, inMax, outMin, outMax) تنقل عددا من مدى إلى مدى آخر بخط مستقيم. لكنها تحسب بأعداد صحيحة فقط وتحذف الكسر (لا تقرّب)، ولذلك هي ملائمة للنسبة المئوية أو للزاوية، وغير ملائمة عندما نحتاج إلى كسور. البرنامج التالي يقرأ البوتنشيومتر ويحسب الجهد بثلاث طرق:

قراءة البوتنشيومتر: map() مقابل الحساب العشري Arduino Uno · pot_read.ino
const int POT = A0;

void setup() { Serial.begin(9600); }

void loop() {
  int n = analogRead(POT);                // 0..1023
  long vMap = map(n, 0, 1023, 0, 5);      // whole volts only
  long mV = map(n, 0, 1023, 0, 5000);     // millivolts, integer
  float v = n * 5.0 / 1023.0;             // float math
  Serial.print("N = ");       Serial.print(n);
  Serial.print("  map V = "); Serial.print(vMap);
  Serial.print("  mV = ");    Serial.print(mV);
  Serial.print("  V = ");     Serial.println(v, 3);
  delay(500);
}
Serial Monitor · قراءة نموذجية
N = 0  map V = 0  mV = 0  V = 0.000
N = 100  map V = 0  mV = 488  V = 0.489
N = 511  map V = 2  mV = 2497  V = 2.498
N = 1000  map V = 4  mV = 4887  V = 4.888
N = 1023  map V = 5  mV = 5000  V = 5.000

في السطر N = 1000 تُرجع map(n, 0, 1023, 0, 5) العدد 4 ، والجهد الحقيقي 4.888 V : خطأ 0.89 V ، أي نحو 18% من المدى! الحساب الصحيح هو السطر n * 5.0 / 1023.0: النقطة العشرية تجعل الحساب بأعداد float. لو كتبنا n * 5 / 1023 لكانت النتيجة أعدادا صحيحة من 0 حتى 5 فقط.

خطأ شائع: في لوحة Uno المتغيّر int يتّسع لأعداد حتى 32767 فقط. الحساب n * 5000 بمتغيّر int يتجاوز هذا الحد (مثلا 512·5000 = 2,560,000) فيفيض ونحصل على عدد لا معنى له. الحل: نكتب 5000L (الحرف L يعني long)، أو نحسب بأعداد float.
سؤال 4.2: ماذا تُرجع map(n, 0, 1023, 0, 100) عندما N = 700 ؟ وما هي النسبة المئوية الدقيقة؟
على اللوحات الثلاث: Uno: طرفا البوتنشيومتر إلى 5 V و GND. ESP32: الطرفان إلى 3.3 V لا إلى 5 V ، والزالق إلى طرف بين GPIO32 و GPIO39. الراسبيري باي: فقط عبر محوّل خارجي مثل MCP3008 (البند 4.6).
▶تجربة حية — البوتنشيومتر والمدخل التماثلينحرّك الزالق ونرى الجهد والقيمة الخام والقراءة في الشاشة التسلسلية معا.
⚠
المختبر غير متاح الآن. المادة في هذا الفصل كاملة من دونه — نواصل القراءة، ونعود إلى التجربة لاحقا أو نفتحها مباشرة من الرابط الذي تحت الإطار.
https://fahed-lab.com/micro/sensors_guide#pot
نفتح المختبر في صفحة مستقلة ↗ fahed-lab.com/micro/sensors_guide#pot

חיישן התנגדותי במחלק מתח – الحسّاس المقاوم في مُجزِّء الجهد (Resistive Sensor in a Divider)

حسّاسات كثيرة تغيّر مقاومتها وليس جهدها: المقاومة الحرارية (NTC)، المقاومة الضوئية (LDR)، وحسّاس الانحناء. المحوّل يقيس جهدا فقط، ولذلك نحوّل المقاومة إلى جهد بأبسط دائرة: مُجزِّء الجهد. تحويل إشارة الحسّاس إلى جهد يلائم مدخل المتحكّم يُسمّى ملاءمة الإشارة (התאמת אותות).

مُجزِّء الجهد (מחלק מתח): مقاومتان على التوالي بين VCC والأرضي؛ الجهد في نقطة الوصل بينهما جزء من VCC يتعلّق بنسبة المقاومتين، وإذا كانت إحداهما حسّاسا يتغيّر الجهد مع الكمّية المقيسة.
مُجزِّء الجهد مع حسّاس مقاوم في الأسفل · מחלק מתח
Vout = VCC·RSRF + RS
الرمزالمعنىوحدة القياس
Voutالجهد في نقطة الوصل، إلى المدخل التماثلي[V]
RS , RFمقاومة الحسّاس (في الأسفل) · المقاومة الثابتة (في الأعلى)[Ω]
Arduino Uno5VA0GNDNTCRF10 kΩRSVout
مقاومة حرارية NTC في أسفل مُجزِّء الجهد، ومقاومة ثابتة RF = 10 kΩ في أعلاه، ونقطة الوصل إلى A0

كيف نختار المقاومة الثابتة؟ قاعدة عملية: نختار RF قريبة من مقاومة الحسّاس في منتصف مدى القياس. هكذا يتغيّر Vout بأكبر قدر تقريبا، ولا يلتصق بـ 0 V أو بـ 5 V. لذلك نصل المقاومة الحرارية «10 kΩ» (هذه مقاومتها في 25 °C) بمقاومة ثابتة 10 kΩ.

مثال 4.2
مقاومة المقاومة الحرارية في الشكل 10 kΩ في 25 °C ، ونحو 3.6 kΩ في 50 °C (قيمة نموذجية حسب ورقة البيانات). نحسب Vout والقيمة الخام في Uno في الحرارتين.
الحل:
V25°C = 5·1010 + 10 = 2.5 V → N = 511
V50°C = 5·3.610 + 3.6 = 1.32 V → N = 270

ارتفعت الحرارة فصغرت مقاومة NTC ، ولذلك صغر الجهد وصغرت القيمة الخام.

V25°C = 2.5 V , V50°C = 1.32 V

البرنامج التالي يقرأ A0 ، يحسب الجهد كما في البند 4.2، ثم يحسب منه مقاومة الحسّاس. السطر الذي يحسب rs هو قانون مُجزِّء الجهد بعد أن نعزل منه RS. إذا قرأ المحوّل 1023 فالأرجح أن الحسّاس مفصول.

حساب مقاومة الحسّاس من القراءة Arduino Uno · divider_rs.ino
const int SENSOR = A0;
const float VCC = 5.0;
const float R_FIXED = 10000.0;    // ohm, top resistor

void setup() { Serial.begin(9600); }

void loop() {
  int n = analogRead(SENSOR);
  if (n >= 1023) {
    Serial.println("sensor open?");
  } else {
    float v = n * VCC / 1023.0;
    float rs = R_FIXED * v / (VCC - v);   // sensor at the bottom
    Serial.print("N = ");   Serial.print(n);
    Serial.print("  V = "); Serial.print(v, 2);
    Serial.print("  Rs = "); Serial.print(rs / 1000.0, 2);
    Serial.println(" kOhm");
  }
  delay(1000);
}
Serial Monitor · قراءة نموذجية
N = 788  V = 3.85  Rs = 33.53 kOhm
N = 511  V = 2.50  Rs = 9.98 kOhm
N = 270  V = 1.32  Rs = 3.59 kOhm

الأسطر الثلاثة تقابل المقاومة الحرارية في 0 °C ، 25 °C و 50 °C. القيمة المحسوبة قريبة جدا من المقاومة الحقيقية؛ الفرق الصغير سببه التكميم. نتعرّف على المقاومة الحرارية أكثر في الفصل 5.

تصغير جهد كبير بمُجزِّء الجهد – הקטנת מתח גבוה במחלק מתח:

لقياس جهد أكبر من Vref ، مثلا مُركِّم 12 V ، نصغّره بمُجزِّء جهد حتى لا يتجاوز 5 V في أسوأ الحالات. مع R1 = 22 kΩ و R2 = 10 kΩ نحسب النسبة وأكبر جهد نستطيع قياسه:

R2R1 + R2 = 1022 + 10 = 0.3125
Vbat,max = 50.3125 = 16 V
Arduino UnoA0GND+−R122 kΩR210 kΩVbat
قياس جهد مُركِّم بمُجزِّء جهد: R1 = 22 kΩ ، R2 = 10 kΩ. الأرضي مشترك بين المُركِّم واللوحة
مثال 4.3
المُركِّم في الدائرة مشحون إلى 12.6 V. ما هو الجهد في A0 ، وما هي القيمة الخام؟
الحل:
VA0 = Vbat·R2R1 + R2 = 12.6·1022 + 10 = 3.9375 V
N = 3.9375·10235 = 805.6 → N = 805
VA0 = 3.938 V , N = 805

في البرنامج نحسب الجهد v في A0 كما في البند 4.2، ثم «نُلغي» مُجزِّء الجهد بالضرب في R1 + R2R2 :

float vBat = v * (22.0 + 10.0) / 10.0;   // volts at the battery
ملاحظة: نختار مقاومات بين بضعة كيلو أوم وبضع عشرات الكيلو أوم: المقاومات الصغيرة جدا تستهلك تيار المُركِّم بلا فائدة، والكبيرة جدا (ميغا أوم) تجعل قراءة المحوّل غير دقيقة.
تحذير: مُجزِّء الجهد لا يصلح أبدا لقياس جهد الشبكة 230 V : قياس الشبكة فقط بوحدة قياس معزولة ومُعتمدة وبإشراف المعلّم (الفصل 9). وقبل التوصيل نتأكّد بالحساب أن أكبر جهد ممكن للمصدر لا يرفع المدخل فوق 5 V.
سؤال 4.3: ما هو الجهد في A0 والقيمة الخام في دائرة المُركِّم إذا انخفض جهده إلى 9 V ؟

רעש ומיצוע בתוכנה – الضجيج والمتوسّط في البرنامج (Noise and Averaging)

حتى عندما لا تتغيّر الكمّية المقيسة، تقفز القيمة الخام بضع درجات إلى الأعلى والأسفل. هذا هو الضجيج (רעש): إشارات غير مرغوب فيها تأتي من أسلاك طويلة، من محرّكات قريبة، من شبكة 50 Hz ، ومن المحوّل نفسه. تقليل الضجيج يُسمّى الترشيح (סינון). أبسط ترشيح نكتبه في البرنامج: نقرأ المدخل عدّة مرات متتالية ونحسب المتوسّط. الضجيج عشوائي، فيه قيم فوق القيمة الحقيقية وقيم تحتها، ولذلك يُلغي بعضها بعضا في المجموع.

متوسّط ثماني قراءات Arduino Uno · average8.ino
const int SENSOR = A0;
const int COUNT = 8;

void setup() { Serial.begin(9600); }

void loop() {
  int raw = analogRead(SENSOR);         // one single reading
  long sum = raw;
  for (int i = 1; i < COUNT; i++) {
    sum += analogRead(SENSOR);
  }
  float avg = sum / (float)COUNT;       // average of 8 readings
  Serial.print("raw = ");    Serial.print(raw);
  Serial.print("  avg = ");  Serial.println(avg, 1);
  delay(500);
}
Serial Monitor · قراءة نموذجية
raw = 516  avg = 511.4
raw = 522  avg = 513.1
raw = 506  avg = 511.9
raw = 519  avg = 511.6
raw = 524  avg = 513.5

في هذه التجربة جهد ثابت يعطي N = 512. القراءات المفردة تتراوح بين 500 و 524 بسبب الضجيج، أما المتوسّطات فتبقى بين 511.4 و 513.5 فقط. الثمن: كل نتيجة تحتاج إلى ثماني قراءات. لحسّاس حرارة بطيء نستطيع أن نجمع قراءات كثيرة؛ لزرّ أو لحسّاس حماية سريع نجمع قراءات قليلة.

سؤال 4.4: نحسب متوسّط 16 قراءة، وكل قراءة في Uno تستغرق نحو 100 µs (البند 4.1). كم من الوقت تحتاج نتيجة واحدة؟
▶تجربة حية — معالجة الإشارةنضيف ضجيجا إلى إشارة الحسّاس ونقارن بين الإشارة الخام والإشارة بعد الترشيح والمتوسّط.
⚠
المختبر غير متاح الآن. المادة في هذا الفصل كاملة من دونه — نواصل القراءة، ونعود إلى التجربة لاحقا أو نفتحها مباشرة من الرابط الذي تحت الإطار.
https://fahed-lab.com/hashmal/sensors#signal
نفتح المختبر في صفحة مستقلة ↗ fahed-lab.com/hashmal/sensors#signal

המרה ליחידות הנדסיות – التحويل إلى وحدات هندسية (Converting to Engineering Units)

القيمة الخام N لا تعني شيئا للمستخدم. نريد أن نعرض وحدات هندسية (יחידות הנדסיות): °C ، cm ، bar. ورقة بيانات الحسّاس تعطي مدى القياس والجهد الذي يقابله: أصغر قيمة في المدى تعطي أصغر جهد، وأكبر قيمة تعطي أكبر جهد. في الحسّاس الخطّي العلاقة بينهما خط مستقيم، ولذلك يكفي تناسب بسيط. الطريق كله ثلاث خطوات:

  1. نقرأ القيمة الخام N بالأمر analogRead().
  2. نحوّل القيمة الخام إلى جهد: V = N·VrefNmax (البند 4.1).
  3. نحوّل الجهد إلى الكمّية المقيسة بالتناسب، حسب ورقة البيانات.
مثال 4.4
حسّاس الحرارة LM35 يُخرج 10 mV لكل 1 °C (قيمة نموذجية حسب ورقة البيانات): 0 V في 0 °C ، و 1 V في 100 °C. لوحة Uno تقرأ N = 62. ما هي الحرارة؟
الحل:

نحوّل القيمة الخام إلى جهد، ثم الجهد إلى درجات بالتناسب:

V = N·VrefNmax = 62·51023 = 0.303 V = 303 mV
T = 303 mV10 mV/°C = 30.3 °C
T = 30.3 °C

التحويل بالدالة map() – המרה בעזרת map():

عندما يقابل مدى الحسّاس كل مدى المحوّل، أي من 0 V حتى 5 V ، يكفي سطر واحد بالدالة map(): نكتب فيها القيمة الخام، ثم مدى المحوّل (0 و 1023)، ثم أصغر قيمة وأكبر قيمة في مدى الحسّاس. مثال: حسّاس مستوى تماثلي يُخرج 0 V والخزان فارغ، و 5 V عندما يصل الماء إلى 200 cm (هذا مثال للتوضيح؛ المدى الحقيقي نقرؤه في ورقة بيانات الحسّاس). البرنامج يحسب الارتفاع ونسبة الامتلاء:

من القيمة الخام إلى سنتيمتر وإلى نسبة مئوية بالدالة map() Arduino Uno · level_map.ino
const int LEVEL = A0;
const int H_MAX = 200;      // cm at 5 V, from the datasheet

void setup() { Serial.begin(9600); }

void loop() {
  int n = analogRead(LEVEL);
  long h = map(n, 0, 1023, 0, H_MAX);       // whole cm
  long fill = map(n, 0, 1023, 0, 100);      // percent
  Serial.print("N = ");    Serial.print(n);
  Serial.print("  h = ");  Serial.print(h);
  Serial.print(" cm  fill = "); Serial.print(fill);
  Serial.println(" %");
  delay(1000);
}
Serial Monitor · قراءة نموذجية
N = 0  h = 0 cm  fill = 0 %
N = 256  h = 50 cm  fill = 25 %
N = 512  h = 100 cm  fill = 50 %
N = 1023  h = 200 cm  fill = 100 %
200400600800100050100150200Nh [cm]0–5 V1–5 V
التحويل خط مستقيم: الخط الأزرق لحسّاس خرجه من 0 V حتى 5 V ، والمتقطّع لحسّاس خرجه من 1 V حتى 5 V لنفس المدى

إذا كان خرج الحسّاس من 1 V حتى 5 V لنفس المدى، نكتب في map() بدل الصفر القيمة الخام لجهد 1 V ، وهي N = 204 (الخط المتقطّع في الرسم):

long h = map(n, 204, 1023, 0, H_MAX);   // sensor output 1..5 V
خطأ شائع: الدالة map() تحذف الكسر (البند 4.2): هي ملائمة للسنتيمتر الكامل وللنسبة المئوية، لكن لقيمة مثل 30.3 °C نحسب بالتناسب بأعداد float كما في مثال LM35.
سؤال 4.5: حسّاس ضغط يُخرج من 0 V حتى 5 V لمدى من 0 حتى 6 bar. لوحة Uno تقرأ N = 600.
(أ) ماذا تُرجع map(n, 0, 1023, 0, 6) ؟
(ب) ما هو الضغط الدقيق؟

שלושה לוחות, שלושה ממירים – ثلاث لوحات، ثلاثة محوّلات (Uno, ESP32 and Raspberry Pi)

الحسّاس نفسه يتّصل بثلاث لوحات شائعة في المختبر: Arduino Uno و ESP32 والراسبيري باي (רספברי פיי). اللوحة تحدّد ثلاثة أمور: أيّ جهد مسموح على الطرف، وهل يوجد محوّل تماثلي-رقمي أصلا، وكم بتّا فيه. والفرق الأكبر: الراسبيري باي لا يحتوي على محوّل تماثلي-رقمي في أيّ طراز، ولذلك يقرأ الحسّاس التماثلي فقط عبر محوّل خارجي، مثل الدائرة المتكاملة MCP3008 (عشرة بتات، ثماني قنوات، تتّصل بناقل SPI).

Arduino UnoESP32Raspberry Pi
جهد الأطراف5 V3.3 V — لا يتحمّل 5 V3.3 V — لا يتحمّل 5 V
المحوّل التماثلي-الرقميمدمج، 10 بتاتمدمج، 12 بتّاغير موجود — فقط MCP3008 خارجي (10 بتات)
مدى القيم الخام0 حتى 10230 حتى 40950 حتى 1023 (عبر MCP3008)
جهد المرجع5 Vنحو 3.3 V3.3 V
دقّة التمييز4.88 mV0.81 mV3.22 mV
لغة البرمجةأردوينو (C++)أردوينو أو مايكروبايثونبايثون
مثال 4.5
حسّاس LM35 في حرارة 25 °C يُخرج 0.25 V. ما هي القيمة الخام في كل لوحة؟ (الراسبيري باي عبر MCP3008 بمرجع 3.3 V.)
الحل:

نستعمل الصيغة نفسها في الثلاث: N = V·NmaxVref ، ونأخذ الجزء الصحيح:

NUno = 0.25·10235 → 51
NESP32 = 0.25·40953.3 → 310
NPi = 0.25·10233.3 → 77

الجهد نفسه يعطي ثلاثة أعداد مختلفة، لأنّ عدد البتات وجهد المرجع مختلفان. لذلك نكتب في كل برنامج Nmax و Vref الصحيحين للّوحة.

NUno = 51 , NESP32 = 310 , NPi = 77
سؤال 4.6: الراسبيري باي يقرأ LM35 عبر MCP3008 (Vref = 3.3 V) ويحصل على N = 155. ما هو الجهد؟ وما هي الحرارة؟
من Uno إلى ESP32: برامج هذا الكتاب مكتوبة للوحة Uno ، ومعظمها يُترجَم كما هو للوحة ESP32 أيضا. لكن لتعمل القراءة صحيحة نغيّر ثلاثة أمور: رقم الطرف (المدخل التماثلي بين GPIO32 و GPIO39)، والعدد 1023 إلى 4095 ، والجهد 5 V إلى 3.3 V. وفي برنامج المحرّك المؤازر نستعمل المكتبة ESP32Servo بدل Servo.

الحسّاسات في الراسبيري باي ببايثون – חיישנים ברספברי פיי בפייתון:

في الراسبيري باي لا نكتب برنامج أردوينو، بل برنامجا بلغة بايثون. الحسّاسات الرقمية تتّصل مباشرة بأطراف GPIO (بجهد 3.3 V)، والتماثلية عبر MCP3008. نعرض أربعة أمثلة قصيرة لحسّاسات من هذا الكتاب. المكتبة gpiozero موجودة في نظام Raspberry Pi OS ، ومكتبة DHT22 نثبّتها مرّة واحدة بالأمر:

pip install adafruit-circuitpython-dht
زرّ لحظي على GPIO17: المقاومة الساحبة داخلية، كما في الفصل 3
from gpiozero import Button
from signal import pause

btn = Button(17)              # GPIO17, internal pull-up

btn.when_pressed = lambda: print("pressed")
btn.when_released = lambda: print("released")
pause()
LM35 عبر MCP3008 على القناة 0: الصيغة نفسها كما في Uno، مع 3.3 V بدل 5 V
from gpiozero import MCP3008
from time import sleep

lm35 = MCP3008(channel=0)     # SPI, Vref = 3.3 V

while True:
    n = lm35.raw_value        # 0 .. 1023
    v = n * 3.3 / 1023
    t = v / 0.010             # 10 mV per degree C
    print("N = %d  V = %.3f V  T = %.1f C" % (n, v, t))
    sleep(1)
DHT22 على GPIO27: لا نقرأ أسرع من مرّة كل ثانيتين (الفصل 5)
import time
import board
import adafruit_dht

dht = adafruit_dht.DHT22(board.D27)      # GPIO27

while True:
    try:
        print("T = %.1f C  RH = %.1f %%" % (dht.temperature, dht.humidity))
    except RuntimeError:
        pass                  # a missed reading: try again
    time.sleep(2)
DS18B20 على GPIO4: نظام التشغيل يقرأ ناقل 1-Wire بعد تفعيله، والبرنامج يقرأ الملف فقط
import glob, time

dev = glob.glob("/sys/bus/w1/devices/28-*/temperature")[0]

while True:
    with open(dev) as f:
        t = int(f.read()) / 1000      # millidegrees C
    print("T = %.2f C" % t)
    time.sleep(1)
الراسبيري باي: قبل التشغيل نفعّل في إعدادات الراسبيري باي (raspi-config) الواجهة SPI من أجل MCP3008 ، والواجهة 1-Wire من أجل DS18B20. نغذّي MCP3008 ومرجعه من 3.3 V ، ونغذّي LM35 من الطرف 5 V في اللوحة (يحتاج إلى 4 V على الأقل)؛ مخرجه أقلّ من 1.5 V ، فلا خطر على MCP3008.
3.3 V: أطراف الراسبيري باي، مثل ESP32، تعمل بـ 3.3 V ولا تتحمّل 5 V. حسّاس مخرجه 5 V ، مثل طرف ECHO في HC-SR04 ، نوصله عبر مُجزِّء جهد كما في الفصل 3.

ملخّص قوانين الفصل:

القانونالصيغة
أكبر قيمة خامNmax = 2n − 1
دقّة التمييزΔ V = Vref2n
من القيمة الخام إلى الجهدV = N·VrefNmax
من الجهد إلى القيمة الخامN = V·NmaxVref
مُجزِّء الجهد، الحسّاس في الأسفلVout = VCC·RSRF + RS
LM35: من الجهد إلى الحرارةT = V10 mV/°C

قاموس المصطلحات – מילון מונחים:

بالعربيةبالعبرية (كما تظهر في الامتحان)English
المحوّل التماثلي-الرقميממיר תקבילי-ספרתי (ADC)Analog-to-digital converter
أخذ العيّناتדגימהSampling
التكميمקוונטיזציהQuantization
عدد البتاتמספר סיביותNumber of bits
القيمة الخامערך גולמיRaw value (count)
جهد المرجعמתח ייחוסReference voltage
دقّة التمييزרזולוציה (הפרדה)Resolution
مُجزِّء الجهدמחלק מתחVoltage divider
ملاءمة الإشارةהתאמת אותותSignal conditioning
الضجيجרעשNoise
الترشيحסינוןFiltering
مدى القياسתחום מדידהMeasuring range
الوحدات الهندسيةיחידות הנדסיותEngineering units

أسئلة للتمرين:

1.
لوحة Uno تقرأ N = 300. ما هو الجهد في المدخل؟
الإجابات: V = 1.466 V
2.
محوّل من 8 بتات وجهد مرجعه 5 V.
(أ) ما هو Nmax ؟
(ب) ما هي دقّة التمييز؟
(ج) ما هي القيمة الخام لجهد 2 V ؟
الإجابات: (أ) 255 (ب) 19.53 mV (ج) N = 102
3.
في ESP32 نقرأ N = 2500. ما هو الجهد؟ ولماذا لا نستعمل طرفا من ADC2 في مشروع يرسل القراءة عبر WiFi ؟
الإجابات: V = 2.015 V ؛ أطراف ADC2 لا تعمل عندما تكون WiFi مفعّلة
4.
ماذا يطبع البرنامج في كل حالة عندما N = 800 (المتغيّر n من نوع int):
(أ) n / 1023 * 5
(ب) map(n, 0, 1023, 0, 5)
(ج) n * 5.0 / 1023.0 مع ثلاث خانات عشرية؟
الإجابات: (أ) 0 (ب) 3 (ج) 3.910
5.
في مُجزِّء جهد RF = 4.7 kΩ في الأعلى، وحسّاس RS = 12 kΩ في الأسفل، و VCC = 5 V. احسبوا Vout والقيمة الخام في Uno.
الإجابات: Vout = 3.593 V ، N = 735
6.
في دائرة المقاومة الحرارية (RF = 10 kΩ في الأعلى، NTC في الأسفل) تنخفض الحرارة إلى 0 °C ، ومقاومة NTC تصبح نحو 33.6 kΩ.
(أ) هل يكبر Vout أم يصغر مقارنة بـ 25 °C ؟
(ب) احسبوا Vout والقيمة الخام.
الإجابات: (أ) يكبر، لأن مقاومة الحسّاس كبرت (ب) Vout = 3.85 V ، N = 788
7.
نقيس جهد مُركِّم 24 V بمُجزِّء جهد فيه R1 = 47 kΩ و R2 = 10 kΩ.
(أ) ما هو الجهد في A0 ؟
(ب) ما هي القيمة الخام؟
(ج) ما هو أكبر جهد نستطيع قياسه بهذا المُجزِّء؟
الإجابات: (أ) VA0 = 4.21 V (ب) N = 861 (ج) 28.5 V
8.
البرنامج average8 جمع القراءات الثماني: 410 , 402 , 418 , 406 , 430 , 426 , 414 , 410. ما هي قيمة avg التي يطبعها؟ وما هي قيمة raw ؟
الإجابات: avg = 414.5 ، raw = 410
9.
حسّاس LM35 (10 mV/°C) موصول بلوحة Uno التي تقرأ N = 82. ما هو الجهد، وما هي الحرارة؟
الإجابات: V = 0.401 V ، T = 40.1 °C
10.
حسّاس حرارة موصول بلوحة ESP32 يُخرج من 0 V حتى 3.3 V لمدى من 0 حتى 50 °C. القراءة N = 3000.
(أ) اكتبوا سطر map() الملائم.
(ب) ماذا يُرجع؟
(ج) ما هي الحرارة الدقيقة؟
الإجابات: (أ) map(n, 0, 4095, 0, 50) (ب) 36 (ج) T = 36.6 °C
11.
حسّاس حرارة صناعي يُخرج من 1 V حتى 5 V لمدى من 0 حتى 100 °C ، موصول بلوحة Uno.
(أ) ما هي القيمة الخام عند 1 V وعند 5 V ؟
(ب) اكتبوا سطر map() الملائم.
(ج) ما هي الحرارة عندما N = 614 ؟
الإجابات: (أ) 204 و 1023 (ب) map(n, 204, 1023, 0, 100) (ج) T = 50 °C
الإجابات النهائية لأسئلة الفصل
4.1 N = 2047 ، V = 0.806 V
4.2 map تعطي 68 ، والنسبة الدقيقة 68.43%
4.3 VA0 = 2.812 V ، N = 575
4.4 1.6 ms
4.5 (أ) 3 (ب) P = 3.52 bar
4.6 V = 0.5 V ، T = 50 °C
لوحة القوانين: كل قوانين هذا الفصل مجموعة مع رسومها وجداول رموزها في الفصل 15 — لوحة القوانين الشاملة. (נוסחאון הספר)