السبت، 20 مايو 2023

استكشاف التعلم الآلي باستخدام XIAO ESP32S3 الجديد

 إنشاء مشروع TinyML اكتشاف الشذوذ وتصنيف الحركة باستخدام IMU MPU2060



الأشياء المستخدمة في هذا المشروع

مكونات الأجهزة

Seeed Studio XIAO ESP32S3

مستشعر DFRobot 6 DOF - MPU6050

اردوينو IDE

Edge Impulse Studio

قصة

مقدمة

في تعليمي الأخير ، أصبح TinyML سهلًا: تصنيف الصور ، استكشفنا تصنيف الصور على الجهاز الصغير الجديد لعائلة Seeed XIAO ، ESP32S3 Sense. يحتوي جهاز Sense على كاميرا وميكروفون مدمجين ، ولكن ماذا يحدث إذا كنت تريد نوعًا آخر من أجهزة الاستشعار مثل IMU؟ لا مشكلة! إحدى الميزات الرائعة لـ XIAO ESP32S3 هي دبابيسه المتعددة المتوفرة كناقل I2C (دبابيس SDA / SCL).



تثبيت XIAO ESP32S3 Sense على Arduino IDE

بعد تعليمي الأخير ، يجب أن يكون الجهاز مثبتًا على Arduino IDE. إذا لم يكن الأمر كذلك ، فلنقم بمراجعة سريعة:


في Arduino IDE ، انتقل إلى ملف> تفضيلات ،  URL:

في الحقل ==> عناوين URL الإضافية لمدير اللوحات


بعد ذلك ، افتح مدير المجالس. اذهب إلى Tools> Board> Boards Manager ... وادخل مع esp32. حدد الحزمة الأكثر تحديثًا وقم بتثبيتها:

في الأدوات ، حدد اللوحة (XIAO ESP32S3):


أخيرًا وليس آخرًا ، حدد المنفذ الذي تم توصيل ESP32S3 به.


هذا هو! يجب أن يكون الجهاز على ما يرام. للتأكد ، قم بتشغيل رسم Blink.

تثبيت IMU

يمكنك تحديد IMU الخاص بك من عدة أجهزة موجودة في السوق ، مثل ADXL362 (3 محاور) ، MAX21100 (6 محاور) ، MPU6050 (6 محاور) ، LIS3DHTR (3 محاور) ، أو LCM20600 (6 محاور) ) ، وهو جزء من Seeed Grove - IMU 9DOF (lcm20600 + AK09918).

بالنسبة لهذا المشروع ، سنستخدم وحدة IMU ، MPU6050 (أو 6500) ، وحدة منخفضة التكلفة (أقل من 2.00 دولارًا أمريكيًا) مقياس تسارع / جيروسكوب سداسي المحاور.

في الختام ، سأعود أيضًا باستخدام LCM20600

MPU-6500 عبارة عن جهاز تتبع الحركة سداسي المحاور يجمع بين جيروسكوب ثلاثي المحاور ومقياس تسارع ثلاثي المحاور ومعالج الحركة الرقمية (DMP) في حزمة صغيرة 3 × 3 × 0.9 مم. كما تتميز أيضًا بـ 4096 بايت FIFO يمكنها تقليل حركة المرور على واجهة الناقل التسلسلي وتقليل استهلاك الطاقة من خلال السماح لمعالج النظام بتفجير بيانات مستشعر القراءة ثم الانتقال إلى وضع الطاقة المنخفضة.

من خلال ناقل مستشعر I2C المخصص ، يقبل MPU-6500 بشكل مباشر المدخلات من أجهزة I2C الخارجية. MPU-6500 ، مع تكامله المكون من 6 محاور ، و DMP على الرقاقة ، والبرامج الثابتة لمعايرة وقت التشغيل ، تمكن المصنّعين من التخلص من الاختيار المكلف والمعقد ، والتأهيل ، والتكامل على مستوى النظام للأجهزة المنفصلة ، مما يضمن أداء الحركة الأمثل للمستهلكين . تم تصميم MPU-6500 أيضًا للتفاعل مع أجهزة استشعار رقمية متعددة غير تعمل بالقصور الذاتي ، مثل مستشعرات الضغط ، على منفذ I2C الإضافي الخاص بها.



