مثل العديد من المنتجات المنزلية الأخرى ، أستخدم بانتظام ميكروكنترولر AVR لجميع أنواع الحرف اليدوية للهواة. وبفضل مفهوم Arduino ، أصبحت هذه الحرف اليدوية الآن تبدو أنيقة أيضًا. في الواقع ، بالنسبة لحوالي 300-400 روبل ، نحصل على لوحة مصغرة متعددة الطبقات مع قناع وشاشة حريرية ومع الأجهزة الطرفية لوحدة التحكم الدقيقة المرباة بالكامل (علاوة على ذلك ، في إصدار SMD!). أنا لا أتحدث عن جميع أنواع المكونات الإضافية من نفس سلسلة "Arduino": المستشعرات ، وحدات التحكم ، الشاشات والمجموعات الكاملة ، الملحقات الإضافية التي نحتاجها كثيرًا. ومرة أخرى ، كل شيء غير مكلف وأداء ممتاز. عمليا لم تعد بحاجة لتربية شيء ولحم على "الركبة".
ولكن كل هذه الحرف اليدوية المختلفة تتطلب بطبيعة الحال
برمجة أولية. وبعد ذلك ، ومع التحسينات المختلفة ، يتعين علي دائمًا إعادة تحميل هذه الحرف. من الواضح أنه أكثر ملاءمة للقيام بذلك عن بعد من جرهم باستمرار إلى مبرمج عادي. بشكل عام ، وبفضل منصة Arduino نفسها ، هناك العديد من الخيارات هنا: Bluetooth ، ZigBee ، قناة راديو مع بروتوكولك الشخصي ، IR ، وحتى Wi-Fi. كلها تسمح لك بإقامة اتصال لاسلكي مع متحكمك. لكننا سنتوقف عند الخيار الأخير. هناك أربعة أسباب رئيسية:
1: حديث ، إنترنت الأشياء!
2: يوجد جهاز توجيه لاسلكي في كل شقة ، سجل أجهزتك في الشبكة المنزلية وفويلا!
3: تقدم حرفتك قفزة ثورية في تطورها ؛ لا يمكن برمجتها من مسافة بعيدة فحسب ، بل يمكنهم أيضًا التواصل مع العالم من حولهم: تستغرق الساعة الإلكترونية بشكل مستقل الوقت المحدد من ساعات خادم NTP ، ويتم التحكم في الأجهزة التنفيذية من الطرف الآخر من المدينة أو البلد ، كما تقوم أجهزة التسجيل بتخزين البيانات المتراكمة في سحابة الخ. الخ.
4: هناك سلسلة رائعة من رقائق ESP8266 التي
ليس من السهل عليها تنفيذ كل هذا.
علاوة على ذلك ، في هذه المقالة ، باستخدام مثال الذراع الميكانيكية على الماكينات ، والبرمجة عن بعد وتبادل البيانات مع جهاز كمبيوتر (أو أيا كان) مع الأجهزة المستندة إلى ميكروكنترولر AVR سيتم تفكيكها وإثباتها. أود أن أشير على الفور إلى أن جميع البرامج المدرجة فيما يلي هي عروض توضيحية بحتة وليس لها قيمة تجارية. لذلك ، لا يتم قبول الادعاءات ، مثل السبب في أن المبرمج مخصي وسوء الأداء أو لماذا لا توجد خدمات إضافية في كل مكان. نظرًا لأن الرموز مفتوحة ، يمكن لأي شخص إنهاءها وفقًا لتقديرها ، ولكن لا يزال لدي ما يكفي للعمل.
من المفترض أن القارئ على دراية بالفعل بكل من وحدات Arduino (الدروع) والاتصال والبرامج الثابتة لـ ESP8266. في الواقع ، تم نشر كمية كبيرة من المواد على الويب لشرح أساسيات العمل مع هذه الأجهزة ولا أريد أن أكررها هنا. بالنسبة للمبتدئين ، توجد في نهاية المقالة قائمة بالارتباطات المفيدة حول هذه المشكلات ، حيث يمكنك العثور على الكثير من المعلومات
، ولماذا لا يعمل كل شيء معك . من تجربتي كمهندس إلكترونيات سابق ، يمكنني أن أعلن بشكل مسؤول أن 99 ٪ من المشاكل هي كما يلي:
1. اتصالات سيئة. بما أن دروع "Arduino" تعني التبديل مع بعضها البعض من خلال أسلاك من نوع "الأب-الأم" ، وليس من خلال اللحام ، غالبًا ما يختفي شيء ما ، في مكان ما. تحقق من ذلك. والواقع أن الإلكترونيات ، كما يقولون ، هي علم الاتصالات.
2. مشاكل الطاقة. لا تزود 5 فولت من الطاقة حيث يتطلب 3.3. يأتي الدخان في بعض الأحيان من ESP8266. على الرغم من أنه ، من ناحية أخرى ، يستوعب الإشارات المنطقية من الأجهزة ذات الخمسة فولت دون مشاكل.
3. مشاكل مع القوة الكافية. ESP8266 له طبيعة حقيرة وأحيانًا يمكن أن يستهلك ما يقرب من ثلاثمائة مل أمبير ، على الرغم من أنه قبل ذلك يمكن أن يكون راضياً عن ثلاثين. وفقًا لذلك ، فإن جهاز التثبيت الهش 3.3 فولت بغطاء "اردوينو" ، والذي يمكنك من إضافة ما يصل إلى لا شيء ، فهو متصل ، فإنه يغرق على الفور في القيم المجهرية. ولا يمكنك أن تفهم لماذا تعمل ، ثم لا.
4. الخلط مع الاستنتاجات. تحقق دائمًا من الإشارات التي تذهب إليها. يجب أن يتصل مستقبل RXD بجهاز إرسال TXD ، وكذلك TXD بـ RXD ، ولكن يجب أن تتصل MOSI بـ MOSI ، و MISO بـ MISO ، وما إلى ذلك.
5. لا تعتمد على مقاومات السحب في الدائرة في ESP8266 ، اسحب دائمًا الأسلاك إلى صفر أو طاقة ، من خلال مقاومات خارجية 5-10 كيلو أوم ، وليس مجرد وصلة مرور. خلاف ذلك ، يمكنك ، في أحسن الأحوال ، الحصول على استهلاك تيار غير مسبوق ، ثم تشم رائحة البلاستيك المحترق الكريهة.
6. ضحكات البرمجيات. نظرًا لأن البرامج للمستخدمين الفرديين يكتبها نفس المتحمسين ، فإن الأخطاء من البرامج الثابتة نفسها والأخطاء تظهر بشكل دوري عند تحديث إصدارات نفس البرامج الثابتة. يتم التعامل معها عن طريق الزحف في المنتديات ذات الصلة ، وأحيانًا باللغة الإنجليزية. حتى أن بعض الرفاق زعموا أن شريحة ESP نفسها كانت رطبة مثل الطقس في سان بطرسبرغ ، ولكن من ناحية أخرى كان هناك رأي مفاده أنه منذ عام 2014 (العام الذي تم إصداره لأول مرة) ، تحسن الوضع مع هذا بشكل كبير (على عكس الطقس).
7. مواطن الخلل الغامضة. هذه ظاهرة نادرة ولكنها تستهلك الأعصاب. على سبيل المثال ، لم يكن لدي جهاز "Arduino" عن بُعد. بدلا من ذلك ، حدث ذلك ولكن مع وجود أخطاء. ولكن ذهب دون أخطاء إذا كان كبل من المبرمج معلقة عليه (ولكن بدون المبرمج نفسه). "AHA" ، أخبرت نفسي ، وقمت بلحام مكثف 15 pF بين دبوس نقل البيانات ودبوس المزامنة. كل شيء يعمل. لكن اليوم قتل.
لذا ، لنبدأ بالأبسط. لدينا طرف ميكانيكي MechArm (ولكن ليس ما جمعه Howard Volovits) المصنوع في الصين وجهاز كمبيوتر شخصي مع Windows. وتتمثل المهمة في فلاش البرنامج عن بعد وإدارته من جهاز الكمبيوتر.

