يحتوي هذا المقال على روابط تسويق بالعمولة مُعلَّمة بعلامة *. بصفتي شريكًا في برنامج Amazon Associates، أربح من عمليات الشراء المؤهلة، دون أي تكلفة إضافية عليك. يساعد ذلك على إبقاء الشروحات مجانية.
في الفيديو أدناه، أبني الدائرة على مرحلتين: في البداية تحرّك عصا التحكم (Joystick) محركَي السيرفو دون شاشة، ثم أضيف شاشة OLED. أما الخطوات المكتوبة فتتناول النسخة النهائية مع الشاشة.
ملخص سريع
ستبني وحدة تحكم بمحركات السيرفو على محورين باستخدام Arduino Uno: تحرّك عصا التحكم محركَي سيرفو SG90، وتعرض شاشة SSD1306 OLED الزاوية المرسلة إلى كل محرك. يغطي المشروع الإدخال التناظري، والتحكم بمحركات السيرفو، وشاشة OLED على ناقل I2C الذي لا يحتاج إلا إلى سلكين للإشارة. والدائرة نفسها هي الأساس لحامل كاميرا بمحوري دوران أفقي وعمودي (Pan-Tilt) أو لنموذج صغير من الذراع الروبوتية.
ما الذي ستتعلمه
- كيف توفّر وحدة عصا التحكم محورين تناظريين (X وY).
- كيف يقرأ Arduino قيم عصا التحكم ويحوّلها إلى زوايا سيرفو باستخدام الدالة
map(). - كيف توصّل محركَي سيرفو SG90 وشاشة SSD1306 OLED بلوحة Arduino Uno.
- كيف تعرض شاشة OLED الزاوية المرسلة إلى كل سيرفو أثناء تحريكك لعصا التحكم.
- كيف تغذّي محركات السيرفو من مزود طاقة خارجي بجهد 5 V مع أرضي (GND) مشترك.
- كيف توقف اهتزاز السيرفو (حركاته الصغيرة غير المرغوب فيها) عند المنتصف باستخدام منطقة ميتة (Dead Zone): وهي نطاق حول القيمة المركزية يتجاهل فيه الكود التغيرات الصغيرة في عصا التحكم.
- كيف تعكس اتجاه محور أو تحدّ من نطاق حركة السيرفو.
كيف تعمل الدائرة
تتكون حلقة التحكم من أربعة أجزاء:
- وحدة عصا التحكم: تحتوي على مقاومتين متغيرتين (Potentiometers)، هما VRx للمحور X وVRy للمحور Y. تُخرج كل منهما جهدًا بين 0 و5 V، يقرؤه Arduino كقيمة من 0 إلى 1023.
- Arduino Uno: يشغّل برنامج Arduino (Sketch). يقرأ البرنامج القيمتين، ويحوّلهما إلى زوايا من 0 إلى 180 درجة باستخدام
map()، ويرسل الزوايا إلى محركات السيرفو، ويحدّث شاشة OLED. - محركا سيرفو: يستقبل كل سيرفو إشارة PWM (تعديل عرض النبضة) من طرف خاص به في Arduino. الإشارة نبضة تتكرر كل 20 ms، وعرضها هو الذي يحدد الزاوية، ويتراوح بين 0.5 و2.4 ms تقريبًا في مكتبة Servo الخاصة بـ Arduino. يتحكم المحور X بالسيرفو الموصول بالطرف D9، والمحور Y بالسيرفو الموصول بالطرف D10.
- شاشة SSD1306 OLED: شاشة OLED هذه بدقة 128×64 بكسل. تتواصل مع Arduino عبر I2C: ينقل الخط SDA البيانات، وينقل الخط SCL إشارة الساعة.
تستغرق الدورة الواحدة للحلقة 50 ms إضافة إلى زمن تحديث شاشة OLED، لذا تتبع محركات السيرفو عصا التحكم دون تأخير ملحوظ. هل أنت جديد على محركات السيرفو؟ يشرح دليل التحكم بالسيرفو مع Arduino الأساسيات.
المكونات المطلوبة
| المكوّن | الكمية | الغرض | ملاحظات |
|---|---|---|---|
| Arduino Uno (أو Nano) | 1 | لوحة المتحكم الدقيق الرئيسية | تعمل أي لوحة Arduino مزودة بشريحة المتحكم الدقيق ATmega328P |
| وحدة عصا التحكم (XY + SW) | 1 | إدخال تناظري بمحورين | توفّر VRx وVRy وزر ضغط اختياريًا (SW) |
| محرك سيرفو (SG90 أو MG90S) | 2 | مشغّلات للمحورين X وY | محركات سيرفو صغيرة للهواة مصممة لجهد من 4.8 إلى 6 V |
| شاشة OLED (SSD1306، I2C) | 1 | تعرض الزاوية المرسلة إلى كل سيرفو | 128×64 بكسل، من 3.3 إلى 5 V |
| لوحة التجارب (Breadboard) + أسلاك التوصيل (Jumper) | حسب الحاجة | التوصيلات | أسلاك توصيل ذكر-ذكر وذكر-أنثى |
| مزود طاقة خارجي 5 V | 1 | تغذية السيرفو | 2 A على الأقل لمحركَي سيرفو |
مخطط التوصيل
وصّل المكونات كما هو موضح في الجدول. إذا كنت جديدًا على توصيلات Arduino، فاقرأ أساسيات برمجة Arduino أولًا.
| طرف المكوّن | طرف Arduino | ملاحظات |
|---|---|---|
| عصا التحكم VRx | A0 | الخرج التناظري للمحور X |
| عصا التحكم VRy | A1 | الخرج التناظري للمحور Y |
| عصا التحكم SW | D2 (اختياري) | زر ضغط، غير مستخدم في هذا البرنامج |
| إشارة السيرفو 1 | D9 | خرج PWM لسيرفو المحور X |
| إشارة السيرفو 2 | D10 | خرج PWM لسيرفو المحور Y |
| OLED SDA | A4 | خط بيانات I2C |
| OLED SCL | A5 | خط ساعة I2C |
| السيرفو +V (كلاهما) | مصدر خارجي 5 V | لا تغذِّ محركات السيرفو من الطرف 5 V في Arduino |
| السيرفو GND (كلاهما) | GND مشترك | وصّل GND لمزود الطاقة الخارجي بـ GND في Arduino |
ملاحظات مهمة حول التوصيلات:
- مزود طاقة خارجي 5 V لمحركات السيرفو: يسحب محرك SG90 نحو 100 mA عندما يتحرك بحرية، وما يصل إلى نحو 650 mA عند التوقف (Stall). والسيرفو المتوقف هو سيرفو محجوز الحركة لا يستطيع بلوغ موضعه المستهدف. يسحب محركان متوقفان ما يصل إلى 1.3 A، بينما يوفّر منفذ USB تيارًا قدره 500 mA. والنتيجة انخفاضات في الجهد، أو اهتزاز السيرفو، أو إعادة تشغيل اللوحة. استخدم مزود طاقة خارجيًا بجهد 5 V وتيار 2 A على الأقل.
- أرضي مشترك: يجب توصيل GND لمزود الطاقة الخارجي، وGND في Arduino، وجميع أطراف GND للمكونات معًا. فمن دون أرضي مشترك، لا يكون لدى محركات السيرفو مرجع لجهد الإشارة، فتستجيب بشكل عشوائي أو لا تستجيب إطلاقًا.
- مقاومات الرفع (Pull-up) لناقل I2C: تحتوي معظم وحدات SSD1306 على مقاومات رفع (Pull-up) على خطي SDA وSCL. مقاومة الرفع تُبقي الخط عند جهد محدد عندما لا يسحبه أي جهاز إلى المستوى المنخفض. إذا لم تكن على شاشتك مقاومات رفع، فأضف مقاومات رفع بقيمة 4.7 kΩ إلى 3.3 V أو 5 V.

