أهداف المشروع
بطريقة ما اتضح أنني بنيت منزلي ، هيكل عظمي. في أولي الفاخرة لا يوجد غاز وليس من المتوقع في المستقبل القريب ، ولهذا اخترت هيكلاً عظميًا - كل شيء آخر ، بالنسبة لي ، سيكون غاليًا جدًا للتدفئة باستخدام الكهرباء. حسنًا ، لأنها أيضًا واحدة من أرخص التقنيات.
حسناً ، لقد ألقيت الأنابيب في جميع أنحاء المنزل ، وعلقت البطاريات ، والمراجل ، بدا الأمر دافئًا ، لكن هناك خطأ ما.
بعد أن استمعت إلى نفسي ، أدركت أن هذا الضفدع لا يعجبني ، وأنني بينما أنا لست في المنزل (12-16 ساعة في اليوم) ، تعمل التدفئة. قد لا يعمل ، قم بتشغيله فقط قبل الوصول ، لأن الهيكل العظمي لديه قصور طفيف ويسمح لك برفع درجة الحرارة بسرعة. نفس الوضع عند مكان ما لفترة طويلة لمغادرة المنزل. حسنًا ، بشكل عام ، الجري ، إن تدوير مقبض المرجل مع تغيرات في درجة الحرارة في الشارع ليس بطريقة ما كوشير.
أصبح من الواضح أنه بدون التشغيل الآلي ، في أي مكان ، يكون المرجل هو الأبسط ، ولكن لديه جهات اتصال لتوصيل مرحل التحكم الخارجي. بالطبع ، يمكنك شراء غلاية على الفور بجميع الوظائف الضرورية ، لكن بالنسبة لي ، فإن هذه الغلايات غير إنسانية إلى حد ما. بالإضافة إلى أنني كنت أرغب في القرفصاء مع العقول ، والتأمل في شيء من أجل الروح ، وتعلم القليل من C ، وإن كان ذلك في نسخة اردوينو.
في الواقع حول المتطلبات:
- ضبط درجة الحرارة setpoint
- التحكم في درجة حرارة سائل التبريد اعتمادًا على درجة الحرارة في الهواء الطلق أو يدويًا
- المناطق الزمنية مع إعدادات مختلفة ، برودة في النهار ، وأكثر سخونة ليلا
- الوضع التلقائي ، مع الانتقال التلقائي ليلا ونهارا
- الوضع اليدوي ، لا التحولات السيارات ، لعطلة نهاية الأسبوع
- الوضع غير التلقائي ، حيث يمكنك ضبط أي درجة حرارة سائل التبريد يدويًا وتشغيل / إيقاف تشغيل المرجل
- التحكم في التسخين محليًا ، من الأزرار والشاشة ومن خلال موقع الويب / تطبيق الهاتف المحمول
كان ذلك في البداية ، ثم عانيت وأضاف:
- التحكم في مصباح الشارع (أضواء كاشفة LED)
- نظام الإنذار على أساس استشعار الحركة ، وصفارات الإنذار ومصباح الشارع
- قياس الطاقة التي يستهلكها المرجل في اليوم / الشهر / السنة + لكل شهر من العام
- وضع التنبيه فقط عن طريق اللمعان البطيء للمصباح
- وضع الإشارة عن طريق وميض سريع لمصباح وصفارات قصيرة من صفارات الإنذار
- وضع الإشارة عن طريق وميض سريع للمصباح وعويل مستمر من صفارات الإنذار
الغرض من هذا المقال هو تبادل الخبرات ، ووصف شيء باللغة الروسية لم أجده على الإنترنت. أعتقد أن هذه المقالة ستكون مفيدة للمبتدئين Arduino افعل ذلك بنفسهم الذين هم بالفعل على دراية بالبرمجة ، أشياء أساسية للغاية لم أصفها. حاولت أن أكتب الكود بوضوح قدر الإمكان ، وآمل أن أكون قد نجحت.
ما كان في البداية
في البداية ، تم تنفيذ المشروع على مجموعة كبيرة من Arduino Nano + ESP8266 ، ولكن ESP ليس كدرع ، ولكن كجهاز منفصل. لماذا هذا نعم ، لأنني حصلت بالفعل على كل هذا ، لكن لم يكن هناك مال من الكلمة على الإطلاق ، لذلك لم أكن أريد شراء حديد جديد من حيث المبدأ. لماذا ESP ليس مثل الدرع؟ الآن أنا لا أتذكر ذلك.
قاد Arduino جميع العمليات لأنه يحتوي على الكمية المطلوبة من GPIO ، وأرسل ESP جميع البيانات إلى خادم Blynk ، لأنه كان يعرف الإنترنت ولم يكن لديه GPIO كافيًا. ربطوا أنفسهم من خلال UART ، وأرسلوا JSON مع البيانات لبعضهم البعض. المخطط غير عادي ، لكنه نجح لمدة عام مع عدم وجود أي شكاوى تقريبًا. يمكن لأي شخص مهتم رؤية برنامج الترميز .
سوف أبدي تحفظًا على الفور ، لم أكن ماهرة جدًا في ذلك الوقت (وحتى الآن أرغب في القيام بذلك بشكل أفضل) ، لذلك من الأفضل ألا تراقب النساء الحوامل والأطفال. بالإضافة إلى ذلك ، تم كتابة كل شيء في Arduino IDE ، ولن يتم تذكره ليلًا ، والذي كان محدودًا جدًا من حيث إعادة التوطين ، فكل شيء بدائي للغاية هناك.
حديد
لذلك ، لقد مر عام ، وتمكنت الموارد المالية من شراء ESP32 devkit v1 ، التي تحتوي على ما يكفي من GPIO ، من الوصول إلى الإنترنت وبشكل عام وحدة تحكم فائقة. بالإضافة إلى النكات ، أحببتها كثيرًا في نهاية العمل.
قائمة الحديد:
- ESP32 devkit v1 noname الصين
- 3 أجهزة استشعار درجة الحرارة DS18B20 ، ودرجة الحرارة داخل المنزل ، في الخارج ودرجة حرارة المبرد في الأنابيب
- كتلة من 4 التبديلات
- جهاز استشعار البير HC-SR501
لن أرسم مخططًا ، أعتقد أن كل شيء سيكون واضحًا من وحدات الماكرو بأسماء المسامير.
لماذا FreeRTOS واردوينو كور
مجموعة من المكتبات مكتوبة على Arduino ، على وجه الخصوص ، Blynk نفسه ، لذلك لن تفلت من Arduino Core.
FreeRTOS لأنه يسمح لك بتنظيم عمل قطعة صغيرة من الحديد مماثلة لعمل وحدة تحكم صناعية كاملة. يمكن نقل كل مهمة إلى مهمتها الخاصة ، أو إيقافها ، أو تشغيلها ، أو إنشاؤها ، عند الضرورة ، حذفها - كل هذا أكثر مرونة بكثير من كتابة حماقة طويلة من كود Arduino ، عندما يتم كل شيء في النهاية بدوره في وظيفة الحلقة.
عند استخدام FreeRTOS ، سيتم تنفيذ كل مهمة في وقت محدد بدقة ، إذا كانت طاقة المعالج كافية فقط. على العكس من ذلك ، في Arduino يتم تنفيذ جميع التعليمات البرمجية في وظيفة واحدة ، في مؤشر ترابط واحد ، إذا تباطأ شيء ، سيتم تنفيذ بقية المهام مع تأخير. هذا ملحوظ بشكل خاص عند إدارة العمليات السريعة ، في هذا المشروع سوف نناقش هذا وميض المصباح وصفير الإنذار أدناه.
عن المنطق
حول مهام FreeRTOS
→ تصل إلى كامل الترميز للمشروع
لذلك ، عند استخدام FreeRTOS ، تلعب وظيفة الإعداد دور الوظيفة الرئيسية ، ونقطة الدخول إلى التطبيق ، ويتم إنشاء مهام FreeRTOS (المشار إليها فيما يلي بالمهام) ، لا يمكن استخدام وظيفة الحلقة على الإطلاق.
فكر في مهمة صغيرة لحساب درجة حرارة سائل التبريد:
void calculate_water_temp(void *pvParameters) { while (true) { if (heating_mode == 3) {} else { if (temp_outside > -20) max_water_temp = 60; if (temp_outside <= -20 && temp_outside > -25) max_water_temp = 65; if (temp_outside <= -25 && temp_outside > -30) max_water_temp = 70; if (temp_outside <= -30) max_water_temp = 85; } vTaskDelay(1000 / portTICK_RATE_MS); } }
تم إعلانها كدالة يجب أن تأخذ pvParameters pvParameters
، ويتم تنظيم حلقة لا نهاية لها داخل الوظيفة ، وأنا استخدمها while (true)
.
يتم vTaskDelay(1000 / portTICK_RATE_MS)
حسابية بسيطة لدرجة الحرارة (إذا كان وضع التشغيل يسمح بذلك) ثم يتم vTaskDelay(1000 / portTICK_RATE_MS)
من المهمة بواسطة vTaskDelay(1000 / portTICK_RATE_MS)
لمدة ثانية واحدة. في هذا الوضع ، لا يستهلك وقت وحدة المعالجة المركزية ، ويتم تخزين المتغيرات التي عملت بها المهمة ، وبمعنى آخر ، السياق ، على المكدس لإخراجها من هناك عندما يحين الوقت.
يجب إنشاء المهمة التالية في الإعداد. يتم ذلك عن طريق استدعاء الأسلوب xTaskCreate
:
xTaskCreate(calculate_water_temp, "calculate_water_temp", 2048, NULL, 1, NULL);
هناك العديد من الوسائط ، ولكن بالنسبة لنا ، تعتبر calculate_water_temp مهمة - اسم الدالة التي تحتوي على رمز المهمة و 2048 هو حجم المكدس بالبايت.
في البداية كان حجم الرصة يضبط الجميع على 1024 بايت ، ثم قمت بحساب الطريقة المطلوبة عن طريق الكتابة ، إذا بدأت وحدة التحكم في السقوط مع تجاوز سعة مكدس (كما يمكن رؤيته من الإخراج في uart) ، لقد قمت بزيادة حجم الرصة بمقدار 2 مرات ، إذا لم يساعد ، بمقدار مرتين وما إلى ذلك حتى يعمل. بالطبع ، هذا لا يحفظ الذاكرة أكثر من اللازم ، ولكن ESP32 لديه ما يكفي منها ، في حالتي ، لا يمكنك أن تهتم بهذا.
يمكنك أيضًا تحديد مؤشر للمهمة - مقبض يمكنك من خلاله التحكم في المهمة بعد الإنشاء ، على سبيل المثال - حذف. هذا هو NULL الأخير في المثال. يتم إنشاء مقبض مثل هذا:
TaskHandle_t slow_blink_handle;
بعد ذلك ، عند إنشاء مهمة ، xTaskCreate
تمرير مؤشر إلى المؤشر إلى المعلمة xTaskCreate:
xTaskCreate(outside_lamp_blinks, "outside_lamp_blynk", 10000, (void *)1000, 1, &slow_blink_handle);
وإذا أردنا إزالة المهمة ، فنحن نفعل ذلك:
vTaskDelete(slow_blink_handle);
يمكن رؤية كيفية استخدام ذلك في رمز panic_control
panic_control.
FreeRTOS الايجابيات
يستخدم Mutex لإزالة التعارضات بين المهام عند الوصول إلى الموارد مثل uart ، wifi ، إلخ. في حالتي ، كنت بحاجة إلى mutexes للواي فاي والوصول إلى ذاكرة فلاش.
إنشاء رابط إلى mutex:
SemaphoreHandle_t wifi_mutex;
في setup
بإنشاء مزامنة:
wifi_mutex = xSemaphoreCreateMutex();
علاوة على ذلك ، عندما نحتاج إلى الوصول إلى مورد المهمة ، فإنه يتطلب الأمر mutex ، مما يتيح لبقية المهام معرفة أن المورد مشغول ويجب ألا نحاول التعامل معه:
xSemaphoreTake(wifi_mutex, portMAX_DELAY);
portMAX_DELAY
- انتظر إلى أجل غير مسمى حتى يتم تحرير المورد و mutex من قبل مهام أخرى ، كل هذا الوقت سوف تنام المهمة.
بعد العمل مع المورد ، نعطي mutex بحيث يمكن للآخرين استخدامه:
xSemaphoreGive(wifi_mutex);
يمكنك رؤية الكود بمزيد من send_data_to_blynk
في send_data_to_blynk
send_data_to_blynk.
في الممارسة العملية ، كان عدم استخدام mutexes غير ملحوظ أثناء تشغيل وحدة التحكم ، ولكن أثناء تصحيح JTAG ، اختفت الأخطاء باستمرار والتي اختفت بعد استخدام mutexes.
وصف قصير من tasok
get_temps
- تلقي درجة الحرارة من أجهزة الاستشعار ، كل 30 ثانية ، في كثير من الأحيان ليس من الضروري.
get_time_task
- احصل على الوقت من خوادم NTP. في السابق ، كان الوقت قد حان من وحدة RTC DS3231 ، لكنها بدأت بالفشل بعد عام من العمل ، لذلك قررت التخلص منه على الإطلاق. قررت أن هذا ليس له أي تبعات خاصة بالنسبة لي ، حيث يؤثر الوقت بشكل رئيسي على تبديل المنطقة الزمنية للتدفئة - ليلا أو نهارا. إذا اختفى الإنترنت أثناء تشغيل وحدة التحكم ، فسوف يتجمد الوقت ببساطة ، وستظل المنطقة الزمنية كما هي. إذا كانت وحدة التحكم متوقفة عن التشغيل وبعد التشغيل ، لا يوجد إنترنت ، فسيكون الوقت دائمًا 0:00:00 - وضع التسخين في الليل.
calculate_water_temp
- المذكورة أعلاه.
detect_pir_move
- تلقي إشارة حركة من جهاز استشعار HC-SR501. يشكل المستشعر وحدة منطقية + 3.3 digitalRead
عند اكتشاف الحركة ، والتي يتم اكتشافها باستخدام digitalRead
، بالمناسبة ، يجب سحب دبوس اكتشاف هذا المستشعر إلى GND - pinMode(pir_pin, INPUT_PULLDOWN);
heating_control
- تبديل أوضاع التدفئة.
out_lamp_control
- التحكم في مصباح الشارع.
panic_control
- التحكم في صفارات الإنذار وأضواء كاشفة عند اكتشاف الحركة. لإنشاء تأثير صفارات الإنذار والمصابيح الوامضة ، يتم استخدام مهام منفصلة و siren_beeps
و siren_beeps
. عند استخدام FreeRTOS ، فإن الوميض والصفير يعملان تمامًا تمامًا ، تمامًا على الفواصل الزمنية المحددة ، لا تؤثر المهام الأخرى على عملهما ، لأن انهم يعيشون في تيارات منفصلة. يضمن FreeRTOS أن يتم تنفيذ التعليمات البرمجية في المهمة في الوقت المحدد. عند تنفيذ هذه الوظائف في loop
كل شيء يعمل بشكل سلس ، لأنه تتأثر بتنفيذ التعليمات البرمجية الأخرى.
guard_control
- التحكم في أوضاع الحراسة.
send_data_to_blynk
- إرسال البيانات إلى تطبيق Blynk.
run_blynk
- مهمة لتشغيل Blynk.run()
كما هو مطلوب بواسطة دليل استخدام Blynk. كما أفهمها ، هذا مطلوب للحصول على البيانات من التطبيق إلى وحدة التحكم. بشكل عام ، يجب أن يكون Blynk.run()
في loop
، لكنني في الأساس لا أريد وضع أي شيء هناك وجعله مهمة منفصلة.
write_setting_to_pref
- إعدادات التسجيل وأنماط التشغيل من أجل التقاطها بعد إعادة التشغيل. حول موصوفة وسيتم وصف أدناه.
count_heated_hours
- حساب وقت تشغيل المرجل. لقد قمت بذلك ببساطة ، إذا تم تشغيل المرجل في لحظة بدء المهمة (مرة واحدة كل 30 ثانية) ، في ذاكرة الفلاش ، تزداد قيمة المفتاح المطلوب بمقدار واحد.
send_heated_hours_to_app
- في هذه المهمة ، يتم استخراج القيم وضربها في 0.00833 (1/120 ساعة) ، ويتم إرسال ساعات تشغيل المرجل المستلمة إلى تطبيق Blynk.
feed_watchdog
- تغذية الوكالة الدولية للطاقة. اضطررت إلى كتابة الوكالة الدولية للطاقة ، لأنه مرة واحدة كل بضعة أيام وحدة تحكم يمكن تجميد. ما هو متصل به غير واضح ، قد يكون هناك نوع من التداخل في إمدادات الطاقة ، ولكن استخدام الوكالة الدولية للطاقة يحل هذه المشكلة. مؤقت الوكالة الدولية للطاقة 10 ثوان ، لا بأس إذا لم يكن جهاز التحكم متاحًا لمدة 10 ثوانٍ.
heart_beat
- مهمة مع النبض. عند تمرير وحدة التحكم ، أريد أن أعرف أنه يعمل بشكل جيد. لأن على Serial.begin(9600);
لا يوجد LED مضمن ، اضطررت إلى استخدام UART LED - تثبيت Serial.begin(9600);
واكتب سلسلة طويلة في UART. انها تعمل بشكل جيد جدا.
ESP32 NVS ارتداء التسوية
الأوصاف التالية غير واضحة إلى حد ما ، حرفيًا على الأصابع ، فقط لنقل جوهر المشكلة. مزيد من التفاصيل
يستخدم Arduino ذاكرة EEPROM لتخزين البيانات في ذاكرة غير متقلبة. هذه هي ذاكرة صغيرة يمكن فيها كتابة كل بايت ومسحها بشكل منفصل ، بينما يتم مسح ذاكرة الفلاش فقط حسب القطاعات.
لا توجد EEPROM في ESP32 ، ولكن توجد عادة ذاكرة فلاش بسعة 4 ميجابايت يمكنك من خلالها إنشاء أقسام لبرامج التحكم الثابتة أو لتخزين بيانات المستخدم. أقسام لبيانات المستخدم من عدة أنواع - NVS ، FATFS ، SPIFFS. يجب اختياره بناءً على نوع البيانات المعدة للتسجيل.
لأن جميع البيانات التي تتم كتابتها في هذا المشروع هي من النوع Int ، لقد اخترت NVS - التخزين بدون Volitile. هذا النوع من التقسيم مناسب تمامًا لتخزين البيانات الصغيرة التي غالباً ما تكون قابلة للكتابة. لفهم السبب ، يجب أن تتعمق في تنظيم NVS.
مثل EEPROM و FLASH ، هناك قيود على بيانات الكتابة ، يمكن الكتابة فوق وحدات البايت في EEPROM من 100،000 إلى 1،000،000 مرة ، وقطاع FLASH هو نفسه. إذا كتبنا البيانات مرة واحدة في الثانية ، فسنحصل على 60 ثانية × 60 دقيقة × 24 ساعة = 86400 مرة / يوم. هذا هو ، في هذا الوضع ، ستستمر البايتة 11 يومًا ، وهو قليل. وبعدها لن تكون البايت متاحة للكتابة والقراءة.
لتخفيف هذه المشكلة ، تقوم وظيفة update()
put()
الخاصة بمكتبة Arduino EEPROM بكتابة البيانات فقط عندما تتغير. بمعنى أنه يمكنك كتابة كل ثانية بعض الإعدادات ورموز الوضع التي نادراً ما تتغير.
يستخدم NVS طريقة مختلفة للتحكم في تسوية التآكل. كما ذكر أعلاه ، يمكن كتابة البيانات في قطاع الفلاش في أجزاء ، ولكن يمكن مسح القطاع بأكمله فقط. لذلك ، يتم تسجيل البيانات في NVS في نوع من المجلة ، وتنقسم هذه المجلة إلى صفحات ، يتم وضعها في قطاع واحد من ذاكرة الفلاش. تتم كتابة البيانات في أزواج من المفتاح: القيمة. في الواقع ، إنه أسهل من EEPROM ، لأن العمل باستخدام اسم مفيد أسهل من العمل باستخدام عنوان في الذاكرة. التحديثات: طول المفتاح لا يزيد عن 15 حرفًا!
إذا قمت أولاً بكتابة القيمة 1
إلى مفتاح ما ، ثم كتبت القيمة 2
إلى نفس المفتاح ، فلن يتم حذف القيمة الأولى ، وسيتم تعليمها فقط على أنها محذوفة (ستتم محوها) ، وستتم إضافة إدخال جديد إلى السجل:

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