عادةً ما تكون المكتبات المتاحة مخصصة لـ MPU6050 ، لكنها تعمل لكلا الجهازين.

توصيل HW


قم بتوصيل IMU بـ XIAO وفقًا للرسم البياني أدناه:


MPU6050 SCL -> XIAO D5

MPU6050 SDA -> XIAO D4

MPU6050 VCC-> XIAO 3.3 فولت

MPU6050 GND -> XIAO GND


قم بتثبيت المكتبة

انتقل إلى Arduino Library Manager واكتب MPU6050. قم بتثبيت أحدث إصدار.



قم بتنزيل المخطط MPU6050_Acc_Data_Acquisition.in:

/*
* Based on I2C device class (I2Cdev) Arduino sketch for MPU6050 class by Jeff Rowberg <jeff@rowberg.net>
* and Edge Impulse Data Forwarder Exampe (Arduino) - https://docs.edgeimpulse.com/docs/cli-data-forwarder
*
* Developed by M.Rovai @11May23
*/

#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

#define FREQUENCY_HZ 50
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
#define ACC_RANGE 1 // 0: -/+2G; 1: +/-4G

// convert factor g to m/s2 ==> [-32768, +32767] ==> [-2g, +2g]
#define CONVERT_G_TO_MS2 (9.81/(16384.0/(1.+ACC_RANGE)))

static unsigned long last_interval_ms = 0;

MPU6050 imu;
int16_t ax, ay, az;

void setup() {

Serial.begin(115200);


// initialize device
Serial.println("Initializing I2C devices...");
Wire.begin();
imu.initialize();
delay(10);

// // verify connection
// if (imu.testConnection()) {
// Serial.println("IMU connected");
// }
// else {
// Serial.println("IMU Error");
// }
delay(300);

//Set MCU 6050 OffSet Calibration
imu.setXAccelOffset(-4732);
imu.setYAccelOffset(4703);
imu.setZAccelOffset(8867);
imu.setXGyroOffset(61);
imu.setYGyroOffset(-73);
imu.setZGyroOffset(35);

/* Set full-scale accelerometer range.
* 0 = +/- 2g
* 1 = +/- 4g
* 2 = +/- 8g
* 3 = +/- 16g
*/
imu.setFullScaleAccelRange(ACC_RANGE);
}

void loop() {

if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();

// read raw accel/gyro measurements from device
imu.getAcceleration(&ax, &ay, &az);

// converting to m/s2
float ax_m_s2 = ax * CONVERT_G_TO_MS2;
float ay_m_s2 = ay * CONVERT_G_TO_MS2;
float az_m_s2 = az * CONVERT_G_TO_MS2;

Serial.print(ax_m_s2);
Serial.print("\t");
Serial.print(ay_m_s2);
Serial.print("\t");
Serial.println(az_m_s2);
}
}

بعض التعليقات حول الكود:

لاحظ أن القيم التي تم إنشاؤها بواسطة مقياس التسارع والجيروسكوب لها نطاق: [-32768 ، +32767] ، لذلك على سبيل المثال ، إذا تم استخدام نطاق مقياس التسارع الافتراضي ، فيجب أن يكون النطاق في Gs: [-2g ، + 2g]. لذا ، "1G" تعني 16384.

للتحويل إلى m / s2 ، على سبيل المثال ، يمكنك تحديد ما يلي:

#define CONVERT_G_TO_MS2 (9.81/16384.0)

في الكود ، تركت خيارًا (ACC_RANGE) ليتم ضبطه على 0 (+/- 2G) أو 1 (+/- 4G). سوف نستخدم +/- 4G ؛ يجب أن يكون ذلك كافيا بالنسبة لنا. في هذه الحالة.