بالنسبة لوحدة التحكم ، نأخذ وشاح Arduino Nano المصغر اللطيف بحجر ATmega328P. يتم دفع هذه اللوحة بشكل مثالي في الذراع الميكانيكية.

الآن نقرر كيف سنبرمجها. هناك ثلاث طرق رئيسية هي الأنسب للبرامج الثابتة عن بعد: من خلال واجهة SPI ، من خلال محمل الإقلاع المدمج ، من خلال منفذ JTAG.
الخيار الأسهل بالطبع هو محمل الإقلاع المدمج (محمل الإقلاع). هذه ذاكرة مسجلة مسبقًا في FLASH ، وهو برنامج يتلقى رمزًا وفقًا لبروتوكول معين (على سبيل المثال ، باستخدام أبسط UART) ويكتبه إلى موقع البرنامج المحمل بأوامر خاصة. يعمل هذا ، على سبيل المثال ، محمل الإقلاع ARDUINO IDE. بعد إعادة التعيين أو البدء ، ينتظر محمل الإقلاع بعض الوقت لاستلام البيانات وإذا لم ينتظر ، فإنه يبدأ في تنفيذ البرنامج من العنوان صفر. إذا وصلت البيانات ، يكتبها إلى قسم البرنامج. بعد إعادة التعيين التالية ، يبدأ تشغيل البرنامج الذي تم تنزيله. بالتفصيل ، ربما وصفت بشكل غير دقيق ، ولكن الجوهر هو ذلك بالضبط. ونتيجة لذلك ، نحتاج فقط إلى ثلاثة مخرجات للبرمجة: جهاز استقبال RTD وإعادة تعيين RESET وأرض GND. بشكل عام ، يتم استخدام جهاز إرسال TRD أيضًا للتحقق من البرنامج المسجل ، ولكن بالنسبة للتطبيقات التوضيحية البسيطة (ليس لمحطة الطاقة النووية) ، يمكن حذف التحقق.
تتم كتابة اللودر نفسه بلغة التجميع ، وهناك أمثلة على اللوادر البسيطة في أوراق البيانات على AVR. يمكنك حفر محمل إقلاع موجود إذا كان في المجال العام واستخدامه ببساطة في شكل جاهز إذا كان البروتوكول الذي يعمل به معروفًا. التحذير الوحيد هو أنك تحتاج إلى تكوين AVR في وضع خاص عن طريق وميض بت الفيوزات الخاصة ، والتي يتم إجراؤها بواسطة مبرمج عادي ، ثم يمكنك أيضًا خياطة محمل الإقلاع في ذاكرة وحدة التحكم الدقيقة (أي أنه لا يمكنك الاستغناء عن مبرمج مرة واحدة).
الخيار الثاني هو البرمجة من خلال واجهة SPI التسلسلية. لا يوجد محمل إقلاع داخلي هنا ، ولكننا نبرمج عن طريق إرسال أوامر خاصة ثم البيانات عبر الواجهة المذكورة أعلاه. هنا لدينا محمل إقلاع خارجي ، لكنك ما زلت بحاجة إلى كتابته. بالإضافة إلى RESET و GND ، يتم استخدام أربعة مخرجات MOSI إضافية للإرسال ، وبيانات MISO ، ومزامنة SLK ، واختيار رقاقة CS. ولكن بشكل عام ، يمكنك أيضًا إزالة MISO و CS. سيتم قبول البيانات فقط (عندها لن يكون هناك تحقق من البرنامج) ، ولدينا بلورة واحدة فقط.
لكل نهج إيجابياته وسلبياته (ولم أعتبر JTAG على الإطلاق ، لأن حياة الإنسان قصيرة). ولكن في النهاية ، اتجهت نحو SPI لأنني كنت كسولًا جدًا في الكتابة في المجمّع ، لكنني لم أجد محمل إقلاع جاهزًا مفتوحًا (لم أبحث عنه جيدًا).
لبناء قناة لاسلكية ، اخترت ، كما ذكرنا من قبل ، شريحة ESP8266 المعروفة حاليًا على نطاق واسع - متحكم دقيق ، أو بالأحرى ، SoC (System-on-Chip) بالكامل من الشركة المصنعة الصينية Espressif مع واجهة Wi-Fi. بالإضافة إلى شبكة Wi-Fi ، تتميز بالقدرة على تنفيذ البرامج من ذاكرة فلاش خارجية. وبالتحديد لمشروعي ، أخذت ESP8266-07 مع 512 كيلوبايت من الذاكرة على متن الطائرة.