بقدر ما فهمت من الوثائق الموجودة على موقع Espressif على الويب والمنتديات المختلفة ، يبدأ تنظيف الصفحة عندما تنتهي الصفحات المجانية. لكي تكون أكثر دقة ، وفقًا لهذا ، سيحدث المسح عندما تبقى صفحة واحدة فقط مجانية.
إذا كانت هناك حاجة إلى مسح الصفحة ، فسيتم نقل السجلات الحالية (غير الممحاة) إلى صفحة أخرى ، وتتم الكتابة فوق الصفحة.
وبالتالي ، فإن عملية محو الكتابة لكل صفحة معينة نادرة جدًا ، فكلما زاد عدد الصفحات - كلما كان ذلك أقل. بناءً على ذلك ، قمت بزيادة حجم قسم NVS إلى 1 ميغابايت ، وهذا بمعدل تسجيلي يكفي لمدة 170 عامًا ، وهو ما يكفي بشكل عام. حول تغيير حجم قسم NVS سيكون التالي.
من أجل العمل المريح مع NVS ، يوجد ESP32 لـ Arduino Core مكتبة مفيدة من التفضيلات مكتوبة ، وكيفية التعامل معها مكتوبة هنا .
قليلا عن VisualGDB
بمجرد أن بدأت العمل مع Arduino IDE ، فوجئت على الفور بالوظائف البائسة مقارنةً بـ Visual Studio. يقولون أن VS ليس نافورة ، رغم أنه يناسبني ، لكن كتابة ما يزيد عن 50 سطرًا في Arduino IDE مؤلمة ومؤلمة. وهكذا ، فإن السؤال الذي يطرح نفسه هو اختيار IDE للتنمية. لأن أنا على دراية VS ، أنا استقر على VisualGDB .
بعد تطوير Arduino IDE ، يعد تطوير ESP32 مجرد ملاذ آمن. ما هو الانتقال إلى التعريف ، والبحث عن المكالمات في المشروع والقدرة على إعادة تسمية المتغير.
تغيير جدول قسم ESP32 باستخدام VisualGDB
كما ذكر أعلاه ، يمكن تغيير الجدول باستخدام قسم ESP32 ، وسننظر في كيفية القيام بذلك.
يتم تحرير الجدول كملف CSV ، بشكل افتراضي VisualGDB يكتب الجدول التالي:
Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x140000, app1, app, ota_1, 0x150000,0x140000, spiffs, data, spiffs, 0x290000,0x170000,
هنا نرى قسمًا تحت NVS ، قسمين للتطبيقات ، وعدد قليل من الأقسام الأخرى. من الفروق الدقيقة ، يمكن ملاحظة أنه يجب دائمًا كتابة app0 (التطبيق الخاص بك) في الإزاحة 0x10000 ، بدءًا من الصفر ، وإلا فلن يكتشف محمل الإقلاع ذلك. أيضًا ، يجب تحديد الإزاحات بحيث لا "تتداخل" الأقسام مع بعضها البعض. يتم كتابة جدول القسم نفسه عند الإزاحة 0x8000. كما ترون ، حجم NVS في هذه الحالة هو 0x5000 - 20KB ، وهو ليس كثيرًا.
قمت بتعديل جدول القسم كما يلي:
Name, Type, SubType, Offset, Size, Flags app0, app, ota_0, 0x10000, 0x140000, nvs, data, nvs, , 1M, otadata, data, ota, , 0x2000, spiffs, data, spiffs, , 0x170000,
لا تنس إضافة شبكة قبل الاسم ، إذا كنت تستخدم هذا الجدول ، فأنت بحاجة إلى اعتبار هذا السطر تعليقًا.
كما ترون ، يتم زيادة حجم NVS إلى 1 ميغابايت. إذا لم تحدد الإزاحة ، فسيبدأ القسم فورًا بعد القسم السابق ، لذلك يكفي الإشارة إلى الإزاحة فقط للتطبيق 0. يمكن تحرير ملفات CSV في المفكرة كـ txt ثم قم بتغيير إذن ملف CSV للملف المحفوظ.
بعد ذلك ، يجب تحويل جدول القسم إلى ثنائي ، لأن يدخل وحدة التحكم في هذا النموذج. للقيام بذلك ، قم بتشغيل المحول:
c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\tools\gen_esp32part.exe part_table_name.csv part_table_name.bin
. المعلمة الأولى هي CSV ، والمعلمة الثانية هي المخرجات الثنائية.
يجب وضع الثنائي الناتج في c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\tools\partitions\part_table_name.csv
، وبعد ذلك من الضروري تحديد أنه هو الذي تم اتخاذه لبناء الحل ، و لا يوجد جدول التقسيم الافتراضي. يمكنك القيام بذلك عن طريق كتابة اسم الجدول الخاص بك في الملف c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\boards.txt
. في حالتي ، هذا هو esp32doit-devkit-v1.build.partitions=part_table_name
بعد هذه المعالجة ، سيأخذ VisualGDB عند إنشاء التطبيق جدول القسم الخاص بك ويضعه في وضعه الصحيح
~project_folder_path\Output\board_name\Debug\project_name.ino.partitions.bin
، من حيث سيتم سكبه بالفعل في اللوحة.
JTAG مصحح الأخطاء CJMC-FT232H
بقدر ما أعرف ، هذا هو أرخص مصحح أخطاء يمكنه العمل مع ESP32 ، لقد كلفني حوالي 600 روبل ، وهناك الكثير منهم على Aliexpress.