سنلتقط بيانات مقياس التسارع على تردد 50 هرتز ، وسيتم إرسال بيانات التسارع إلى المنفذ التسلسلي كمتر لكل ثانية مربعة (م / ث 2).

عند تشغيل الكود مع وضع وحدة IMU فوق الجدول ، يجب أن تكون بيانات مقياس التسارع المعروضة على Serial Monitor: 0.00 و 0.00 و 9.81. إذا كانت القيم مختلفة كثيرًا ، فيجب عليك معايرة وحدة IMU.

يمكن معايرة MCU6050 باستخدام المخطط: mcu6050-calibration.ino.

قم بتشغيل الكود. سيتم عرض ما يلي على Serial Monitor:


أرسل أي حرف (في المثال أعلاه ، "x") ، ويجب أن تبدأ المعايرة.

لاحظ أن رسالة فشل اتصال MPU6050. تجاهل هذه الرسالة. لسبب ما ، لا يُرجع imu.testConnection () النتيجة الصحيحة.

في النهاية ، ستتلقى قيم الإزاحة لاستخدامها في جميع رسوماتك التخطيطية:


خذ القيم واستخدمها في الإعداد:

//Set MCU 6050 OffSet Calibration 
imu.setXAccelOffset(-4732);
imu.setYAccelOffset(4703);
imu.setZAccelOffset(8867);
imu.setXGyroOffset(61);
imu.setYGyroOffset(-73);
imu.setZGyroOffset(35);

الآن ، قم بتشغيل المخطط MPU6050_Acc_Data_Acquisition.in:

بمجرد تشغيل الرسم أعلاه ، افتح Serial Monitor:


أو تحقق من الراسمة:



حرك جهازك في المحاور الثلاثة ، يجب أن ترى الاختلاف على الراسمة:


نموذج تصنيف الحركة TinyML

في برنامجنا التعليمي ، سنقوم بمحاكاة الضغوط الميكانيكية في النقل. ستكون مشكلتنا في تصنيف أربع فئات للحركة:

البحرية (المنصات في القوارب)

أرضية (لوحات في شاحنة أو قطار)

الرفع (يتم التعامل مع اللوحات بواسطة رافعة شوكية)

الخمول (لوحات في مخازن)

لذا ، للبدء ، يجب أن نجمع البيانات. بعد ذلك ، ستوفر مقاييس التسارع البيانات الموجودة على اللوحة (أو الحاوية).



من الصور أعلاه ، يمكننا أن نرى أن الحركات الأفقية في المقام الأول يجب أن ترتبط بـ "الطبقة الأرضية" ، والحركات الرأسية مع "فئة الرفع" ، ولا يوجد نشاط مع "فئة الخمول" ، وتتحرك على جميع المحاور الثلاثة إلى الطبقة البحرية.

توصيل الجهاز بـ Edge Impulse

لجمع البيانات ، يجب علينا أولاً توصيل أجهزتنا بـ Edge Impulse Studio ، والذي سيتم استخدامه أيضًا للمعالجة المسبقة للبيانات ، والتدريب على النموذج ، والاختبار ، والنشر.

اتبع الإرشادات الواردة هنا لتثبيت Node.js و Edge Impulse CLI على جهاز الكمبيوتر الخاص بك.

بمجرد أن لا يكون XIAO ESP32S3 لوحة تطوير مدعومة بالكامل من Edge Impulse ، يجب علينا ، على سبيل المثال ، استخدام CLI Data Forwarder لالتقاط البيانات من المستشعر الخاص بنا وإرسالها إلى الاستوديو ، كما هو موضح في هذا الرسم البياني:


يمكنك أيضًا التقاط بياناتك "في وضع عدم الاتصال" ، وتخزينها على بطاقة SD أو إرسال البيانات عبر Bluetouth أو Wifi لجهاز الكمبيوتر الخاص بك. في هذا الفيديو ، يمكنك التعرف على طرق بديلة لإرسال البيانات إلى Edge Impulse Studio.

