مستشعرات الحمل

weighing-scale-with-white-background

فهم مستشعرات الحمل: كيف تعمل وكيف تستخدمها

هل تساءلت يومًا كيف يعمل الميزان الرقمي عند وزن الأشياء؟ أو كيف تقيس الآلات الصناعية مقدار القوة التي تطبقها؟ السر يكمن في مستشعر خاص يُسمى مستشعر الحمل—وهو مكون صغير لكنه قوي، يحوّل القوة الميكانيكية إلى إشارات كهربائية قابلة للقياس.

في هذا المقال، سنتعرف على ما هي مستشعرات الحمل، كيف تعمل، وكيف يمكنك استخدامها في مشاريعك الإلكترونية باستخدام الأردوينو.

Load sensors combined

1. ما هو مستشعر الحمل؟

مستشعر الحمل (Load Cell) هو نوع من المحولات (Transducer) وظيفته تحويل القوة الميكانيكية (مثل الوزن أو الضغط) إلى إشارة كهربائية.

هذه الإشارة الكهربائية عادة ما تكون صغيرة جدًا، وتحتاج إلى تضخيم قبل أن يتمكن متحكم مثل أردوينو من قراءتها.

تُستخدم مستشعرات الحمل في مجموعة واسعة من التطبيقات، مثل:

  • موازين المطبخ الإلكترونية
  • أنظمة الوزن الصناعية
  • الحقائب الذكية
  • أذرع الروبوت
  • مراقبة إجهاد الهياكل والجسور


Robot arm
structural health monitoring sensor

2. كيف يعمل مستشعر الحمل؟

تعتمد معظم مستشعرات الحمل على تقنية تُسمى مقياس الانفعال (Strain Gauge)، وهو سلك أو نمط معدني يتغير مقاومته الكهربائية عند تعرضه للشد أو الانضغاط.

عندما يُطبق وزن على المستشعر، تحدث تشوهات صغيرة جدًا في هذا المقياس، تؤدي إلى تغير في مقاومته. ولأن هذا التغير صغير جدًا، يتم توصيل أربعة من هذه المقاييس في تشكيل يُسمى جسر ويتستون (Wheatstone Bridge) لزيادة الدقة واستقرار الإشارة.

Strain gauge implanted in a metal bar
load-cell-with-compression-tension-illustration
strain-gauges-in-wheatstone-bridge-formation

3. أنواع مستشعرات الحمل

يوجد عدة أنواع من مستشعرات الحمل، مصممة لتناسب تطبيقات ميكانيكية مختلفة:

مستشعر الحمل النقطي (Single-Point Load Cell)

يُعرف أيضًا باسم مستشعر الانحناء، ويُعد الأكثر استخدامًا في مشاريع الأردوينو. غالبًا ما يُصنع من سبيكة الألمنيوم وله أربعة أسلاك (أحمر، أسود، أخضر، أبيض)، ويُستخدم في:

  • موازين المطبخ والبريد
  • أنظمة الوزن الدقيقة
  • روبوتات الاستشعار بالقوة
  • المشاريع التعليمية والـ DIY

يوجد في وسط هذا النوع فتحة محفورة تساعد على تركيز الإجهاد، حيث توضع مقاييس الانفعال حولها وتُوصل بشكل جسر ويتستون.

10kg load cell

مستشعر S-Type

على شكل حرف "S"، ويُستخدم لقياس الضغط والشد.

S load sensor

مستشعر الزر (Button Type)

صغير الحجم ويُستخدم في المساحات الضيقة.

button load sensor

4. شرح جسر ويتستون

جسر ويتستون هو دائرة كهربائية تُستخدم لقياس التغيرات الصغيرة جدًا في المقاومة الكهربائية. يتكون من أربعة مقاومات (أو مقاييس انفعال) تُرتب على شكل ماسة.

عندما لا يوجد وزن، يكون الجسر "متزنًا"، ويكون الجهد الخارج شبه صفر. وعند تطبيق وزن، تتغير مقاومة بعض المقاييس، مما يؤدي إلى خلل في التوازن وظهور فرق جهد صغير.

لماذا نستخدم جسر ويتستون؟

  • حساسية عالية: يمكنه اكتشاف تغييرات صغيرة جدًا في المقاومة.
  • رفض التشويش: يعزل التأثيرات الناتجة عن التغير في درجة الحرارة أو الضوضاء الكهربائية.
  • خروج خطي: يعطي علاقة خطية تقريبًا بين الوزن والجهد، ما يسهل المعايرة.
wheatstone bridge illustration

5. تضخيم الإشارة: دور وحدة HX711

