كل ما يتعلق بـESP32 – الجزء الأول
لمحة عامة والأدوات و الليد الوامض
أجزاء سلسلة كل ما يتعلق بـESP32
- الجزء الأول: لمحة عامة والأدوات و الليد الوامض
- الجزء الثاني: طباعة الرسائل وأساسيات الواي فاي
- الجزء الثالث: الـTCP والـHTTP عبر الـWiFi
- الجزء الرابع: أساسيات Bluetooth Low Energy (BLE)
متعلقات
ESP32 هي System on Chip SoC تحوي طرفيات غنيّة جداً، حيث تحصي الداتاشيت أكثر من 19 طرفية داخل هذه الآيسية إلى جانب طرفيتي البلوتوث والواي فاي. ليس هذا فقط، بل أيضاً تحوي ESP32 (نسخ محدّدة) على نواتي معالجة dual core 32-bit microprocessor. في ظل هذا التنوع الكبير كان لابد من تسمية السلسلة بـ “كل ما يتعلق بـESP32” لكثرة المميزات التي يجب اكتشافها.
لمحة عامة
طلب ESP32
تختلف إصدارات الـESP32 بالتالي:
- عدد الأنوية cores.
- وجود ذاكرة فلاش 16-Mbit داخل الآيسية.
- حجم الغلاف للآيسية.
توفر الشركة المصمّمة Expressif العديد من الموديولات modules الجاهزة للاستخدام والتي تحوي آيسية ESP32 ومعها كل العناصر المتفرّقة اللازمة لعمل الآيسية، من مقاومات ومكثفات وذاكرة فلاش وذاكرة رام (بعض الموديولات) وهوائي مطبوع PCB Antenna (بعض الموديولات)، وعلى كل الأحوال يمكن مراجعة الصفحة الرسمية للموديولات المتوفرة.
Module Name | ESP32 Version | External Memories | Antenna(s) |
---|---|---|---|
ESP32-WROOM-32 | ESP32-D0WD | 4-MB flash memory | PCB antenna |
ESP32-WROOM-32D | ESP32-D0WD | 4-MB flash memory | PCB antenna |
ESP32-WROOM-32U | ESP32-D0WD | 4-MB flash memory | IPEX antenna |
ESP32-WROVER | ESP32-D0WD | 4-MB flash memory & 4-MB SRAM memory | PCB antenna |
ESP32-WROVER-I | ESP32-D0WD | 4-MB flash memory & 4-MB SRAM memory | PCB antenna & IPEX antenna |
ESP32-SOLO-1 | ESP32-S0WD | 4-MB flash memory | PCB antenna |
نجد من الجدول أعلاه (حتى هذا الوقت) أن جميع الموديولات تستخدم نفس رقم الـESP32 وهو ESP32-D0WD (باستثناء ESP32-SOLO-1 الذي يستخدم ESP32-S0WD وحيد النواة) ويبقى الشيء الذي تتمايز فيه:
- نوع الهوائي.
- وجود ذاكرة رام حجم 4 ميغا بايت من عدمه.
إن آخر شكل للـESP32 يمكن الحديث عنه هو ESP32-PICO-D4 وهو نظام داخل غلاف System-in-Package (SiP) حيث يحوي الـESP32 وأيضاً كل العناصر المطلوبة من مكثفات الفلترة والذاكرة فلاش والمهتز وتقريباً كل شيء ما عدا الهوائي.
الشيء الأخير الذي يجب الكلام عنه عن طلب ESP32 هو اللوحات التطويرية وهي أكثر من أن تحصى، فإما يتم استخدام دارة تطويرية من تصميم الشركة المصنعة نفسها Expressif Dev KITS أو من شركات مصممة متخصّصة معروفة مثل SparkFun ESP32 Thing أو شراء دارة تطويرية صينية رخيصة الثمن كالتي بحوزتي الآن Goouuu-ESP32 Development Board.
ميزات أساسية
توفر ESP32 خيارين للاتصال اللاسلكي وهما: الواي فاي 802.11 b/g/n والبلوتوث نسخة 4.2 كما أن مواصفات المعالج والذواكر المتاحة أمر مهم حيث يتوفر Xtensa single-/dual-core 32-bit LX6 microprocessor(s) مع ذواكر داخلية 448 kB ROM و 520 kB SRAM ويدعم ESP32 ذواكر خارجية بحجم 4 x 16 MB عبر واجهة QSPI. يحوي ESP32 ذاكرة كاش ووحدات حماية وتنظيم الذاكرة MPU و MMU وذلك لتنظيم النفاذ للذواكر الداخلية والخارجية.
هذا الوحش الصيني لا يحوي طرفيات فقط بل أيضاً حساسات داخلية وهي:
- حساس حرارة بمجال -40°C إلى 125°C.
- 10 أرجل قابلة للعمل كحساسات سعوية (حساس لمس) capacitive-sensing.
- حساس الأثر Hall وبهذا باستخدام مغناطيس ودارة ESP32 يمكن صنع تطبيق تحسس لحالة الباب.
لتعداد بعض الطرفيات الأخرى المتاحة:
- 34 دخل/خرج.
- 18 قناة للتحويل التماثلي الرقمي ADC بدقة 12 بت.
- قناتين للتحويل الرقمي التماثلي DAC بدقة 8 بت.
- واجهة إيثرنت Ethernet MAC.
- SD/SDIO/MMC host controller
- SDIO/SPI Slave Controller
- ثلاث وجهات تسلسلية UART.
- واجهتين I2C.
- واجهتين I2S.
- ثماني أقنية لاستقبال وإرسال الإشارة IR.
- عدّاد نبضات.
- Pulse Width Modulation (PWM)
- متحكم النفاذ المباشر للذاكرة DMA.
- مجموعتي عدادات. كل مجموعة 2 x 64-bit.
نهايةً، إن مصممي ESP32 قد أبدوا انتباهاً جيداً لموضوع توفير الطاقة والذي شمل تضمين متحكم خاص للعمل في نمط التوفير الأقصى ultra-low-power processor وسموه ULP co-processor ويحوي ذاكرة رام بحجم 8 كيلو بايت للبيانات والتعليمات معاً. هذا المعالج المساعد له بيئته التطويرية الخاصة من ناحية الأدوات والـtoolchain ولمزيد من المعلومات يمكن التحقق من الدليل الرسمي.
الأدوات البرمجية Toolchain
يتوفر لبرمجة الـESP32 وكسابقتها ESP8266 خيارين أساسيين وهما استخدام حزمة أدوات التطوير(كيت) الرسمية من الشركة official SDK أو استخدام نواة الأردوينو لـESP32 على الرغم أن نواة الأردوينو فعلياً مكتوبة باستخدام الكيت التطويري الرسمي ولكن مع توفير طبقة تجريد للمطوّر.
اخترتُ في هذه السلسلة الكيت التطويري الرسمي لكثير من الأسباب المتعلقة بالأداء والبعد عن المشاكل البرمجية ولتحقيق فهماً أعمق. خلافاً لـESP8266 فإن ESP32 لا توفر كيت تطويري مع/بدون نظام RTOS وإنما نظام FreeRTOS معتمد بشكل أساسي في هذه الكيت التطويرية. إن الاسم الرسمي لهذه الكت التطويرية هو ESP-IDF (Espressif IoT Development Framework)، ومما لا شك فيه أنه يوجد العديد من الخيارات الأخرى لكتابة البرنامج بلغات أخرى مثل الجافا سكربت أو البايثون وفي صفحة الـESP32 بموقع الويكيبيديا قائمة جيدة حول هذه الخيارات.
إنه من غير المجدي إعادة كتابة خطوات تحميل وتهيئة سلسلة الأدوات toolchain والـ ESP-IDF فهي موثّقة بشكل جيد جداً رسمياً، وكتأكيد يجب أن يكون في حاسب القارئ:
- سلسلة الأدوات toolchain.
- الـ ESP-IDF من مستودع Expressif.
إن الخرج التالي يجب أن يظهر بعد تنزيل وتهيئة ناجحة لما سبق عبر إرسال الأوامر التالية عبر التيرمينال في لينكس أو MinGW في الويندوز الموجود داخل ESP-IDF:
- Command: echo $IDF_PATH
Output: \your\path\to\esp-idf - Command: printenv PATH
Output: /home/user-name/esp/xtensa-esp32-elf/bin
الليد الوامض Blinking LED
لأخذ قالب جاهز لمشروع ESP32، فإننا ننسخ مشروع من الأمثلة المتاحة في ESP-IDF وذلك باستخدام التعليمة الخاصة بإنشاء مجلد للمشاريع وثم نسخ المشروع إليه باسم جديد وهو first_app.
mkdir esp32-workspace cp -r $IDF_PATH/examples/get-started/hello_world esp32-workspace/first_app
لنفهم بداية وقبل تعلم كيفية بناء الكود وبرمجته على ESP32 كيفية كتابة الكود الأول لتحقيق ليد وامض.
ملفات الترويس
#include "freertos/FreeRTOS.h" #include "freertos/task.h"
يستخدم الكود تابع من الـFreeRTOS، لذلك يلزمنا الملفين السابقين إضافة إلى الملف التالي والذي يحوي توابع للتعامل مع الدخل/الخرج GPIO.
#include "driver/gpio.h"
التابع app_main
هذا التابع هو التابع الرئيسي الذي يحوي البرنامج. طالما أن ESP-IDF تستخدم FreeRTOS، فإنه يمكننا إنشاء اجرائية task خاصة بعملية الوميض. يتم إنشاء هذه الإجرائية باستدعاء التابع xTaskCreate. قد لا يكون القارئ مطلعاً على FreeRTOS لذلك كلما أحتجنا لشيء معين منه يتم شرحه في وقته ولنبدأ بـ xTaskCreate والذي له التعريف التالي وأقتبس هنا من دليل FreeRTOS الرسمي reference manual :
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, unsigned short usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask );
This function creates a new instance of a task, and takes the following parameters:
- pvTaskCode: Tasks are simply C functions that never exit and, as such, are normally implemented as an infinite loop. The pvTaskCode parameter is simply a pointer to the function (in effect, just the function name) that implements the task.
- pcName: A descriptive name for the task. This is mainly used to facilitate debugging, but can also be used in a call to xTaskGetHandle() to obtain a task handle.
- usStackDepth: Each task has its own unique stack that is allocated by the kernel to the task when the task is created. The usStackDepth value tells the kernel how large to make the stack.
- pvParameters: Task functions accept a parameter of type ‘pointer to void’ ( void* ). The value assigned to pvParameters will be the value passed into the task.
- uxPriority: Defines the priority at which the task will execute. Priorities can be assigned from 0, which is the lowest priority, to (configMAX_PRIORITIES – 1), which is the highest priority.
- pxCreatedTask: pxCreatedTask can be used to pass out a handle to the task being created.
باختصار يهمنا وسيط واحد بشكل خاص وهو أول وسيط، أي اسم التابع الذي سيتم استدعاءه من قبل المجدول الخاصة بنظام التشغيل كلّما حان وقت التنفيذ الخاص به وأيضاً الوسيط الثاني وهو اسم الإجرائية ولكن ليس لها أي تأثير حالياً ولا تهمنا.
xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
تابع blink_task
void blink_task(void *pvParameter) { gpio_pad_select_gpio(BLINK_GPIO); gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); while(1) { gpio_set_level(BLINK_GPIO, 0); vTaskDelay(1000 / portTICK_PERIOD_MS); gpio_set_level(BLINK_GPIO, 1); vTaskDelay(1000 / portTICK_PERIOD_MS); } }
إن كود هذا التابع سهل ومباشر كأي كود تعامل مع مداخل/مخارج، حيث يتضمن اختيار رقم الرجل والنمط وسوية الخرج وكل هذا عبر توابع من ESP-IDF.
لنرَ الآن ما مهمّة الـ vTaskDelay وسأقتبس مرة أخرى من الدليل الرسمي للـFreeRTOS :
“vTaskDelay Places the task that calls vTaskDelay() into the Blocked state for a fixed number of tick interrupts”. portTICK_PERIOD_MS is macro for the period of each tick in mS, so for 1000mS delay, we need 1000/portTICK_PERIOD_MS of ticks.
وبالتالي هو مسؤول عن نقل الإجرائية إلى حالة الانتظار لمدة تساوي عدد عدّات معين ولتوليد تأخير 1000 ميلي ثانية فإن عدد العدّات يساوي 1000 تقسيم زمن العدّة الواحدة بالميلي ثانية وهو ثابت موجود في النظام.
لنرَ الآن المثال كاملاً:
#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #define BLINK_GPIO 1 void blink_task(void *pvParameter) { gpio_pad_select_gpio(BLINK_GPIO); gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); while(1) { gpio_set_level(BLINK_GPIO, 0); vTaskDelay(1000 / portTICK_PERIOD_MS); gpio_set_level(BLINK_GPIO, 1); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void app_main() { xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL); }
بناء الكود
يجب وضع الكود السابق في المسار التالي first_app/main/first_app_main.c ويجب أن يكون الـ terminal مشير للمجلد first_app. إن الأمر التالي make سيؤدي إلى تشغيل واجهة رسومية بسيطة:
توفر هذه الواجهة الكثير من الخيارات والتي سنكتشفها تباعاً لاحقاً ولكن ما يهمنا الآن هو تحديد اسم ورقم المنفذ الموصول إليه الدارة وذلك من أجل البرمجة. من الممكن حفظ الإعدادات من أجل اختصار هذه الخطوة في عملية البناء القادمة. تم توضيح هذه الخطوات في التسجيل التالي:
خيار آخر متاح لبناء وبرمجة الدارة مباشرة هو “make flash” ولإرغام الواجهة الرسومية للظهور مجدداً “make menuconfig”.
تبدو عملية بناء وبرمجة صحيحة كما يلي:
اقرأ أكثر
هذا كل ما هنالك في هذا الجزء نلتقي في الجزء الثاني. في هذه الأثناء أنصح القرّاء بالاطلاع على كتاب كولبان Kolban’s Book on ESP32 وكما هو مذكور في مقدمة الكتاب، فهو دفتر ملاحظات أكثر من كونه كتاب ولكن يحوي على ملاحظات قيّمة ومتنوعة وتقريباً حول كل شيء يتعلق بالـESP32 مع شرح لكثير من الأساسيات. مرجع آخر يُنصح به بشدة وهو سلسلة موجودة في موقع آخر وأيضاً تناقش تقريباً كل شيء عن ESP32 وباستخدام الـESP-IDF. يبقى أخيراً المرجع الأساسي رفيق الدرب الرئيسي في تعلّم الـ ESP-IDF.
أجزاء سلسلة كل ما يتعلق بـESP32
- الجزء الأول: لمحة عامة والأدوات و الليد الوامض
- الجزء الثاني: طباعة الرسائل وأساسيات الواي فاي
- الجزء الثالث: الـTCP والـHTTP عبر الـWiFi
- الجزء الرابع: أساسيات Bluetooth Low Energy (BLE)
متعلقات