قم بتوصيل جهازك بالمنفذ التسلسلي وقم بتشغيل الكود السابق لالتقاط بيانات IMU (مقياس التسارع) ، "طباعتها" على المسلسل. سيسمح هذا لبرنامج Edge Impulse Studio "بالتقاطها".

انتقل إلى صفحة Edge Impulse وقم بإنشاء مشروع.


الحد الأقصى لطول اسم مكتبة Arduino هو 63 حرفًا. لاحظ أن الاستوديو سيقوم بتسمية المكتبة النهائية باستخدام اسم مشروعك مع تضمين "_inference" لها. في حالتي ، لن يعمل الاسم الذي أختاره في البداية عندما أحاول نشر مكتبة Arduino ، لأنه سينتج عنه 64 حرفًا. لذا ، أحتاج إلى تغييره ، بإزالة جزء "اكتشاف الشذوذ".

بعد ذلك ، ابدأ في CLI Data Forwarder على جهازك الطرفي ، وأدخل (إذا كانت هذه هي المرة الأولى) الأمر التالي:

$ edge-impulse-data-forwarder --clean
بعد ذلك ، أدخل بيانات اعتماد EI الخاصة بك ، واختر مشروعك والمتغيرات وأسماء الأجهزة:


انتقل إلى مشروع EI الخاص بك وتحقق مما إذا كان الجهاز متصلاً (يجب أن تكون النقطة خضراء):


جمع البيانات

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


تخيل الآن أن الحاوية الخاصة بك على قارب ، وتواجه محيطًا غاضبًا ، على متن شاحنة ، وما إلى ذلك:

البحرية (المنصات في القوارب)



يمكنك التقاط ، على سبيل المثال ، دقيقتان (اثنا عشر عينة كل منها 10 ثوانٍ) للفصول الأربعة. باستخدام "النقاط الثلاث" بعد كل واحدة من العينات ، حدد 2 ، وقم بنقلها لمجموعة الاختبار (أو استخدم أداة الانقسام / الاختبار التلقائية في علامة التبويب منطقة الخطر في لوحة القيادة). أدناه يمكنك رؤية مجموعات البيانات الناتجة:


المعالجة المسبقة للبيانات

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


يمكننا أن نرى 10 ثوانٍ من بيانات مقياس التسارع التي تم التقاطها بمعدل عينة (SR) يبلغ 50 هرتز. ستلتقط نافذة مدتها ثانيتان 300 نقطة بيانات (3 محاور × ثانيتين × 50 عينة). سنقوم بتمرير هذه النافذة كل 200 مللي ثانية ، لإنشاء مجموعة بيانات أكبر حيث يحتوي كل مثيل على 300 ميزة أولية.


يجب عليك استخدام أفضل SR لحالتك ، مع الأخذ في الاعتبار نظرية نيكويست ، التي تنص على أنه يجب أخذ عينات من الإشارة الدورية بأكثر من ضعف أعلى مكون تردد للإشارة.

تعد المعالجة المسبقة للبيانات مجالًا صعبًا للتعلم الآلي المضمن. ومع ذلك ، تساعد Edge Impulse في التغلب على هذا من خلال خطوة المعالجة المسبقة لمعالجة الإشارات الرقمية (DSP) ، وبشكل أكثر تحديدًا ، الميزات الطيفية.


في الاستوديو ، ستكون مجموعة البيانات هذه مدخلات من كتلة التحليل الطيفي ، والتي تعد ممتازة لتحليل الحركة المتكررة ، مثل البيانات من مقاييس التسارع. ستقوم هذه الكتلة بتنفيذ DSP (معالجة الإشارات الرقمية) ، واستخراج ميزات مثل "FFT" أو "Wavelets". في الحالة الأكثر شيوعًا ، FFT ، تكون الميزات الإحصائية للمجال الزمني لكل محور / قناة هي:

RMS

انحراف

التفرطح

والميزات الطيفية لمجال التردد لكل محور / قناة هي:

القوة الطيفية

انحراف

التفرطح

لذلك ، على سبيل المثال ، بالنسبة لطول FFT البالغ 32 نقطة ، سيكون الناتج الناتج من كتلة التحليل الطيفي 21 ميزة لكل محور (إجمالي 63 ميزة).

هذه الميزات الـ 63 ستكون موتر الإدخال لمصنف الشبكة العصبية ونموذج كشف الشذوذ (K-Means).

يمكنك معرفة المزيد عن البحث في البرنامج التعليمي TinyML تحت الغطاء: التحليل الطيفي.

تصميم النموذج

سيكون المصنف الخاص بنا عبارة عن شبكة عصبية كثيفة (DNN) ستحتوي على 63 خلية عصبية في طبقة الإدخال ، وطبقتين مخفيتين تحتويان على 20 و 10 خلايا عصبية ، وطبقة إخراج بها أربعة خلايا عصبية (واحدة لكل فئة) ، كما هو موضح هنا:


تصميم النبضة

يأخذ الدافع البيانات الأولية ، ويستخدم معالجة الإشارات لاستخراج الميزات ، ثم يستخدم كتلة التعلم لتصنيف البيانات الجديدة.

نستفيد أيضًا من النموذج الثاني ، K-mean ، الذي يمكن استخدامه لاكتشاف الشذوذ. إذا تخيلنا أنه يمكن أن يكون لدينا فئاتنا المعروفة باسم العناقيد ، فإن أي عينة لا يمكن أن تلائم ذلك يمكن أن تكون شاذة أو شذوذًا (على سبيل المثال ، حاوية تتدحرج من سفينة في المحيط).


لذلك ، يمكننا استخدام نفس موتر الإدخال الذي يذهب إلى NN Classifier كمدخل لنموذج K-mean:


فيما يلي تصميم Impulse النهائي الخاص بنا:



توليد الميزات

في هذه المرحلة من مشروعنا ، حددنا طريقة المعالجة المسبقة والنموذج المصمم. حان الوقت الآن لإنجاز المهمة. أولاً ، لنأخذ البيانات الأولية (نوع السلاسل الزمنية) ونحولها إلى بيانات جدولية. انتقل إلى علامة التبويب "الميزات الطيفية" ، وحدد "حفظ المعلمات":


وفي القائمة العلوية ، حدد خيار إنشاء الميزات وزر إنشاء الميزات. سيتم تحويل كل من بيانات النافذة التي تبلغ مدتها ثانيتين إلى نقطة بيانات واحدة تحتوي كل منها على 63 ميزة.

سيعرض مستكشف الميزات هذه البيانات في 2D باستخدام UMAP. التقريب والإسقاط المتشعب الموحد (UMAP) هو أسلوب لتقليل الأبعاد يمكن استخدامه للتصور بشكل مشابه لـ t-SNE ولكن أيضًا لتقليل البعد غير الخطي العام.

يجعل التصور من الممكن التحقق من أن الفئات تقدم فصلًا ممتازًا ، مما يشير إلى أن المصنف يجب أن يعمل بشكل جيد.


اختياريًا ، يمكنك تحليل مدى أهمية كل ميزة من الميزات لفئة واحدة مقارنة بالفئات الأخرى.

تمرين

يتكون نموذجنا من أربع طبقات ، كما هو موضح أدناه:


كمعلمات فائقة ، سوف نستخدم معدل تعلم 0.005 و 20٪ من البيانات للتحقق من صحة 30 حقبة. بعد التدريب يمكننا أن نرى أن الدقة تصل إلى 97٪.


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


اختبارات