عند توصيل المصحح ، يقوم Windows بتثبيت برامج التشغيل غير المناسبة التي يجب تغييرها باستخدام برنامج Zadig ، كل شيء بسيط هناك ، لن أصف ذلك.
يتصل ESP32 devkit-v1 بالطريقة التالية:
FT232H - ESP32
AD0 - GPIO13
AD1 - GPIO12
AD2 - GPIO15
AD3 - GPIO14
بعد ذلك ، في Project -> VisualGDB Project Properties
تحتاج إلى إجراء الإعدادات التالية:

ثم انقر فوق اختبار. في بعض الأحيان يحدث أن الاتصال لم يتم تأسيسه لأول مرة ، ويبدو أن العملية تتجمد ، ثم تحتاج إلى مقاطعة وتكرار اختبار. إذا كان كل شيء على ما يرام ، فإن عملية اختبار الاتصال تستغرق حوالي 5 ثوان.
عادةً ما أقوم بتجميع المشروع وتحميله عبر USB إلى ESP32 نفسه (وليس عبر مصحح الأخطاء) ، وبعد ذلك بدأت في تصحيح الأخطاء باستخدام Debug -> Attach to Running Embedded Firmware
. في التعليمات البرمجية ، يمكنك تعيين نقاط التوقف وإلقاء نظرة على قيم المتغيرات في وقت التعطل وفي نافذة Debug -> Windows -> Threads
الترابط التي يمكنك من خلالها معرفة مهمة FreeRTOS التي أوقفتها التعليمات البرمجية ، وهو أمر مفيد في حالة حدوث خطأ أثناء تصحيح الأخطاء. كانت هذه الوظائف من مصحح الأخطاء كافية بالنسبة لي للعمل بشكل مريح.
عندما بدأت العمل مع NVS ، تمت مقاطعة تصحيح الأخطاء باستمرار بسبب الأخطاء الغامضة. كما أفهمها ، فهذا لأن مصحح الأخطاء يحتاج إلى إنشاء شيء مثل تفريغ في قسم NVS الافتراضي ، ولكن في هذا الوقت يتم استخدام NVS بالفعل بواسطة وحدة التحكم. بالطبع ، يمكن التحايل على ذلك من خلال إنشاء قسمين لـ NVS ، أحدهما يحمل الاسم الافتراضي لتصحيح الأخطاء والآخر لاحتياجاته الخاصة. لكن لم يكن هناك شيء معقد ، في الكود المضاف ، كان يعمل في المرة الأولى ، لذلك لم أتحقق منه.
مواطن الخلل ESP32
مثل أي جهاز مع Aliexpress ، كان لوحي ESP32 الخاص به خلل غير موصوف في أي مكان. عندما وصلت ، أطعمت بعض الأجهزة الطرفية التي عملت على I2C من اللوحة ، ولكن بعد مرور بعض الوقت ، بدأت اللوحة في إعادة التشغيل إذا كانت هناك أي معدات مستهلكة أو حتى مجرد مكثف مثبتًا على الساق + 5V. لماذا هذا غير مفهومة تماما.
الآن يمكنني تشغيل اللوحة من الشحنة الصينية 0.7A ، وأجهزة استشعار ds18b20 من سفح لوحة 3.3V ، ومستشعر الترحيل والحركة من شحنة أخرى تبلغ 2A. وبطبيعة الحال ، فإن قدم GND للوحة متصل بدبابيس GND لبقية الحديد. رخيصة والبهجة هو خيارنا.
عن نتائج المشروع
حصلت على فرصة للسيطرة بمرونة على التدفئة في المنزل ، وتوفير المال والعرق المكتسبة. في الوقت الحالي ، إذا كان التدفئة يحتفظ بـ 23 درجة طوال اليوم عند -5 - -7 بالخارج ، فهو في مكان ما حوالي 11 ساعة من تشغيل الغلاية. إذا حافظت خلال اليوم على 20 درجة ودافئة إلى 23 فقط في المساء ، فهذا بالفعل 9 ساعات من تشغيل الغلاية. تبلغ سعة الغلاية 6 كيلو وات ، ويبلغ السعر الحالي للكيلووات 2.2 روبل ، أي حوالي 26.4 روبل يوميًا. مدة موسم التدفئة في منطقتنا هي 200 يوم ، ومتوسط درجة الحرارة في موسم التدفئة حوالي -5 درجة فقط. وبالتالي ، نحصل على حوالي 5000r وفورات لموسم التدفئة.
لا تتعدى تكلفة المعدات 2000 ريال ، أي أن التكاليف سيتم صدها في غضون بضعة أشهر ، ناهيك عن حقيقة أن نظام جاهز لمثل هذه الأتمتة سيكلف 20000 ريال على الأقل. شيء آخر هو أنني قضيت حوالي أسبوع من وقت العمل الخالص في كتابة البرامج الثابتة وتصحيح الأخطاء ، ولكن في أثناء العمل ، على سبيل المثال ، أدركت أخيرًا ما هي المؤشرات في C ++ وحصلت على الكثير من الخبرة الأخرى (على سبيل المثال ، تجربة ساعات طويلة من تصحيح الأخطاء غير المفهومة). والخبرة ، كما تعلمون ، يصعب المبالغة في تقديرها.
لقطات من تطبيق Blynk للهاتف المحمول:



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