مشروع هندسة عكسية. بدأ مع جهاز المشي Bowflex 22 ولكنه أصبح عامًا لأي جهاز يعمل بنظام Android تبيعه شركة Nautilus Inc. (Nautilus, Bowflex, Schwinn).
ينطبق هذا بشكل رئيسي على جهاز المشي 22 وجهاز المشي 56.
لوحة التحكم بالمحرك مُصنعة من قبل Electronics Way Industry.
بالنظر إلى دليل الخدمة المقدم من شركة Nautilus Inc. (نسخة احتياطية على archive.org):
التركيز بشكل خاص على هذا الجزء:
يمكننا تحديد “كابل الاتصال” الذي يربط وحدة تحكم المحرك ككابل مكون من 5 دبابيس. هناك موصل واحد فقط مكون من 5 دبابيس. لقد قمت بتمييز الكابلات بألوانها المقابلة (البيانات والمفتاح معزولين بصريًا):
لون الكابل | التسمية |
---|---|
أحمر | GND |
أبيض | RXD |
أسود | TXD |
أصفر | +12 |
أخضر | SW |
اللوحة غير متصلة مباشرة بوحدة التحكم بنظام Android.
الموصل المكون من 5 دبابيس الوحيد هو من Molex. البحث في جوجل عن “موصلات Molex الصغيرة” قادني إلى صورة لما يُسمى بـ Molex Micro-Fit 3.0 Single Row (5-Pin)
، والذي يُستخدم لتوصيل لوحة تحكم المحرك:
من خلال إلقاء نظرة على NautilusLauncher.apk
عبر jadx-gui
، يمكنني رؤية أنهم يتواصلون بين جهاز Android اللوحي و”وحدة التحكم العالمية” باستخدام الاتصال التسلسلي بسرعة 230400 باود (باستخدام /dev/ttyS4
). هذا ليس ما نقوم بتحليله هنا. هذا يشير إلى الاتصال بين Android و”وحدة التحكم العالمية”. نحن نحقق في الاتصال بين “وحدة تحكم لوحة الأزرار” و”لوحة تحكم المحرك”، وبالتالي نستبعد ثلاث لوحات كنقاط محتملة للفشل.
محاولة توصيل جسر تسلسلي ESP32 أو CH340 مباشرة إلى الكابلات بين قاعدة جهاز المشي ولوحة تحكم Bowflex تتسبب في عدم تهيئة قاعدة جهاز المشي بشكل صحيح، وبعد ذلك قمت بالحصول على محلل منطقي للتحقيق بشكل أعمق.
في الأسابيع الأخيرة، وبعد ما يقرب من ثلاث سنوات منذ أن بدأت بهذا المشروع، تواصل معي عدة أشخاص للاستفسار عن التقدم في هذا الشأن، مما أكد افتراضي الأولي بأن نظام جهاز المشي سيئ، وأنه كان مسألة وقت قبل أن تبدأ الأجهزة في الفشل. بدا وكأن الوقت مناسب لاستخدام محلل المنطق الخاص بي، الذي كان حتى الآن مجمعًا فقط للغبار.
بتوصيل محلل المنطق بخطوط TXD و RXD (و GND بالطبع)، تمكنت على الفور من بدء اعتراض الرسائل بين الطرفين دون تعطيل الاتصال. أفترض أنني في البداية لم أتمكن من استخدام ESP32 بسبب مشاكل في المقاومة. بعد بضع دقائق من التجربة والخطأ، توصلت إلى إعداد التسلسل التالي:
- 2400 باود
- 8 بت لكل إطار
- بت توقف واحد
- بدون بت توازن
- إرسال أقل بت أهمية أولًا
- TXD: إشارة معكوسة
- RXD: إشارة غير معكوسة
مع هذه الإعدادات، كان بإمكاني رؤية الرسائل المحددة بوضوح.
اعتراض رسائل UART أثناء عملية التمهيد
بعض الأشياء التي لاحظتها على الفور:
0x68
0x73
0x43
مع ذلك كقاعدة، تبدأ عملية فك تشفير الرسائل وفهم ما يتم التواصل به بين الطرفين، مع إجراء تغييرات مضبوطة في روتين التمرين.
بإجراء تغييرات مضبوطة على سرعات محددة، يمكن ملاحظة القيم التالية المرسلة إلى لوحة تحكم المحرك:
السرعة على الشاشة | الرسالة المرسلة |
---|---|
0.0 كم/س (انتظار أو متوقف) | 0x68 0x08 0x80 0x50 0x00 0x0A 0x00 0x00 0xE2 0x43 |
2.0 كم/س | 0x68 0x08 0x80 0x50 0x14 0x0A 0x00 0x00 0xF6 0x43 |
3.0 كم/س | 0x68 0x08 0x80 0x50 0x1D 0x0A 0x00 0x00 0xFF 0x43 |
5.0 كم/س | 0x68 0x08 0x80 0x50 0x31 0x0A 0x00 0x00 0x13 0x43 |
يمكن ملاحظة أن البايت الخامس والتاسع يتغيران. يبدو أن البايت الخامس هو السرعة بالست عشري، والبايت التاسع يبدو كأنه رقم تحقق.
تحويل قيم البايت الخامس إلى عشري:
السرعة على الشاشة | ست عشري | عشري |
---|---|---|
0.0 كم/س (انتظار أو متوقف) | 0x00 | 0 |
2.0 كم/س | 0x14 | 20 |
3.0 كم/س | 0x1D | 29 |
5.0 كم/س | 0x31 | 49 |
بعد فك بعض أجزاء نظام Android قبل سنوات، تذكرت أنه عند تكوين الجهاز في النظام المتري، يقوم تطبيق Bowflex داخليًا بتحويل من النظام المتري إلى الإمبراطوري للتواصل مع “وحدة التحكم العالمية”. لوحة تحكم المحرك تبدو أنها تستخدم النظام المتري، ومن الواضح أن هناك فقدًا في الدقة في التحويل من المتري إلى الإمبراطوري ثم العودة إلى المتري (وهو ما تتوقعه لوحة التحكم بالمحرك)، حيث يتم التعامل مع كل شيء بدقة عشرية واحدة. هل كان من الصعب القيام بذلك بشكل صحيح، يا Nautilus؟
بالنظر إلى ذلك، وإذا تم تطبيق عامل ضرب قدره 10، فإنها تطابق تمامًا القيم المرسلة إلى لوحة تحكم المحرك. لذا، فإن الصيغة ستكون:
القيمة العشرية = السرعة بالكيلومتر/س × 10
باتباع نفس العملية مع السرعة، يمكن ملاحظة القيم التالية المرسلة إلى لوحة تحكم المحرك:
الميل على الشاشة | الرسالة المرسلة |
---|---|
-5° | 0x68 0x08 0x80 0x50 0x1D 0x00 0x00 0x00 0xF5 0x43 |
0° | 0x68 0x08 0x80 0x50 0x1D 0x32 0x00 0x00 0x27 0x43 |
9° | 0x68 0x08 0x80 0x50 0x1D 0x8C 0x00 0x00 0x81 0x43 |
في هذه الحالة، يبدو أن البايت السادس هو الميل بالست عشري، ويؤكد أن البايت التاسع هو رقم تحقق.
تحويل قيم البايت السادس إلى عشري:
الميل على الشاشة | ست عشري | عشري |
---|---|---|
-5° | 0x00 | 0 |
0° | 0x32 | 50 |
9° | 0x8C | 140 |
الصيغة التي تطابق تمامًا القيم المرسلة إلى لوحة تحكم المحرك هي:
القيمة العشرية = (الزاوية + 5) × 10
يبدو أن هذا يكون رقم تحقق بسيطًا ومعيارياً في المتحكمات الدقيقة، يجمع كل بايتات الرسالة ويسبب تجاوز الحد عند الوصول إلى 256. التمثيل البسيط سيكون شيئًا مثل:
uint8_t calculateChecksum(uint8_t *msg) {
return msg[1] + msg[2] + msg[3] + msg[4] + msg[5] + msg[6] + msg[7];
}
باستخدام uint8_t
كنوع الإرجاع، يحدث التجاوز بشكل طبيعي. يمكن استخدام for loop
لجمع القيم وإرجاع sum % 256
، ولكن ستكون أبطأ للمتحكمات الدقيقة بدون أي فائدة حقيقية.
مع ذلك، يمكن تكرار وظيفة لوحة الأزرار، وبهذا، يمكن التحكم في جهاز المشي من متحكم دقيق.
— يتبع —
©2022-2025 سيباستيان بارينيشيا. جميع الحقوق محفوظة.
مبني بواسطة Astro v5.5.4.