باستخدام 20٪ من البيانات المتروكة أثناء مرحلة التقاط البيانات ، يمكننا التحقق من كيفية تعامل نموذجنا مع البيانات غير المعروفة ؛ إن لم يكن 100٪ (ما هو متوقع) ، فإن النتيجة لم تكن جيدة (8٪) ، ويرجع ذلك أساسًا إلى الطبقة الأرضية. بمجرد أن يكون لدينا أربعة فئات (والتي يجب أن يضيف الناتج 1.0) ، يمكننا إعداد حد أدنى للفصل ليتم اعتباره صالحًا (على سبيل المثال ، 0.4):


الآن ، سترتفع دقة الاختبار إلى 97٪


يجب عليك أيضًا استخدام جهازك (الذي لا يزال متصلًا بالاستوديو) وإجراء بعض التصنيف المباشر.

كن على علم أنك هنا ستلتقط بيانات حقيقية بجهازك وتحميلها إلى الاستوديو ، حيث سيتم أخذ الاستدلال باستخدام النموذج المدرب (لكن النموذج ليس في جهازك).

نشر

حان وقت السحر˜! سيقوم الاستوديو بحزم جميع المكتبات المطلوبة ووظائف المعالجة المسبقة والنماذج المدربة وتنزيلها على جهاز الكمبيوتر الخاص بك. يجب عليك تحديد الخيار Arduino Library وفي الأسفل ، حدد Quantized (Int8) و Build. سيتم إنشاء ملف مضغوط وتنزيله على جهاز الكمبيوتر الخاص بك.


في Arduino IDE الخاص بك ، انتقل إلى علامة التبويب Sketch وحدد الخيار Add.ZIP Library واختر ملف zip الذي تم تنزيله بواسطة Studio



الإستنباط

حان الوقت الآن لاختبار حقيقي. سنقوم بعمل استنتاجات منفصلة تمامًا عن الاستوديو. دعنا نغير أحد أمثلة التعليمات البرمجية التي تم إنشاؤها عند نشر مكتبة Arduino.

في Arduino IDE الخاص بك ، انتقل إلى علامة التبويب ملف / أمثلة وابحث عن مشروعك ، وعلى الأمثلة ، حدد nano_ble_sense_accelerometer:


بالطبع ، هذا ليس منتداك ، ولكن يمكننا جعل الكود يعمل مع بعض التغييرات فقط.

على سبيل المثال ، في بداية الكود ، لديك مكتبة مرتبطة بـ Arduino Sense IMU:

/* Includes --------------------------------------------------------------- */
#include <XIAO-ESP32S3-Motion-Classification_inferencing.h>
#include <Arduino_LSM9DS1.h>

غيّر جزء "التضمين" بالرمز المتعلق بوحدة IMU:

#include <XIAO-ESP32S3-Motion-Classification_inferencing.h>
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

تغيير التعاريف الثابتة

/* Constant defines ------------------------------------------------------- */
MPU6050 imu;
int16_t ax, ay, az;

#define ACC_RANGE 1 // 0: -/+2G; 1: +/-4G
#define CONVERT_G_TO_MS2 (9.81/(16384/(1.+ACC_RANGE)))
#define MAX_ACCEPTED_RANGE (2*9.81)+(2*9.81)*ACC_RANGE

في وظيفة الإعداد ، ابدأ وحدة IMU ، واضبط قيم مجموعة الإيقاف والنطاق:

// initialize device
Serial.println("Initializing I2C devices...");
Wire.begin();
imu.initialize();
delay(10);

//Set MCU 6050 OffSet Calibration
imu.setXAccelOffset(-4732);
imu.setYAccelOffset(4703);
imu.setZAccelOffset(8867);
imu.setXGyroOffset(61);
imu.setYGyroOffset(-73);
imu.setZGyroOffset(35);

imu.setFullScaleAccelRange(ACC_RANGE);

في وظيفة الحلقة ، سوف تستقبل المخازن المؤقتة: المخزن المؤقت [ix] والمخزن المؤقت [ix + 1] والمخزن المؤقت [ix + 2] البيانات ثلاثية المحاور التي تم التقاطها بواسطة مقياس التسارع. في الكود الأصلي ، لديك السطر:

IMU.readAcceleration(buffer[ix], buffer[ix + 1], buffer[ix + 2]);
قم بتغييره باستخدام كتلة التعليمات البرمجية هذه:
imu.getAcceleration(&ax, &ay, &az);       
buffer[ix + 0] = ax;
buffer[ix + 1] = ay;
buffer[ix + 2] = az;

يجب عليك تغيير ترتيب الكتلتين التاليتين من التعليمات البرمجية. أولاً ، تقوم بالتحويل إلى البيانات الأولية إلى "متر لكل ثانية مربعة (ms2)" ، متبوعًا باختبار النطاق الأقصى للقبول (الموجود هنا في ms2 ، ولكن في Arduino ، كان في Gs):

buffer[ix + 0] *= CONVERT_G_TO_MS2;
buffer[ix + 1] *= CONVERT_G_TO_MS2;
buffer[ix + 2] *= CONVERT_G_TO_MS2;

for (int i = 0; i < 3; i++) {
if (fabs(buffer[ix + i]) > MAX_ACCEPTED_RANGE) {
buffer[ix + i] = ei_get_sign(buffer[ix + i]) * MAX_ACCEPTED_RANGE;
}
}

وهذا هو عليه! يمكنك الآن تحميل الرمز على جهازك ومتابعة الاستنتاجات. الكود الكامل متاح على GitHub الخاص بالمشروع.

إذا تلقيت خطأ أثناء محاولة تحميل الكود إلى XIAO ESP32S3 على النحو التالي ، فهذا يعني أنه يجب عليك إيقاف تشغيل تسريع ESP NN.


للقيام بذلك ، حدد موقع ei_classifier_config.h في مجلد مكتبة Arduino المُصدَّر: / scr / edge-impulse-sdk / classifier /:



حدد موقع السطر مع #define EI_CLASSIFIER_TFLITE_ENABLE_ESP_NN 1 ، وقم بتغييره من 1 إلى 0:



الآن يجب أن تجرب تحركاتك ، وأن ترى نتيجة استنتاج كل فئة على الصور:


خاتمة

جهاز Seeed XIAO ESP32S هو جهاز صغير عملاق! إنه قوي وغير مكلف ومنخفض الطاقة ومناسب للاستخدام في أكثر تطبيقات التعلم الآلي المضمنة شيوعًا. على الرغم من أن Edge Impulse لا يدعم XIAO BLE Sense رسميًا ، فقد أدركنا أنه يمكن توصيله بسهولة بالاستوديو.


فيما يتعلق بوحدة IMU ، استخدم هذا المشروع MPU6050 منخفض التكلفة ولكن يمكنه أيضًا استخدام وحدات IMU أخرى ، على سبيل المثال ، LCM20600 (6 محاور) ، والتي تعد جزءًا من Seeed Grove - IMU 9DOF (lcm20600 + AK09918).


تتمثل إحدى ميزات الجهاز الأخير في أنه يحتوي على موصل Grove ، والذي يمكن أن يكون مفيدًا في التدريس في حالة استخدامك XIAO مع لوحة تمديد ، كما هو موضح أدناه:


يمكنك اتباع التعليمات الموجودة هنا لتوصيل وحدة IMU بوحدة MCU. لاحظ فقط أنه لاستخدام Grove ICM20600 Accelerometer ، من الضروري تحديث الملفات I2Cdev.cpp و I2Cdev.h التي ستنزلها من المكتبة التي يوفرها Seeed Studio. لذلك ، استبدل كلا الملفين من هذا الرابط. يمكنك أن تجد في مشروع GitHub رسمًا تخطيطيًا لاختبار IMU: Accerometer_test.ino.


في مستودع GitHub الخاص بـ projet ، ستجد الإصدار الأخير من جميع الرموز والمستندات الأخرى: XIAO-ESP32S3 - IMU.