الإشارة القادمة من مستشعر الحمل تكون صغيرة جدًا (ميليفولت)، لذلك تُستخدم وحدة HX711 لتضخيمها وتحويلها إلى قيمة رقمية يستطيع الأردوينو قراءتها.

وحدة HX711 سهلة الاستخدام ورخيصة، وتُعتبر مثالية لمشاريع الوزن باستخدام الأردوينو أو ESP32.

Load cell amplifier HX711

6. كيفية معايرة الوزن في مشاريع الأردوينو

الدالة scale.set_scale() تُستخدم لضبط العامل الذي يُحوّل القيم الخام إلى وحدات وزن حقيقية.

كيف تعمل؟

1float weight = scale.get_units();

داخليًا تُطبق المعادلة التالية:

1weight = (raw_value - offset) / scale_factor;
  • raw_value: القيمة المقروءة الخام من HX711
  • offset: قيمة الصفر التي يتم تعيينها بعد tare()
  • scale_factor: معامل التحويل إلى جرام أو كيلوجرام

طريقة حساب معامل التحويل بدقة

  • استدع scale.tare() لتصفير القراءة.
  • ضع وزنًا معروفًا (مثلاً 500 جرام).
  • اقرأ القيمة الخام:
1float raw = scale.get_units(10);
2
  • احسب معامل التحويل:
1float scale_factor = raw / 500.0;
2
  • خزّنه باستخدام:
1scale.set_scale(scale_factor);
2

7. استخدام مستشعر الحمل مع الأردوينو (نسخة متقدمة مع EEPROM)

لحفظ المعايرة بعد إعادة التشغيل، يمكن تخزين معامل التحويل في EEPROM.

الميزات:

  • معايرة عند الضغط المطول على الزر أثناء التشغيل.
  • تخزين معامل المعايرة في EEPROM.
  • استخدام إدخال من المستخدم لإدخال الوزن الحقيقي.
  • عرض الوزن فقط عند تغيّره.
  • تفادي القراءات السالبة والاهتزاز.

الأدوات المطلوبة:

  • مستشعر حمل
  • وحدة HX711
  • لوحة أردوينو
  • زر ضغط موصول بين D4 و GND (بدون مقاومة خارجية)

ملاحظة – مكتبة HX711 مفقودة؟

إذا ظهرت لك رسالة:
fatal error: HX711.h: No such file or directory

ذلك يعني أن المكتبة غير مثبتة.

لحل المشكلة:

  1. افتح Arduino IDE
  2. اذهب إلى Tools > Manage Libraries
  3. ابحث عن: HX711
  4. ثبّت مكتبة HX711 by Bogdan Necula أو Rob Tillaart
  5. أعد ترجمة الكود

كود أردوينو:

1#include <HX711.h>
2#include <EEPROM.h>
3
4#define DT_PIN 2
5#define SCK_PIN 3
6#define BUTTON_PIN 4
7#define EEPROM_ADDR 0
8#define EEPROM_FLAG_ADDR 1
9#define EPROM_SAVED_FLAG 0xA5
10
11HX711 scale;
12float scale_factor = 1;
13float user_weight = 0;
14
15bool ButtonIsPressed() {
16 return digitalRead(BUTTON_PIN) == LOW;
17}
18
19void WaitPressButton() {
20 while (digitalRead(BUTTON_PIN) == HIGH) {
21 delay(100);
22 }
23}
24
25void WaitReleaseButton() {
26 while (digitalRead(BUTTON_PIN) == LOW) {
27 delay(100);
28 }
29}
30
31bool HasSavedFactor() {
32 return (EEPROM.read(EEPROM_FLAG_ADDR) == EPROM_SAVED_FLAG);
33}
34
35float WaitForSerialInput() {
36 while (Serial.available() == 0) {
37 // wait until user types a number
38 }
39 return Serial.parseFloat();
40}
41
42void StartCalibration() {
43 Serial.println("---------- Calibration Mode Started -----------");
44 if (ButtonIsPressed()) {
45 Serial.println("Release the button to start");
46 WaitReleaseButton();
47 }
48
49 scale.set_scale(1);
50 scale.tare();
51 delay(1000);
52
53 Serial.println("Place a known weight on the scale.");
54 Serial.println("Then press the button to proceed");
55
56 WaitPressButton();
57
58 Serial.println("Enter the known weight value (in grams):");
59 user_weight = WaitForSerialInput();
60 Serial.print("You entered: ");
61 Serial.println(user_weight, 2);
62
63 Serial.println("Calibrating, please wait...");
64 float raw = scale.get_units(10);
65 Serial.print("Raw value: ");
66 Serial.println(raw, 6);
67
68 scale_factor = raw / user_weight;
69 Serial.print("Calculated scale factor: ");
70 Serial.println(scale_factor, 6);
71
72 EEPROM.put(EEPROM_ADDR, scale_factor);
73 EEPROM.write(EEPROM_FLAG_ADDR, EPROM_SAVED_FLAG);
74
75 Serial.println("Remove any weight from the scale.");
76 Serial.println("Then press the button to continue.");
77 WaitPressButton();
78
79 Serial.println("---------- Calibration Completed -----------");
80}
81
82void setup() {
83 Serial.begin(9600);
84 pinMode(BUTTON_PIN, INPUT_PULLUP);
85 scale.begin(DT_PIN, SCK_PIN);
86
87 if (ButtonIsPressed() || !HasSavedFactor()) {
88 StartCalibration();
89 }
90
91 EEPROM.get(EEPROM_ADDR, scale_factor);
92 Serial.print("Loaded scale factor from EEPROM: ");
93 Serial.println(scale_factor, 6);
94
95 scale.set_scale(scale_factor);
96 scale.tare();
97 delay(1000);
98 Serial.println("Scale is ready.");
99}
100
101void loop() {
102 static float lastWeight = 0.0;
103 float weight = scale.get_units(10);
104 if (weight < 0) weight = 0;
105
106 float threshold = 0.15;
107 if (abs(weight - lastWeight) >= threshold) {
108 Serial.print("Weight: ");
109 Serial.print(weight, 1);
110 Serial.println(" g");
111 lastWeight = weight;
112 }
113
114 delay(10);
115}
116
load-sensor-to-arduino-with-a-switch_circuit