بشكل عام ، يعتبر أي ESP8266 مناسبًا حيث توجد أرجل إضافية لتنفيذ SPI. لذلك ، لا يناسبنا أبسط ESP8266-01 ، نظرًا لأنه يحتوي على عدد قليل جدًا من الأرجل لمنافذ الإدخال / الإخراج. ولكن من ناحية أخرى ، فإن الفرق في السعر أقل من مائة روبل ، وهي متاحة على قدم المساواة. حسنًا ، لوحات تصحيح الأخطاء الكبيرة مع ESP ، حيث توجد مجموعة من الأجهزة الطرفية للراحة ، ليست أيضًا مناسبة لنا ، لأنها لا تدخل إلى حيث نريد دفعها إلى ذراعنا الميكانيكي.
كان الجوهر العالمي للفكرة بشكل عام على النحو التالي. يتم نقل نص البرنامج الذي تم تحميله في وحدة التحكم الدقيقة من الكمبيوتر إلى ESP لاسلكيًا عبر WI-FI (داخل شبكتك المنزلية). و ESP بالفعل عن طريق الأسلاك باستخدام واجهة SPI يكتب هذا البرنامج مباشرة إلى ذاكرة فلاش من متحكم. ثم يعيدها بشكل طبيعي ويسمح بتنفيذ البرنامج المحمل. بالإضافة إلى ذلك ، يجب أن يكون لدى ESP وحدة مستقلة ، والتي تدير أيضًا تبادل البيانات مع وحدة التحكم الدقيقة ، لأننا لا نريد فقط برمجة ، ولكن أيضًا تبادل البيانات معها. على وجه الخصوص ، بالنسبة لمشروع مع MechArm ، بعد تسجيل البرنامج ، ما زلنا نرسل إشارات تحكم مؤازرة من أجل تحريك هذه اليد. لذلك ، على ESP نفسه ، من المستحسن بالنسبة لنا رفع خادم TCP لنقل البرنامج وخادم UDP للتحكم في MechArm. وفقًا لذلك ، تنضم هذه الخوادم إلى الشبكة المنزلية وتستمع بعناية إلى ما إذا كان هناك أي شخص يريد تحميل رمز جديد إلى MechaArm أو التلويح بشخص ما.
لذلك ، وجدت على الويب أن البرامج الثابتة تسمح لك بالفعل ببرمجة AVR عبر الهواء ، ولكن هناك مشكلة رئيسية هي أنه لما لم يعد من الممكن استخدام هذه البرامج الثابتة. بعد البرمجة ، نود التواصل مع AVR أيضًا عن بُعد.
ما البرنامج الذي سنستخدمه:
بالنسبة للكمبيوتر ، كتبت كل شيء في JAVA و
IntelliJ IDEA . ولكن في الأساس ، يمكنك القيام بأي شيء ، الشيء الرئيسي بالنسبة لنا هو كتابة عميل يرسل البرنامج لوميض AVR إلى ESP8266.
أنا شخصيا أكتب برامج AVR في
ATMEL STUDIO ، باللغة C ، ونادرا ما يتم تجميعها. لا أستخدم رسومات Arduino من حيث المبدأ ، حيث تتم كتابة أي مكتبة ضرورية تقريبًا في غضون ساعة أو ساعتين ، مع فهم كامل لعملها. لقد جربت اسكتشات ، ولكن طالما لم يكن لديك نظام تشغيل على AVR ، فإن الرسومات ستأخذ الأجهزة الطرفية من صديق وتفشل بانتظام. نعم ، إن Arduino IDE نفسه ، مقارنة بـ ATMEL STUDIO ، هو بالطبع شيء بدائي للغاية. لكن السؤال هنا ، بالطبع ، مثير للجدل ، بالنسبة للإنسانيات وأطفال المدارس ، سيكون أكثر متعة وأسهل ، ربما ، مع الرسومات.
لبرمجة ESP8266 ، استخدمت برنامج NodeMCU الثابت ، وكتبت برامج في Lua. لا ، أود أن أكتب بلغة Java و C ، ولكن لا يوجد أي شيء في ESP. لغة لو كما تطبق على مهمتنا ليست صعبة ، لإتقان زوج من التفاهات. وفي الواقع ، لتنزيل البرامج
وتصحيحها على ESP ، أخذت
IDE ESPlorer . منتج محلي مجاني (ولكن يمكنك التبرع به للمؤلف) ، والذي بالطبع لا يمكن مقارنته بالوسائط المذكورة أعلاه ، ولكن كما يقول حصان الهدايا ... ولكن من أجل استخدام ESPlorer والكتابة على LUA ، نحتاج أولاً إلى تغيير البرامج الثابتة الأساسية (المقدمة من الشركة المصنعة) في شريحة ESP8266 إلى جديد. سيساعدنا برنامج NODE MCU PyFlasher في هذا المشروع. أعني ، أنه سيساعد على إعادة تحميله. وسوف نقوم بإنشاء البرامج الثابتة بأنفسنا
ونضعها في أيدي موقع منشئي المحتوى:
NodeMCU . ويمكنك قراءة المزيد حول هذه العملية
هنا:كل شيء سهل الوصول إليه ومفهوم. نضيف دعم SPI وعمليات البت إلى المكتبات الأساسية (في LUA ، في حالتنا ، يتم تحميل عمليات البت بشكل زائد ولا فائدة منها). لا يجب دفع العديد من المكتبات في البرامج الثابتة للمكتبات ، نظرًا لوجود أي برامج مختلفة على ESP8266 ، لا يوجد سوى القليل جدًا من الذاكرة المتبقية ، نوع من مثير للشفقة 20 كيلوبايت.
بالطبع ، يمكنك فقط أخذ البرامج الثابتة النهائية ، والتي يجري العديد منها بالفعل على الإنترنت ، لكنني لا أوصي به. على الأقل لأن البعض منهم لا يدعم عمليات البت (ونحن بحاجة إليها) ولا يوجد تنظيم لمعدل نقل البيانات عبر SPI.
وفقًا لذلك ، يتم إرسالها بشكل افتراضي بسرعة 40 ميجاهرتز مقسومة على بعض المعامل الصغيرة ، وبالتالي ليس لدى AVR الوقت لهضمها.
من هو كسول جدًا لإنشاء البرامج الثابتة ، يمكنك تنزيل المنجم من
السحابة .
الآن لدينا البرامج الثابتة ونحتاج إلى تحميلها في ESP8266 بدلاً من الأساسي. للقيام بذلك ، نحتاج إلى محول USB بسيط - UART.
نحن نربط أرجل TXD بـ RXD ، و RXD بـ TXD ، نصنع أرضية مشتركة ، ولكن لا تستخدم ، كما يبدو ، خرج طاقة مناسب 3.3 فولت على المحول. في معظم الحالات ، يقوم ESP8266 بتصريفه بالكامل. لذلك ، نطعمه بشكل منفصل. ثم نضع ESP في وضع البرمجة (GP0 على الأرض ، إذا نسي أي شخص) وتشغيل
NODE MCU PyFlasher .