برمجة Arduino
قبل الرفع، ثبّت هذه المكتبات في Arduino IDE (البرنامج الذي تستخدمه لكتابة البرامج ورفعها إلى اللوحة): Servo (مدمجة)، وAdafruit GFX، وAdafruit SSD1306. افتح Sketch > Include Library > Manage Libraries، وابحث عن Adafruit SSD1306، ثم انقر Install. ووافق على الرسالة التي تطلب تثبيت Adafruit GFX أيضًا.
الكود الكامل
الصق الكود في برنامج جديد (Sketch) في Arduino IDE وارفعه إلى لوحة Uno.
#include <Servo.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Servo setup
Servo servoX;
Servo servoY;
int joyX = A0;
int joyY = A1;
int servoXPin = 9;
int servoYPin = 10;
void setup() {
servoX.attach(servoXPin);
servoY.attach(servoYPin);
// OLED init
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;); // Halt if the display buffer cannot be allocated
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void loop() {
int xVal = analogRead(joyX);
int yVal = analogRead(joyY);
int angleX = map(xVal, 0, 1023, 0, 180);
int angleY = map(yVal, 0, 1023, 0, 180);
servoX.write(angleX);
servoY.write(angleY);
// OLED output
display.clearDisplay();
display.setCursor(0,0);
display.print("Servo X: "); display.println(angleX);
display.print("Servo Y: "); display.println(angleY);
display.display();
delay(50); // at most 20 updates per second
}
شرح الكود
المكتبات والإعداد
يستخدم البرنامج ثلاث مكتبات. Servo.h يوفر Servo ، وهو الصنف (Class) الذي يولّد إشارة التحكم لمحركات السيرفو الصغيرة. Adafruit_GFX.h هي مكتبة الرسوميات الخاصة بالنصوص والأشكال والبكسلات. Adafruit_SSD1306.h هي برنامج التشغيل (Driver) لشاشات SSD1306 OLED عبر I2C.
السطر Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1) ينشئ كائن الشاشة لشاشة 128×64. الوسيط &Wire يختار ناقل I2C في لوحة Uno، بينما -1 يعني أنه لا يوجد طرف إعادة ضبط (Reset) موصول. في setup(), attach() يربط كل كائن من نوع Servo بالطرف الخاص به. الاستدعاء display.begin(SSD1306_SWITCHCAPVCC, 0x3C) يشغّل الشاشة على عنوان I2C 0x3C، وهو العنوان الافتراضي لمعظم وحدات SSD1306 بدقة 128×64. الخيار (Flag) SSD1306_SWITCHCAPVCC يجعل الشاشة تولّد داخليًا الجهد العالي اللازم للوحة العرض، فلا تحتاج إلى مصدر تغذية إضافي. الاستدعاء display.begin() يحجز أيضًا 1 KB من ذاكرة RAM البالغة 2 KB في لوحة Uno لمخزن الصورة المؤقت (Image Buffer)، وهو نسخة من محتوى الشاشة محفوظة في ذاكرة Arduino. إذا لم تكن هذه الذاكرة متاحة، begin() يُعيد القيمة false، والسطر for(;;); يوقف البرنامج في حلقة لا نهائية. ولا يتحقق هذا الاستدعاء مما إذا كانت هناك شاشة تستجيب على ناقل I2C.
القراءة التناظرية لعصا التحكم
الاستدعاءان analogRead(joyX) و analogRead(joyY) يقرآن الجهد على A0 وA1. تُخرج كل مقاومة متغيرة في عصا التحكم 0 V عند أحد طرفي مسارها و5 V عند الطرف الآخر. يحوّل محوّل ADC (المحوّل التناظري الرقمي) في Arduino هذا الجهد إلى رقم من 0 إلى 1023. في وضع المنتصف، ستقرأ عادةً قيمًا بين 500 و520 تقريبًا. عندما كانت عصا التحكم لديّ في وضع السكون، عرضت شاشة OLED الزاوية 88 درجة على X و91 على Y، وهو ما يقابل قيمًا خامًا تبلغ نحو 503 و520.
تحويل القيم إلى زوايا باستخدام map()
الاستدعاء map(xVal, 0, 1023, 0, 180) يحوّل قيمة عصا التحكم الخام (من 0 إلى 1023) خطيًا إلى زاوية سيرفو (من 0 إلى 180 درجة). القيمة الخام 0 تعطي 0 درجة، و1023 تعطي 180 درجة، والقيمة المركزية التي تبلغ نحو 510 تعطي نحو 90 درجة. يعتمد اتجاه عصا التحكم الذي يعطي 0 على طريقة تركيب الوحدة؛ وتوضح الخطوة 4 كيفية عكسه. ويستخدم المحور Y التحويل نفسه.
خرج السيرفو
الاستدعاءان servoX.write(angleX) و servoY.write(angleY) يرسلان الزاوية المحسوبة إلى كل سيرفو. وتولّد مكتبة Servo إشارة PWM.
تحديث شاشة OLED
في كل دورة من loop(), display.clearDisplay() يمسح المحتوى السابق، display.setCursor(0,0) ينقل مؤشر النص إلى الزاوية العلوية اليسرى، ثم print() يكتب الزاويتين. الاستدعاء display.display() يرسل مخزن الصورة المؤقت إلى شاشة OLED؛ print() يغيّر هذا المخزن فقط. تعرض الشاشة الزاوية المرسلة إلى كل سيرفو، وهذا يساعد أثناء المعايرة.
لماذا نستخدم delay(50) في الكود
يحدّ التأخير البالغ 50 ms من سرعة الحلقة، فلا تتجاوز 20 تحديثًا في الثانية. ترسل مكتبة Servo نبضتها كل 20 ms بغض النظر عن التأخير، لذا لا يغيّر التأخير إشارة PWM، لكنه يقلّل عدد المرات التي يصل فيها التشويش الصغير من عصا التحكم إلى محركات السيرفو. إذا استمر اهتزاز محركات السيرفو في وضع السكون، فأضف المنطقة الميتة من الخطوة 3.
كيفية اختبار النظام ومعايرته
الخطوة 1: اختبر المحورين
حرّك عصا التحكم يسارًا ويمينًا: يدور السيرفو الموصول بالطرف D9 من 0 إلى 180 درجة وتتغير قيمة Servo X على شاشة OLED. حرّكها للأعلى وللأسفل: يدور السيرفو الموصول بالطرف D10 وتتغير قيمة Servo Y.
الخطوة 2: تحقّق من وضع المنتصف
عندما تكون عصا التحكم في المنتصف، تُظهر القيمتان على شاشة OLED نحو 90 درجة. إذا بقيت الشاشة فارغة، فراجع قسم استكشاف الأخطاء وإصلاحها.
الخطوة 3: أضف منطقة ميتة لتثبيت وضع المنتصف
إذا اهتزت محركات السيرفو بينما تستقر عصا التحكم في المنتصف، فأضف منطقة ميتة. بعد سطرَي map() ، أضف سطرًا واحدًا لكل محور:
if (xVal > 480 && xVal < 540) angleX = 90; if (yVal > 480 && yVal < 540) angleY = 90;
ما دامت عصا التحكم مستقرة قرب المنتصف، يثبت محركا السيرفو عند 90 درجة ويتجاهلان التشويش التناظري الصغير. وقيم السكون في وحدتي، وهي نحو 503 و520، تقع كلتاهما داخل هذا النطاق.
الخطوة 4: اعكس اتجاه المحور عند الحاجة
إذا تحرك أحد محركات السيرفو عكس اتجاه عصا التحكم، فاعكس نطاق الخرج لهذا المحور: غيّر map(xVal, 0, 1023, 0, 180) إلى map(xVal, 0, 1023, 180, 0).
الخطوة 5: حدّد زوايا السيرفو بما يناسب الأجزاء الميكانيكية لديك
إذا لم تكن الأجزاء الميكانيكية لديك قادرة على استخدام النطاق الكامل من 0 إلى 180 درجة، فغيّر نطاق الخرج. فحامل Pan-Tilt يسمح بالحركة من 30 إلى 150 درجة، مثلًا، يحتاج إلى map(xVal, 0, 1023, 30, 150). عندها لا يضغط السيرفو على المصدّات الميكانيكية، وهو ما قد يتلف التروس مع مرور الوقت. في مشروعي، كان محركا السيرفو موضوعين على الطاولة دون تثبيت، ولم يُركَّب عليهما سوى ذراعَي السيرفو (Horn)، لذا تمكنت من استخدام النطاق الكامل.
استكشاف الأخطاء وإصلاحها
شاشة OLED تبقى فارغة
تحقّق من توصيل SDA بالطرف A4 وSCL بالطرف A5، ومن تثبيت مكتبتَي Adafruit SSD1306 وAdafruit GFX. ثم تحقّق من أن عنوان I2C في display.begin(SSD1306_SWITCHCAPVCC, 0x3C) يطابق شاشتك. تستخدم معظم الوحدات العنوان 0x3C، ومنها وحدة 0.96 بوصة في مشروعي. إذا لم تعمل الشاشة إطلاقًا من قبل، فغيّر العنوان في ذلك السطر إلى 0x3D أو شغّل برنامج فحص I2C، الذي يعرض عناوين جميع أجهزة I2C الموصولة. إذا كانت الشاشة تعمل من قبل ثم توقفت، فابحث عن سلك SDA أو SCL أو سلك تغذية مرتخٍ.
اهتزاز محركات السيرفو في وضع المنتصف
للاهتزاز في المنتصف سببان شائعان: ضعف التغذية (محركات السيرفو موصولة بالطرف 5 V في Arduino) أو التشويش التناظري من عصا التحكم. تحقّق من التغذية أولًا (راجع ملاحظات التوصيل)، ثم أضف المنطقة الميتة من الخطوة 3. يعمل مكثف كهروليتي بسعة 470 µF (بجهد مقنن 10 V أو أكثر) موصول بين خطَّي تغذية السيرفو، وبالقرب من المحركات، على تنعيم انخفاضات الجهد القصيرة. وصّل الطرف المميز بشريط السالب إلى GND.
محركات السيرفو تتحرك في الاتجاه الخاطئ
اعكس نطاق الخرج لهذا المحور، كما هو موضح في الخطوة 4.
أحد محركات السيرفو لا يستجيب
تحقّق من سلك الإشارة لذلك السيرفو ومن الطرف المحدد في الكود (D9 أو D10). اختبر السيرفو وحده باستخدام مثال Sweep (File > Examples > Servo > Sweep)، الذي يدير السيرفو الموصول بالطرف 9 ذهابًا وإيابًا، لتستبعد احتمال أن يكون السيرفو معطوبًا. وتحقّق من أن GND الخاص بالسيرفو موصول بالأرضي المشترك.
الشاشة تعرض بكسلات عشوائية أو نصًا مُزاحًا
تحقّق من شريحة التحكم ومقاس الوحدة لديك. كثير من وحدات 1.3 بوصة تستخدم الشريحة SH1106 التي تحتاج إلى مكتبة مختلفة، كما أن وحدة 128×32 تحتاج إلى SCREEN_HEIGHT 32. إذا عدّلت الكود، فتحقّق من أن display.display() ما زال يُستدعى بعد أوامر الطباعة.
إعادة تشغيل النظام عند تحرك محركَي السيرفو معًا
السبب المعتاد هو عدم كفاية التغذية: فمحركا سيرفو يبدآن الحركة أو يتوقفان (Stall) في الوقت نفسه يسحبان تيارًا أكبر مما يوفّره منفذ USB. غذِّ محركات السيرفو من مزود طاقة خارجي 5 V كما هو موضح في ملاحظات التوصيل، ولا توصّل منه إلى Arduino سوى الأرضي.
قيم عصا التحكم تبدو مشوشة
تعطي بعض وحدات عصا التحكم قراءات تناظرية مشوشة. لتنعيمها، اقرأ كل محور عدة مرات (أربع مرات مثلًا) واستخدم المتوسط، أو أضف المنطقة الميتة من الخطوة 3. واجعل أسلاك عصا التحكم قصيرة وبعيدة عن أسلاك السيرفو.
الأسئلة الشائعة
نعم. يعمل هذا المشروع مع أي لوحة Arduino تحتوي على مدخلين تناظريين وطرفين رقميين حرّين. تولّد مكتبة Servo إشارتها باستخدام مؤقّت (Timer) على أي طرف رقمي، لذا لا تحتاج إلى أطراف PWM العتادية المميزة بالرمز ~ على اللوحة. وتعمل أي لوحة Arduino بجهد 5 V لها الأطراف نفسها دون أي تعديل، مثل Nano. وتعمل لوحتا Mega وLeonardo أيضًا، لكن أطراف I2C فيهما ليست A4 وA5 (Mega: 20 و21، Leonardo: 2 و3)، لذا انقل سلكَي SDA وSCL وفقًا لذلك.
لعصا التحكم الواحدة محوران، لذا فهي تتحكم بمحركَي سيرفو. تحتوي لوحة Uno على ستة مداخل تناظرية (من A0 إلى A5)، لكن A4 وA5 تحملان إشارات I2C لشاشة OLED، لذا يمكن استخدام عصوَي تحكم (أربعة محركات سيرفو) إلى جانب الشاشة. ولمزيد من محركات السيرفو، استخدم زر SW لتبديل عصا التحكم بين أزواج السيرفو، أو أضف لوحة قيادة السيرفو PCA9685، التي تتحكم بما يصل إلى 16 محرك سيرفو عبر I2C.
لا. تتبع محركات السيرفو عصا التحكم من دون الشاشة، لأن display.begin() لا يتحقق مما إذا كانت هناك شاشة موصولة. وتسهّل شاشة OLED الاختبار والمعايرة، لأنها تعرض الزاوية المرسلة إلى كل سيرفو.
نعم، لكن محرك MG996R يسحب تيارًا أكبر بكثير: تذكر TowerPro أن تيار التوقف يبلغ 2.5 A عند 6 V. اختر مزود الطاقة الخارجي بحيث يكفي لتيار التوقف لكلا المحركين. يبقى الكود كما هو، لأن نوعَي السيرفو يستخدمان إشارة التحكم نفسها.
المصادر والخطوات التالية
شروحات OmArTronics ذات الصلة
- دليل التحكم بالسيرفو مع Arduino: SG90 وPWM وPCA9685: طريقة عمل محركات السيرفو الصغيرة، وإشارة PWM، ولوحة قيادة السيرفو PCA9685.
- أساسيات برمجة Arduino: التوصيلات، والبرامج (Sketches)، وArduino IDE للمستخدمين الجدد.
- شرح جهاز التحكم عن بُعد بالأشعة تحت الحمراء (IR) مع Arduino: تحكّم في LED، ثم أضف بابًا يعمل بالسيرفو: جهاز تحكم عن بعد بالأشعة تحت الحمراء (IR) يتحكم بمصباح LED وبباب يعمل بمحرك سيرفو.
- ذراع روبوتية بست درجات حرية (6-DOF) اصنعها بنفسك: الطباعة ثلاثية الأبعاد (3D) والتوصيل والبرمجة: ذراع مطبوعة بالطباعة ثلاثية الأبعاد (3D) بستة مفاصل سيرفو (تعني 6-DOF ست درجات حرية).
- ذراع روبوتية بست درجات حرية (6-DOF) اصنعها بنفسك مع تحكم عبر البلوتوث: ذراع روبوتية يُتحكم بها لاسلكيًا من الهاتف الذكي عبر بلوتوث.
- شرح كامل لوحدة البلوتوث HC-05/HC-06 مع Arduino: التوصيلات والكود لوحدتَي HC-05 وHC-06.
- رادار Arduino باستخدام HC-SR04 ومحرك سيرفو: محرك سيرفو يحرّك مستشعر الموجات فوق الصوتية HC-SR04 ذهابًا وإيابًا.
- قفل باب بكلمة مرور مع Arduino ولوحة مفاتيح وشاشة LCD: رمز يُدخَل عبر لوحة مفاتيح (Keypad) يفتح قفلًا يعمل بمحرك سيرفو.
التطويرات المقترحة التالية
- استخدم الطرف SW في عصا التحكم لحفظ مواضع السيرفو أو للتبديل بين أوضاع التحكم.
- استبدل عصا التحكم بتطبيق على الهاتف الذكي يتواصل مع Arduino عبر وحدة بلوتوث HC-05.
- ابنِ حامل كاميرا بمحورين وتحكّم به باستخدام هذه الدائرة.
- أضف المزيد من محركات السيرفو وعصي التحكم لبناء ذراع روبوتية بمفاصل أكثر.
- خزّن مواضع السيرفو في EEPROM، وهي ذاكرة Arduino التي تحتفظ بالبيانات دون تغذية كهربائية، ثم أعد تنفيذها كتسلسل حركة.