8. المعايرة باستخدام EEPROM + شاشة OLED (النسخة المحسّنة)

في هذا الإصدار، قمنا بإزالة زر الضغط واستخدمنا شاشة OLED بقياس 0.91 بوصة من نوع SSD1306.

نظرة عامة على التوصيلات:

لقد أبقينا توصيلات حساس الوزن ووحدة التكبير HX711 كما هي، مع إضافة شاشة OLED من نوع SSD1306 بقياس 0.91 بوصة:

  • VCC → 3.3V (نعم، هذا صحيح، الشاشة OLED تعمل على 3.3 فولت أو 5 فولت)
  • GND → GND
  • SDA (OLED) → A4
  • SCL (OLED) → A5

لا حاجة بعد الآن إلى شاشة السيريال!

بفضل دمج شاشة OLED في المشروع، أصبح الـ Arduino يعمل بشكل مستقل تمامًا—فبمجرد إتمام المعايرة وتخزينها في الذاكرة، لن تحتاج إلى توصيله بالحاسوب أو فتح شاشة السيريال لمتابعة الوزن.

  • تتم المعايرة مرة واحدة فقط، ويتم حفظ الإعدادات في EEPROM.
  • شاشة OLED تعرض الوزن بشكل مباشر ومستمر.
  • هذا الإعداد مثالي للتطبيقات المحمولة أو المدمجة مثل الميزان المنزلي، موزّعات المواد، أو الرفوف الذكية.

كود أردوينو:

1#include <HX711.h>
2#include <EEPROM.h>
3#include <Wire.h>
4#include <Adafruit_GFX.h>
5#include <Adafruit_SSD1306.h>
6
7#define SCREEN_WIDTH 128
8#define SCREEN_HEIGHT 32
9#define OLED_RESET -1 // Reset pin not used
10
11#define DT_PIN 2
12#define SCK_PIN 3
13#define BUTTON_PIN 4
14#define EEPROM_ADDR 0
15#define EEPROM_FLAG_ADDR 1
16#define EPROM_SAVED_FLAG 0xA5
17
18HX711 scale;
19float scale_factor = 1;
20float user_weight = 0;
21
22
23
24Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
25
26void showProgress(unsigned long totalTime=500){
27 unsigned long delay_t = totalTime/100;
28 display.setTextSize(3);
29 for(int i=0; i< 100;i++){
30 display.setTextColor(SSD1306_WHITE);
31 display.setCursor(i, 0);
32 display.println(".");
33 display.display();
34 delay(delay_t);
35 }
36}
37
38bool ButtonIsPressed(){
39 return digitalRead(BUTTON_PIN) == LOW;
40}
41
42void WaitPressButton(){
43 while (digitalRead(BUTTON_PIN) == HIGH) {
44 delay(100);
45 }
46}
47
48bool HasSavedFactor(){
49 return (EEPROM.read(EEPROM_FLAG_ADDR) == EPROM_SAVED_FLAG);
50}
51
52void WaitReleaseButton(){
53 while (digitalRead(BUTTON_PIN) == LOW) {
54 delay(100);
55 }
56}
57
58
59float WaitForSerialInput() {
60 while (Serial.available() == 0) {
61 // wait here forever until user types something
62 }
63 float val = Serial.parseFloat();
64 return val;
65}
66
67void StartCalibration(){
68 Serial.println("---------- Calibration Mode Started -----------");
69 if(ButtonIsPressed()){
70 Serial.println("Release the button to start");
71 WaitReleaseButton();
72 }
73
74
75 scale.set_scale(1);
76 scale.tare();
77 delay(1000);
78 Serial.println("");
79 Serial.println("Place a known weight on the scale.");
80 Serial.println("then press the button to proceed");
81
82 WaitPressButton();
83
84 Serial.println("");
85 Serial.println("Enter the weight value in the serial monitor:");
86
87 user_weight = WaitForSerialInput(); // Read float from serial
88 Serial.print("You entered: ");
89 Serial.println(user_weight, 2); // Print with 5 decimal places
90
91
92 Serial.println("Calibrating, please wait ...");
93
94 float raw = scale.get_units(10);
95
96 Serial.print("Raw value: ");
97 Serial.println(raw, 6); // Print with 6 decimal places
98
99 scale_factor = raw / user_weight;
100
101 Serial.print("Calculated scale factor: ");
102 Serial.println(scale_factor, 6);
103 Serial.println("Saving scale factor to EEPROM: ");
104 EEPROM.put(EEPROM_ADDR, scale_factor);
105 EEPROM.write(EEPROM_FLAG_ADDR, EPROM_SAVED_FLAG); // flag as saved
106
107 Serial.println("Remove any weight off the scale");
108 Serial.println("then press the button to proceed");
109 WaitPressButton();
110
111 Serial.println("---------- Calibration Completed -----------");
112}
113
114void screenSetup(){
115 Wire.begin();
116 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 0x3C is the I2C address
117
118 display.clearDisplay();
119 display.setTextSize(3);
120}
121
122void displayWeight(float weight){
123 display.clearDisplay();
124 display.setTextSize(3);
125 char displayBuffer[30];
126
127 dtostrf(weight, 5, 1, displayBuffer);
128 strcat(displayBuffer, " g");
129 display.setCursor(0, 0);
130 display.println(displayBuffer);
131
132 display.display();
133
134}
135
136void setup() {
137 screenSetup();
138 Serial.begin(9600);
139 pinMode(BUTTON_PIN, INPUT_PULLUP); // internal pull-up
140 scale.begin(DT_PIN, SCK_PIN);
141
142 // enter caliration mode if scale factor is not set
143 // or calibrate on demand when ardunio is powered while the button is down
144 if(ButtonIsPressed() || !HasSavedFactor()){
145 StartCalibration();
146 }
147
148 EEPROM.get(EEPROM_ADDR, scale_factor);
149 Serial.print("Loaded scale factor from EEPROM: ");
150 Serial.println(scale_factor, 6);
151
152
153 scale.set_scale(scale_factor);
154 scale.tare();
155 showProgress(1000);
156
157 Serial.println("Scale is ready.");
158 displayWeight(0);
159
160}
161
162void loop() {
163 static float lastWeight = 0.0;
164 float weight = scale.get_units(10);
165 if(weight < 0)
166 weight = 0;
167
168
169 float threshold = 0.15;
170 float diff = abs(weight - lastWeight);
171 if (diff >= threshold) {
172
173 Serial.print("Weight: ");
174 Serial.print(weight, 1);
175 Serial.println(" g");
176 lastWeight = weight;
177
178 displayWeight(weight);
179 }
180
181 delay(10);
182}
183
load sensor to arduino with an OLED screen

9. تطبيقات حقيقية لمستشعرات الحمل

  • موازين المطبخ والشحن
  • الحقائب الذكية
  • أنظمة الأتمتة الصناعية
  • روبوتات التحكم بالقوة
  • مراقبة الهياكل والجسور

10. اعتبارات عملية

  • لا تتجاوز الحد الأقصى للوزن.
  • ثبت المستشعر بإحكام للحصول على قراءات دقيقة.
  • درجة الحرارة قد تؤثر على الدقة.
  • حافظ على الأسلاك قصيرة لتجنب التشويش.

11. الخلاصة

مستشعرات الحمل أدوات رائعة تتيح للأردوينو التفاعل مع العالم الحقيقي عبر قياس الوزن والقوة. باستخدام مستشعر الحمل ووحدة HX711، يمكنك بناء ميزان إلكتروني ذكي خاص بك واكتساب فهم عملي رائع للفيزياء والقياس.

أو بإمكانك إستكشاف تصنيفات أخرى

Arduino robot and rover

عالم الإلكترونيات

A DIY made aircraft rc model with a transmitter

الفيزياء وميكانيكا الطيران

Children looking into a microscop in turns

استكشف العالم الخفي تحت المجهر