الأهم من ذلك ، لا تنسى محو ذاكرة الفلاش (نعم ، يمسح جميع البيانات) ، وإلا ، اعتمادًا على إصدار البرنامج الثابت ، بعد البرمجة ، قد تظل القمامة غير الضرورية في الذاكرة ، والتي بدورها ستفريغ القمامة في وحدة التحكم أثناء العمل الإضافي. قبل ذلك ، كنت أستخدم برنامجًا ، حيث لم يكن هناك خيار لمحو الذاكرة مسبقًا ، كنت تعذب بشكل رهيب ، حيث لم ينجح شيء. وافتتح النعش للتو ، فقط الحقيقة في المنتدى الإنجليزي لمبدعي NODE MCU.
بعد الحصول على البرامج الثابتة اللازمة ، يمكننا الآن كتابة برامج LUA وتصحيحها (هناك أيضًا MicroPython ، لكنني لم أستخدمها) باستخدام واجهات برمجة تطبيقات ملائمة جدًا من NODE MCU. أطلقنا ESPlorer المذكور بالفعل.

نقوم أيضًا بتكوينه للعمل مع ESP8266 ، وتعيين معلمات الاتصال التسلسلي. كل شيء بسيط للغاية ويتم ذكره مرارًا وتكرارًا على الإنترنت.
الآن نكتب البرنامج على LUA ، ثم نقوم بتحميله على ESP8266:
محمل التمهيد لوا مكتوب على ESP8266<b>function InstrProgrammingEnable ()
حيث تؤدي الوظائف ذات الصلة الإجراءات التالية:
الوظيفة InstrProgrammingEnable () - تضع وحدة التحكم الدقيقة في وضع البرمجة باستخدام أمر خاص يتم إرساله عبر SPI.
الوظيفة ProgrammingEnable () - فقط قم بإعادة ضبط AVR لمدة 25 مللي ثانية قبل بدء البرمجة
الوظيفة ProgrammingDisable () - بعد نهاية البرمجة ، نقوم بترجمة مخرجات SPI في ESP8266 إلى حالة غير نشطة بحيث لا تتداخل معنا عند تنفيذ التعليمات البرمجية على وحدة التحكم الدقيقة (فجأة يتم استخدامها هناك)
الدالة InstrFlashErase () - نقوم بمسح ذاكرة فلاش على متحكم
دقيق قبل البرمجة. لماذا يجب شرح هذا ليس ضروريا.
دالة InstrStorePAGE (H ، العنوان ، البيانات) - يكتب هذا الأمر بايت البرنامج إلى المخزن المؤقت الداخلي
لوحدة التحكم الدقيقة. ولكن ليس هذا هو سجل الفلاش نفسه ، حيث أن الفلاش مكتوب هنا صفحة بصفحة بحجم 128 بايت.
دالة InstrWriteFLASH (page_address_low، page_address_high) - ولكن هذا سجل فلاش ويستغرق وقتًا ، انتبه للتأخير الزمني البالغ 5000 μs.
وظيفة البرمجة (الحمولة) - أكبر وأهم وظيفة باستخدام الوظائف المذكورة أعلاه. يأخذ البرنامج المرسل بأجزاء من 1024 بايت ، ويقسمها إلى وحدات بايت ويشكل عناوينها ، ثم يرسلها إلى وحدة التحكم الدقيقة في المخزن المؤقت الداخلي ويهيئ سجل فلاش كل 128 بايت. ثم يأخذ الكيلوبايت التالي من التعليمات البرمجية ويكرر العملية ، بشكل طبيعي مع إزاحة في العناوين ، وذلك لكتابة المزيد وعدم الكتابة فوق المسجلة. في البداية ، حاولت إعادة توجيه البرنامج بالكامل ، ولكن عندما أتجاوز 6 كيلوبايت في ESP8266 ، تنتهي الذاكرة المتوفرة فقط وتتعطل. تبين أن كيلوبايت واحد هو الوحدة الأكثر ملاءمة ، لأنه مقسم بدقة إلى أجزاء وينقل بشكل ملائم عبر TCP (ما زلنا بحاجة إلى الحصول عليه من الكمبيوتر). هناك حاجة أيضًا إلى حجم أكبر ، TCP ، كما تعلمون ، في الإصدار الحالي يحد الحزمة المرسلة إلى 1500 أو بايت (ولكن لسبب ما تم إرسال 1440 إلي ، نوعًا ما).
كما لو أن لا شيء معقد ، ولكن كان يجب التغلب على بعض المزالق.
التالي هو الكتلة الرئيسية. في ذلك نحن:
نحن مسجلون في شبكة لاسلكية.
أولاً نقوم بإنشاء خادم TCP يستمع إلى ثلاثة أوامر:
1. "برنامج" (سنبرمج)
2. "البيانات" (سنقوم بتغيير البيانات) ،
3. "توقف" (نوقف كل شيء).
إذا قمنا بالبرمجة ، فإننا نقوم أولاً بتهيئة SPI وننشئ خادم TCP آخر يلتقط البيانات (رمز البرنامج الثابت) لكل كيلوبايت ويستدعي وظائف برمجة وحدة التحكم الدقيقة لها. أتفهم أنه يبدو من السخف إنشاء خادم ثانٍ ، ولكن هذا ضروري ، لأن واجهة برمجة التطبيقات المحلية تدعم إنشاء مقبس واحد فقط ، ونحن بحاجة إلى فصل أمري "البرنامج" و "البيانات" مع البيانات المرسلة ، لأنه بالعين لا تختلف ، هناك وحدات بايت و هنا بايت.
إذا كنا لا نريد البرمجة ، ولكن لتبادل البيانات ، وإرسالها في حالتنا إلى وحدة التحكم الدقيقة ، فإننا نرسل أولاً السلسلة "بيانات" عبر TCP. استجابة لذلك ، سيتم إنشاء خادم UDP (أذكرك بأننا لا ندير ديناميكيًا بيد ميكانيكية وأننا لا نحتاج إلى تأخيرات في تشكيل حزم TCP ، وبالفعل نرسل بايت واحد كإطار TCP كامل على العداد). وستكون مخططات بيانات UDP صغيرة وستتشكل بسرعة.
بعد تهيئة UART ، يتم إرسال كل بايت يتم استقباله لاسلكيًا بالفعل عبر سلك TXD إلى وحدة التحكم الدقيقة ، والتي تكون ملزمة بقبولها إذا تم تحديث البرنامج المقابل هناك. ليس من الصعب تنظيم تبادل البيانات في اتجاه آخر ، لكنني لم أقم بتطبيقه بعد.
حسنًا ، من خلال أمر "الإيقاف" ، تغلق الخوادم المذكورة أعلاه (باستثناء الأولى) الاتصالات ويذهب الخادم الرئيسي مرة أخرى إلى حالة الانتظار لأوامر "البرنامج" و "البيانات".
نظرًا لأن واجهة SPI تمت محاكاتها برمجيًا في ESP8266 ، فإن منافذ الإدخال / الإخراج للإشارات CS و CLK و MISO و MOSI و RESET (لـ AVR) ، يمكنك استخدام أي منها متاح ، وليس تلك المشار إليها في برنامج تحميل التمهيد الخاص بي. بالإضافة إلى ذلك ، اتضح أن CS و MISO ، من حيث المبدأ ، يمكن أيضًا مقاطعتهم في هذه الحالة ، وسوف تعمل بدونها. حسنًا ، يتم استخدام دبوس واحد على LED المدمج في لوحة ESP8266 بحيث يومض في بعض الأحيان ويشير إلى أن البرنامج لا يزال على قيد الحياة.
لا يتم التحقق من أخطاء التسجيل (باستثناء الطلب الأول لـ AVR ، ولكن يتم عرض هذه المعلومات ببساطة على وحدة التحكم) ، EEPROM غير مبرمجة ، أكثر من 32 كيلوبايت غير مخيط - باختصار ، لا يزال هناك عمل للقيام به. تبلغ سرعة تبادل SPI حوالي 115 كيلوبت ، في بضع ثوان يتم وميض كل شيء ، تقريبًا ، مثل المبرمج التسلسلي العادي مثل ISP500).
خذ الرمز ، وأدخل شبكاتك وكلمات المرور الخاصة بك ، وقم بتجميعها على ESplorer ، وأطلق عليها "init" (بحيث تبدأ عند إعادة التشغيل) وأرسلها إلى ESP8266. يجب أن تعمل. بمعنى العمل كمبرمج لاسلكي ، على الأقل.
الآن سنتعامل مع الطرف المُدير - كمبيوتر شخصي.
في الواقع ، نحتاج إلى أخذ ملف HEX الذي تتحول فيه برامجك المكتوبة في بيئة ATMEL STUDIO وإرسالها عبر WI-FI إلى منفذ المقبس الذي نعرفه (في هذه الحالة 4000). المشكلة الصغيرة هي أننا بحاجة إلى ملف BIN ثنائي للتحويل ، ولا يسعدنا ATMEL STUDIO إلا باستخدام HEX. هناك طريقتان للخروج ؛ أو قم بتحويله إلى تنسيق BIN باستخدام محول برنامج خاص ، مثل WinHex ، أو قم بذلك بنفسك في برنامجك. لم أفعل ذلك بعد ، ولكن يبدو أنه ليس من الصعب ، هناك تحتاج إلى قطع العنوان والقيام بشيء آخر.
ونتيجة لذلك ، كتبت برنامج bootloader في JAVA (بشكل أساسي لأنني لا أعرف كيفية القيام بأي شيء آخر) ، حيث عملت في بيئة IntelliJ IDEA الجميلة والبسيطة. يقوم بإنشاء عميل TCP يبحث عن خادم يعمل على ESP8266. إذا وجد ، يتصل به ويرسل له ملفًا موجودًا في هذا العنوان. الرمز أدناه.
تنزيل ملف JAVA المستند إلى الكمبيوتر import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; public class Net { <b> public static void main(String args[]) { new Http_client(4000); }</b> } class Http_client extends Thread { int port; String s; String Greetings_from_S; Http_client(int port){ this.port = port; start(); } public void run() {
هنا ، بالطبع ، جرح الكثير ، ليست هناك حاجة لجميع أنواع جاهزة ، من حيث المبدأ. إذا تم تأسيس اتصال TCP ، يتم تأسيسه. كانت المشكلة الوحيدة هي أن الملف لا يريد أن يتم إرساله حتى في قطع بحجم 1024 بايت بأي شكل من الأشكال ، كما أحتاج حقًا ، على الرغم من أنني أوضحت الحجم بوضوح. يبدو أن هناك نوعًا من المخزن المؤقت النهائي لا يمكن الوصول إليه من JAVA ، ويرسل الحزم بالحجم الذي يريده ، وهو أمر غير مقبول تمامًا من جانب الاستقبال. في البداية حاولت التأخير حتى يتعب المخزن المؤقت من انتظار القطع التالية وإرسالها كما هي. لكن التأخير بدأ في العمل عندما وصل إلى 10 ثوانٍ ، وهو ما بدا بطريقة أو بأخرى أكثر من اللازم لنقل كيلوبايت واحد.
ولكن بعد ذلك لاحظت أنه لسبب ما ، تسير القطعة الأولى بشكل سلس دائمًا ، أي قطعة تم طلبها ، وتبدأ بالفعل من الثانية باتشاناليا غير متوقعة. لذلك ، جعلت العميل يفتح الاتصال ، وأرسل جزءًا من الرمز في 1024 بايت وأغلق الاتصال. وهكذا حتى يتم إرسال الملف بأكمله. كل شيء يعمل بشكل جيد.
الشيء الوحيد الذي يجب البدء به هو تثبيت وقت تشغيل JAVA على الكمبيوتر. لكنني عادة ما أبدأ مباشرة من IntelliJ IDEA لأنه يمكنك دائمًا رؤية ما يحدث في وحدة التحكم (ولكن هنا تحتاج إلى بيئة JAVA). على الرغم من ذلك ، وبطريقة ذكية ، تحتاج إلى إنشاء واجهة مستخدم رسومية. أي النافذة التي يقع فيها المسار إلى الملف ، والقدرة على تغيير أرقام المنافذ في النافذة ، وأيضًا الأشياء الضرورية الأخرى. وجمع كل هذا في شكل ملف قابل للتنفيذ.
وتابيرشها ، كما كان يقول كوروفييف ، دعونا نعود إلى المواطنين ، في الواقع ، إلى الطرف الميكانيكي MechArm ، الذي تم ذكره في البداية. لدينا الآن الفرصة لبرمجة ذلك عن بعد ، ثم إدارته. دعنا ننتقل إلى برنامج التحكم على جانب وحدة التحكم الدقيقة.
في هذه الحالة ، نحتاج إلى التحكم في أربعة أجهزة. هنا هؤلاء.
يتم التحكم في هذا المحرك بواسطة نبضات مستطيلة لمدة 20 مللي ثانية (50 هرتز) مع عامل واجب من 2 إلى 4 في المائة. أي أن 2٪ هي دورة كاملة في اتجاه واحد ، و 4٪ في الاتجاه الآخر. المهمة هي فقط ل PWM المتكاملة في AVR.

يتم استخدام محرك سيرفو واحد للتحرك يسارًا ويمينًا ؛ والثاني على نفسه - من نفسه ؛ الثالثة صعودا وهبوطا. الرابع هو المخلب نفسه ، الذي يجب ضغطه وتوسيعه. كل شيء مكتوب في C وترجم إلى ملف HEX في ATMEL STUDIO. نوع غريب من البرنامج يرجع إلى حقيقة أنه تم التحكم في اليد في البداية من لوحة المفاتيح المربوطة بأسلاك إلى وحدة التحكم الدقيقة. لكن أسلاك الأمس ، يجب أن نتطور أكثر.
يمكنك بالطبع استخدام الرسومات للمكابح من "ARDUINO" ، لكني لم أحبهم. من المثير أكثر أن تكتب نفسك. بالإضافة إلى ذلك ، يجب أن تعمل جميع الماكينات الأربعة في وقت واحد ، وليس في وضع تعدد الإرسال ، عندما يتحول PWM إلى كل مكابح بدوره. لأنه لم يقم أحد بإلغاء الجاذبية ، وسوف ينزل الطرف المرتفع على الفور إذا توقفت نبضات التحكم عن الوصول إلى محرك سيرفو المقابل. لست متأكدًا من أن رسم "ARDUINO" يوفر عملية متزامنة لأربعة أجهزة. ولكن يمكننا نحن أنفسنا كتابة برنامج يلبي المتطلبات اللازمة. بشكل عام ، في حالة عدم وجود نظام تشغيل يفصل الحملان عن الماعز ، فإن استخدام الرسومات التي تتنافس على الأجهزة الطرفية لوحدة التحكم الدقيقة (ولا نعرف حتى أي منها مقدمًا) هو عربات التي تجرها الدواب.
هذا هو الرمز نفسه الذي نكتبه إلى Arduino Nano باستخدام ESP8266-07.
برنامج للتحكم في MechArm للمتحكم الدقيق AVRmega328P #define F_CPU 16000000 #include <avr/io.h> #include <stdint.h>// #include <avr/interrupt.h> #include <math.h> // #include <stdio.h> // - #include <avr/eeprom.h> #include <setjmp.h> #include <stdlib.h> // #define UART_BAUD_RATE 115200 // 1 20 #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // 0 0 1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // 2 B2(PD6) 3(PD7) #define COUNTER2_OFF TCCR2B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t start_position [6]; volatile int8_t number_servo; ISR(USART_RX_vect)// UART { State_of_keyboard=UDR0; return; } ISR(TIMER0_COMPA_vect)// 0 { PORTB &=~(1<<0); TIMSK0&=~(1<<OCIE0A); TIFR0 |=(1<<OCF0A); return; } ISR(TIMER0_COMPB_vect) // 1 { PORTB &=~(1<<1); TIFR0 |=(1<<OCF0B); TIMSK0 &=~(1<<OCIE0B); return; } ISR(TIMER2_COMPA_vect)// 2(PD6) { PORTD &=~(1<<6); TIFR2 |=(1<<OCF2A); TIMSK2 &=~(1<<OCIE2A); return; } ISR(TIMER2_COMPB_vect)// 3(PD7) { PORTD &=~(1<<7); TIFR2 |=(1<<OCF2B); TIMSK2 &=~(1<<OCIE2B); return; } ISR(TIMER1_OVF_vect){// 20 COUNTER1_OFF; COUNTER0_OFF; COUNTER2_OFF; TIFR0 |=(1<<OCF0A); TIFR0 |=(1<<OCF0B); TIFR2 |=(1<<OCF2A); TIFR2 |=(1<<OCF2B); TIFR1 |=(1<<TOV1); PORTB |=(1<<0)|(1<<1); PORTD |=(1<<6)|(1<<7); TCNT1 = period_20ms; // 20 TCNT0 = 0; TCNT2 = 0; TIMSK0|=(1<<OCIE0A)|(1<<OCIE0B); TIMSK2|=(1<<OCIE2A)|(1<<OCIE2B); OCR0A=start_position[1];// 0 0 OCR0B=start_position[2];// 0 1 OCR2A=start_position[3];// 0 2 OCR2B=start_position[4];// 0 3 COUNTER1_ON; COUNTER2_ON; COUNTER0_ON; return; } void time_delay(long i) { cli();sei(); long k; i*=2000; for(k=0;k<i;k++){;;}; } void timer_counter0_1_2_INIT()// 0,1,2 { // 1 TCCR1A &=~(1<<COM1A0)|~(1<<COM1A1)|~(1<<COM1B0)|~(1<<COM1B1);// TCCR1A &=~(1<<WGM10)|~(1<<WGM11); TCCR1B &=~(1<<WGM12)|~(1<<WGM13);// period_20ms=60575; TCNT1 = period_20ms; TIMSK1|=(1<<TOIE1);//| //TIFR0 TOV0 // 0 TCCR0A &=~(1<<COM0A0)|~(1<<COM0A1)|~(1<<COM0B0)|~(1<<COM0B1);// TCCR0A &=~(1<<WGM00)|~(1<<WGM01); TCCR0B &=~(1<<WGM02);// // 2 TCCR2A &=~(1<<COM2A0)|~(1<<COM2A1)|~(1<<COM2B0)|~(1<<COM2B1);// TCCR2A &=~(1<<WGM20)|~(1<<WGM21); TCCR2B &=~(1<<WGM22);// COUNTER1_ON; } void servo_reset() { start_position[1]=97;// 0 0 start_position[2]=70;// 0 1 start_position[3]=92;// 0 2 start_position[4]=124; // 0 3 COUNTER1_ON; time_delay(100); } void servo_go( int8_t moven, uint8_t servo_position_max, uint8_t servo_position_min)// { switch (moven){ case 1: start_position[number_servo]++; if(start_position[number_servo]==servo_position_max){start_position[number_servo]--;};// +90 break; case 2: start_position[number_servo]--; if(start_position[number_servo]==servo_position_min){start_position[number_servo]++;};//6 -90 break; }; time_delay(20); return; } //PORTB-0,1, PORTD - 6,7 - , 8- COUNTER 0 int main(void) { uint8_t servo_positionmin=0, servo_positionmax=0; int8_t const servo_position1max = 122, servo_position1min=58; // int8_t const servo_position2max = 120, servo_position2min=36;// int8_t const servo_position3max = 125, servo_position3min=68;// int8_t const servo_position4max = 129, servo_position4min=108;// 128 108 sei(); DDRD = 0B11000010; // D2-D5 , D0 RX, D1 TX, D6 D7 3 4 PORTD = 0B00111110; // DDRB |=(1<<0)|(1<<1);// PORTB &=(~1<<0)|(~1<<1); UCSR0A=0;// UART UCSR0B=0b10010000; UCSR0C=0b00000110; UBRR0L=103;// 115200 UBRR0H=0; timer_counter0_1_2_INIT(); servo_reset(); PORTB |=(1<<5); while (1) { switch (State_of_keyboard) { case 1:// 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 2: // 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 5: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 6: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 7: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 8: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 3: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// case 4: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// // c - , 4- // , } if(State_of_keyboard==1||State_of_keyboard==3||State_of_keyboard==5||State_of_keyboard==7) { servo_go(1,servo_positionmax,servo_positionmin);// } if(State_of_keyboard==2||State_of_keyboard==4||State_of_keyboard==6||State_of_keyboard==8) // { servo_go(2,servo_positionmax,servo_positionmin);// } time_delay(20); } }
جوهر البرنامج واضح من النص والتعليقات. نستخدم عداد T1 لفترة مثالية تبلغ 20 مللي ثانية و T0 ، عدادات T2 لإصدار إشارات PWM إلى أربعة أسطر من منفذ الإدخال / الإخراج ، حيث يمكن لكل من هذين العددين العمل على جهازين.
يقوم البرنامج بتعيين المواضع الأولية للمكونات من خلال تحميل سجلات العد OCR0A و OCR0B و OCR2A و OCR2B. يتم أيضًا إدخال ثوابت القيد ، لأننا لا نحتاج دائمًا إلى مدى 180 درجة. حسنًا ، علاوة على ذلك ، من خلال المقاطعة من UART ، يقوم البرنامج بالتقاط الرقم المرسل بواسطة ESP8266 (من 1 إلى 8) ويترجمه إلى أمر للجهاز المؤازر المقابل. هناك أربعة محركات ، يعمل كل منها في اتجاهين ، لذا فإن الأعداد الصحيحة من واحد إلى ثمانية كافية. بمجرد تحديد الرقم ، تكون محتويات سجلات العداد المذكورة أعلاه إما زيادة أو نقصان ، على التوالي تغيير دورة العمل لنبض التحكم وزاوية دوران محرك سيرفو المحدد. محركات الأقراص التي لم نختارها تحتفظ بالقيمة القديمة لزاوية التدوير (نظرًا لأن محتويات السجلات المقابلة ، على الرغم من تحديثها ، لم تتغير) وتستمر في الاحتفاظ بالذراع الميكانيكي في نفس الموضع.
الآن علينا فقط كتابة برنامج تحكم ، آسف للتوطين ، للتحكم في يد ميكانيكية مباشرة من الكمبيوتر عبر WI-FI.
الرمز مكتوب أيضًا بلغة JAVA ، ولكنه مغرور قليلاً. كان هناك واجهة المستخدم الرسومية والقدرة على تحرير أرقام المنافذ وعنوان الشبكة ESP8266.

ما يحدث هناك واضح من النافذة. لا
أقدم نص البرنامج هنا (وهو متاح على
Github ) ، للسبب التالي: 95٪ تقريبًا من حجمه هو إنشاء النافذة ومعالجة الإشارات من لوحة المفاتيح. لكن الجوهر هو نفس البرنامج السابق على جافا. يتم إنشاء عميل ، فقط UDP ، والذي ، اعتمادًا على المفتاح الذي تم الضغط عليه ، يرسل رقمًا من 1 إلى 8 ، على العنوان المحدد على المنفذ المحدد.
أو يمكنك الحصول على الملف التنفيذي على الفور
من هنا . لأجهزة 64 بت مع Windows. حتى بيئة JAVA المثبتة ليست ضرورية. تم دفع كل شيء بالفعل إلى 178 ميغابايت.
لذلك ، تم تجميع القلم الميكانيكي وتصحيحه وتقديمه إلى شقيقه بمناسبة الذكرى السنوية. يمكن التقاط أكوام بلاستيكية مع الفودكا ، على سكايب من مدينة أخرى. على الرغم من أن الذراع الميكانيكية لهوارد فولوفيتسا من سلسلة "نظرية الانفجار الكبير" ، إلا أنها لا تزال بعيدة.
ولكن في المقالات التالية (إذا كان أي شخص مهتمًا) ، سنكون قادرين على إدارتها من هاتف محمول ، ونفعل الشيء نفسه مع عربة روبوتية بأربع عجلات وتحديث الوقت في الساعات الإلكترونية من خوادم الساعة على الإنترنت. ثم نضع الهاتف الذكي القديم على العربة وننقل الفيديو منه إلى الشبكة العصبية مع التعرف على الأنماط ، ثم إشارات التحكم إلى المحركات ،
أوه ، شيء ما يحملني بالفعل ...وكل هذا مع ESP8266 الجميل.
سأكون سعيدا إذا وجد أي شخص المقالة مثيرة للاهتمام.
[1]
Pinout ومواصفات ESP8266[2]
توصيل ESP8266. بداية سريعة.[3]
تحديث البرامج الثابتة NodeMCU عبر السحابة[4]
NODE MCU PyFlasher[5]
ESPlorer - IDE لـ ESP8266[6]
برمجة C لـ AVR[7] مراجعة المقالات - "برمجة وحدات التحكم الدقيقة بلغة C"[8] وصف واجهة برمجة تطبيقات NodeMCU[9] مرجع Lua[10] نصوص ووحدات لوا[11] IntelliJ IDEA[12] قم بتنزيل Java على كمبيوتر سطح المكتب الآن![13] اتميل ستوديو