دورة تطوير كاملة لجهاز IoT للتحكم في تسخين حمام السباحة على ESP8266 في بيئة Arduino

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


قبل إنشاء هذا الجهاز ، قمت بما يلي:


  • تقريبا لم يفهم الدوائر الكهربية. فقط على مستوى مبادئ العمل
    المقاوم / الترانزستور ... لم يكن لدي خبرة في إنشاء أي دوائر معقدة.
  • لم تصمم لوحات الدوائر.
  • أبدا ملحوم مكون SMD. كان مستوى لحام الحديد على مستوى أسلاك اللحام ونوع من التتابع.
  • لم أكتب أبدا مثل هذه البرامج المعقدة لمتحكم دقيق. كانت التجربة بأكملها على مستوى "إضاءة LED في Arduino" ، وقابلت أولاً وحدة تحكم ESP8266.
  • لقد كتبت القليل جدًا من C ++ لـ "الأخ الأكبر" ، لكن ذلك كان منذ أكثر من اثني عشر عامًا ونسي كل شيء منذ فترة طويلة.

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


بيان المشكلة


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



تقرير مصور عن بناء القبة على فليكر.


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


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



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


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


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


يجب أن يكون من الممكن حماية ارتفاع درجة حرارة المبادل الحراري.


حل سريع


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


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


لذلك ، من المهم الاستجابة في أقرب وقت ممكن: أي إيقاف تدفق المياه في الدائرة
تجمع.


تم استخدام جهاز استشعار التدفق مثل . تسمح العلبة البلاستيكية وقلة ملامسة المستشعر للماء باستخدامه في الماء المملح.


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



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


مواقع الاستشعار على مبادل حراري وأنابيب مدخل

معلمات الجهاز


تم بناء النموذج الأولي الأول للجهاز على أساس Arduino Uno ، وتم إطلاقه بنجاح.



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


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


الاختصاصات


لذلك ، تقرر تطوير جهاز - وحدة تحكم تجمع متعددة الوظائف. يجب أن يكون قادراً على:


  • للتحكم في تسخين المسبح من خلال المبادل الحراري ، قم بتشغيل / إيقاف تشغيل غلاية الغاز لتسخين المياه.
  • منع ارتفاع درجة حرارة المبادل الحراري من خلال مراقبة وجود تدفق مياه البركة في الدائرة الثانوية ودرجة الحرارة الزائدة للدائرة الثانوية.
  • عرض إحصاءات التدفئة في الوقت الحقيقي (درجة الحرارة في مدخل ومخرج كلتا الدائرتين).
  • سجل (سجل) درجات الحرارة في ذاكرة فلاش. عرض البيانات لـ
    فترة معينة في شكل رسم بياني.
  • باستخدام التتابع ، يمكنك تشغيل / إيقاف مضخات البركة والكلورة.
  • قم بإدارة جميع معلمات الجهاز عن بُعد من خلال خادم الويب الصغير المدمج.

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


الأجهزة


كوحدة تحكم ، تقرر استخدام ESP8266 الرخيصة والشعبية. كانت مثالية لأغراضي ، باستثناء شيء واحد: مطابقة مستويات الإشارة من أجهزة استشعار 5 فولت مع منطق تحكم 3.3 فولت. من حيث المبدأ ، يبدو أن أجهزة استشعار دالاس تعمل عند 3 فولت ، لكن لدي خط طويل إلى حد ما من وحدة التحكم إلى أجهزة الاستشعار ، حوالي 7 أمتار. لذلك ، من الأفضل زيادة الجهد.


تم تحديد أنه من الضروري الحصول على الأجهزة:


  • جهاز تحكم ESP8266 أو شقيقه الأكبر ESP32 (كوحدة DevKit ).
  • محاذاة مستويات الإشارة لأجهزة الاستشعار.
  • منظم الطاقة هو جزء 5 فولت من الدائرة.
  • وحدة التحكم في التتابع.
  • ساعة RTC + ذاكرة فلاش للتسجيل.
  • أبسط شاشة LCD من سطرين لعرض القيم الحالية لأجهزة الاستشعار وحالة الجهاز والمرحل.
  • عدة أزرار فعلية للتحكم في حالة الجهاز دون الوصول عبر الويب.

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


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


مخطط الدائرة


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


الصعوبة الأولى التي واجهتها: هناك الكثير من الخيارات لوحدة تحكم DevKit ESP8266 أو ESP32 ، بعضها يختلف في موقع الدبابيس والغرض منها ، وبعضها حتى في العرض. تقرر رسم الدائرة بحيث كان من الممكن وضع DevKit من أي عرض ومع أي موقع للأطراف ، وعلى جانبيها - صفين من فتحات الطائر ، وبعد ذلك الأسلاك لتوصيل المحطات الضرورية ، فيما يتعلق بوحدة التحكم التي تم شراؤها على وجه التحديد.


ضع تحت وحدة التحكم وصفين من وصلات القفز المزدوجة: JH1 و JH2 في الرسم البياني:



يبدو أن موقع دبابيس الإدخال 5v والإخراج 3.3 فولت من مصدر الطاقة للمثبت المدمج ، وكذلك GND ، هو نفسه بالنسبة إلى DevKit المختلفة ، ولكنني قررت مع ذلك تشغيله بأمان وجعلهم لاعبين: JP1 ، JP2 ، JP3 في الرسم التخطيطي.


قررت التوقيع على وصلات العبور بتوصيلها بمكونات الدائرة بوظائف من المحتمل أن تؤديها.


وإليك ما يبدو مع DevKit ESP8266 ، الذي اشتريته في النهاية وقمت بتثبيته

هنا D1 (GPIO5) و D2 (GPIO4) مسؤولون عن ناقل I2C ، D5 (GPIO14) لسلك واحد ، D6 (GPIO12) - لاستقبال النبضات من مستشعر التدفق.


مخطط الدائرة:



(الصورة قابلة للنقر)


على الرغم من وجود ESP8266 على متن منظم الطاقة المدمج لـ 3.3 فولت ، ما زلنا بحاجة إلى 5 فولت لتشغيل المستشعرات وشاشة LCD ، و 12 فولت لتشغيل التتابع. تقرر جعل طاقة اللوحة 12 فولت ، ووضع منظم الجهد AMS1117-5.0 عند الإدخال ، مما يعطي 5 فولت المطلوب عند الإخراج.


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



جيد جدًا حول مطابقة المستوى مكتوب في المقالة مطابقة المستويات المنطقية لأجهزة 5V و 3.3V .


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



الأزرق في الرسم التخطيطي هو تعيين تخطيطي لمجموعة مستشعر التدفق. على يمين الموصل توجد فواصل الجهد التي حددتها من أجل الحصول على مستوى أقصى يبلغ 3.3 فولت عند الإخراج.


في حافلة I2C ، قمت بتعليق ساعة DS3231SN في الوقت الفعلي وذاكرة فلاش AT24C256C لتخزين السجلات. ذاكرة الفلاش المدمجة في ESP8266 غير مناسبة ، لأنها تحتوي على عدد صغير من دورات إعادة الكتابة (10 آلاف مقابل مليون لـ AT24Cxxx ، وفقًا لأوراق البيانات).


يتم تنظيم التحكم في التتابع على مجموعة من رقائق PCF8574AT و ULN2803A.



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


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


يتم وصف مزيد من المعلومات حول الشريحة هنا .


يمكن أيضًا استخدام موسع PCF8574AT كمدخل: يمكن تعليق أزرار الأجهزة على بعض المدخلات إليه ، وقراءة قيمها على ناقل I2C. في الرسم البياني ، يمكن استخدام الدبابيس 4-7 لقراءة حالة الأزرار. الشيء الرئيسي هو عدم نسيان التمكين المبرمج لشد الأرجل المقابلة للتغذية.


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


يمكن استخدام دبوس موسع منفذ INT للاستجابة بسرعة للضغط على زر. يمكن توصيله بمنفذ حر على وحدة التحكم وتعيين مشغل المقاطعة لتغيير حالة هذا الدبوس.


يتم التحكم في شاشة LCD ذات الخطين أيضًا من خلال موسع PCF8574AT. النقطة الرئيسية: يتم تشغيل الشاشة بواسطة 5 فولت ، بينما يتم التحكم في الشاشة نفسها بواسطة منطق 3 فولت. بالمناسبة ، لم يتم تصميم محولات Arduino القياسية لـ I2C للجهد المزدوج. لقد وجدت فكرة مثل هذا الاتصال في مكان ما على الإنترنت ، للأسف ، فقدت الرابط ، لذلك لا أذكر المصدر.


لوحة الدوائر


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


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


لقد صنعت لوحة دوائر مطبوعة بقياس 97x97 ملم. تناسبها بسهولة في صندوق كهربائي قطع قياسي. بالإضافة إلى ذلك ، فإن اللوحات ذات الأحجام الأقل من 100 × 100 رخيصة الصنع. يكلف إنتاج مجموعة صغيرة من 5 لوحات وفقًا للتخطيط المطور 5 دولارات أمريكية ، ويكلف تسليمها إلى روسيا البيضاء 9 دولارات أمريكية أخرى.



يقع تصميم اللوحة على موقع EasyEDA ومتاح للجميع.


ألاحظ أنه في صورة وحدة التحكم أدناه تظهر العينة الأولى من اللوحة ، حيث قمت "بلف" الكثير من الأشياء غير الضرورية وغير الضرورية (على أمل استخدام هذه المجموعة الدنيا من 5 لوحات في مشاريع أخرى). هنا وعلى موقع EasyEDA نشرت نسخة "نظيفة" من كل هذه الأشياء غير الضرورية.



صور لكلا الجانبين

الجانب الأمامي:



الجانب الخلفي:



جزء البرنامج


لبرمجة وحدة التحكم الدقيقة ، نظرًا للتراكم في شكل نموذج أولي على Arduino Uno ، تقرر استخدام بيئة Arduino مع تثبيت ESP8266 Arduino Core . نعم ، يمكنك استخدام Lua على ESP8266 ، لكنهم يقولون أن هناك تعليق. أنا ، بالنظر إلى الوظيفة الحرجة التي تؤديها ، لا أريد على الإطلاق.
تبدو بيئة Arduino نفسها قديمة جدًا بالنسبة لي ، ولكن لحسن الحظ ، هناك ملحق لـ Visual Studio من Visual Micro. تسمح لك البيئة باستخدام تلميحات كود IntelliSence ، والقفز السريع إلى الإعلانات الوظيفية ، ورمز ريفاكتور: بشكل عام ، كل ما تسمح به البيئة لأجهزة الكمبيوتر "البالغة". تسمح لك النسخة المدفوعة من Visual Micro أيضًا بتصحيح الكود بسهولة ، لكنني كنت راضيًا عن الخيار المجاني.

هيكل المشروع


يتكون المشروع من الملفات التالية:
هيكل المشروع في Visual Studio

ملفالتعيين
WaterpoolManager.ino
الإعلان عن المتغيرات والثوابت الأساسية. التهيئة. الحلقة الرئيسية.
هيتر ماين لوجيك.ينو
المنطق الأساسي للتحكم في مرحل المرجل (وفقًا لدرجة الحرارة) والمرحلات المساعدة.
مجسات .ino
قراءة بيانات الاستشعار
Settings.ino
إعدادات الجهاز ، وحفظها في ذاكرة فلاش تحكم
LCD.ino
إخراج المعلومات على شاشة LCD
ClockTimer.ino
RTC ساعة القراءة ، أو محاكاة الساعة
التبديلات .ino
التحكم في تشغيل / إيقاف التتابع
ButtonLogic.ino
منطق رد فعل لحالة أزرار الأجهزة
ReadButtonStates.ino
قراءة حالات زر الجهاز
EEPROM_Logging.ino
تسجيل بيانات الاستشعار في EEPROM
WebServer.ino
خادم ويب مدمج لإدارة الجهاز وعرض الحالة
صفحات الويب
يتم تخزين صفحات خادم الويب في هذا المجلد.
الفهرس. h
الصفحة الرئيسية لعرض حالة الجهاز. قراءة الحالة الحالية مع مكالمة أجاكس. قم بالتحديث كل 5 ثوانٍ.
loggraph.h
يعرض سجل بيانات المستشعر وحالات الترحيل في رسم بياني. يتم استخدام مكتبة jqPlot - تتم جميع أعمال الإنشاء من جانب العميل. يذهب طلب وحدة التحكم فقط إلى ملف ثنائي - نسخ من البيانات من EEPROM.
logtable.h
أيضا ، ولكن في شكل جدول
الإعدادات. h
إدارة إعدادات الجهاز: وضع حدود لدرجة الحرارة ، وتدفق المياه ، وتكرار تسجيل البيانات
الوقت
إعداد الوقت الحالي

مكتبات
EepromLogger.cpp
مكتبة سجل فلاش
EepromLogger.h
crc8.cpp
عد CRC 8 بت للمكتبة
crc8.h
TimeSpan.cpp

TimeSpan.h


OneWire tempSensAddr. . ( 4 ):


while (ds.search(tempSensAddr[lastSensorIndex]) && lastSensorIndex < 4) { Serial.print("ROM ="); for (byte i = 0; i < 8; i++) { Serial.print(' '); Serial.print(tempSensAddr[lastSensorIndex][i], HEX); } if (OneWire::crc8(tempSensAddr[lastSensorIndex], 7) != tempSensAddr[lastSensorIndex][7]) { Serial.print(" CRC is not valid!"); } else lastSensorIndex++; Serial.println(); } ds.reset_search(); lastSensorIndex--; Serial.print("\r\nTemperature sensor count: "); Serial.print(lastSensorIndex + 1, DEC);  ,       ().       Serial   LCD  : // Read sensor values and print temperatures ds.reset(); ds.write(0xCC, TEMP_SENSOR_POWER_MODE); // Request all sensors at the one time ds.write(0x44, TEMP_SENSOR_POWER_MODE); // Acquire temperatures delay(1000); // Delay is required by temp. sensors char tempString[10]; for (byte addr = 0; addr <= lastSensorIndex; addr++) { ds.reset(); ds.select(tempSensAddr[addr]); ds.write(0xBE, TEMP_SENSOR_POWER_MODE); // Read Scratchpad tempData[addr] = ds.read() | (ds.read() << 8); // Read first 2 bytes which carry temperature data int tempInCelsius = (tempData[addr] + 8) >> 4; // In celsius, with math rounding Serial.print(tempInCelsius, DEC); // Print temperature Serial.println(" C"); } 

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


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


 #define TEMP_MEASURE_PERIOD 20 // Time of measuring, * TEMP_TIMER_PERIODICITY ms #define TEMP_TIMER_PERIODICITY 50 // Periodicity of timer calling, ms timer.attach_ms(TEMP_TIMER_PERIODICITY, tempReadTimer); int tempMeasureCycleCount = 0; void tempReadTimer() // Called many times in second, perform only one small operation per call { tempMeasureCycleCount++; if (tempMeasureCycleCount >= TEMP_MEASURE_PERIOD) { tempMeasureCycleCount = 0; // Start cycle again } if (tempMeasureCycleCount == 0) { ds.reset(); ds.write(0xCC, TEMP_SENSOR_POWER_MODE); // Request all sensors at the one time ds.write(0x44, TEMP_SENSOR_POWER_MODE); // Acquire temperatures } // Between phases above and below should be > 750 ms int addr = TEMP_MEASURE_PERIOD - tempMeasureCycleCount - 1; if (addr >= 0 && addr <= lastSensorIndex) { ds.reset(); ds.select(tempSensAddr[addr]); ds.write(0xBE, TEMP_SENSOR_POWER_MODE); // Read Scratchpad tempData[addr] = ds.read() | (ds.read() << 8); // Read first 2 bytes which carry temperature data } } 

في بداية كل دورة tempMeasureCycleCount ، يُطلب من أجهزة الاستشعار قراءة قيمها. بعد مرور حوالي 50 دورة كهذه (وإجماليها 50 * 20 = 1000 مللي ثانية = 1 ثانية) ، تتم قراءة قيمة كل جهاز استشعار ، واحدة في كل مرة. يتم تقسيم كل العمل إلى أجزاء بحيث لا يستغرق الرمز الذي يتم تشغيله في مقاطعة المؤقت الكثير من الوقت من وحدة التحكم.


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


 pinMode(FLOW_SENSOR_PIN, INPUT); attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), flow, RISING); // Setup Interrupt volatile int flow_frequency; // Flow sensor pulses int flowMeasureCycleCount = 0; void flow() // Flow sensor interrupt function { flow_frequency++; } 

في نفس الوقت الذي يتم فيه استجواب مستشعرات درجة الحرارة ، نأخذ قيمة التجزئة هذه مرة واحدة في الثانية ونترجمها إلى لتر باستخدام ثابت FLOW_SENSOR_CONST ، والذي يمكن العثور على قيمته في خصائص المستشعر:


 flowMeasureCycleCount++; if (flowMeasureCycleCount >= 1000 / TEMP_TIMER_PERIODICITY) { flowMeasureCycleCount = 0; litersInMinute = (flow_frequency / FLOW_SENSOR_CONST); // Pulse frequency (Hz) = FLOW_SENSOR_CONST*Q, Q is flow rate in L/min. flow_frequency = 0; // Reset Counter } 

تسجيل البيانات من أجهزة الاستشعار وحالة الجهاز


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


بعد بعض "التراكم" ، تم اختراع وتنفيذ نموذج التسجيل التالي:



كل سجل هو سجل يحتوي على معلومات حول القيمة الحالية لتدفق المياه ، ودرجات حرارة المستشعر ، بالإضافة إلى حالة الجهاز المشفر في البايت (تشير البتات الفردية إلى ما إذا كان التتابع قيد التشغيل أم لا ، وما إذا كان التسخين ممكّنًا أم لا):


 struct LogEvent { unsigned char litersInMinute = 0; unsigned char tempCelsius[4]{ 0, 0, 0, 0 }; unsigned char deviceStatus = 0; } 

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


نظرًا لأنه سيكون من المكلف للغاية تسجيل البيانات في الوقت الحالي ( الطابع الزمني ) لكل سجل من حيث الحجم ، يتم تنظيم البيانات في كتل كبيرة ، مع تسجيل N في كل سجل. يتم تسجيل الطابع الزمني لكل كتلة مرة واحدة فقط ، أما بالنسبة للباقي - فيتم حسابه بناءً على معلومات حول تكرار التسجيل.


 unsigned int logRecordsInBlock = 60 * 60 / loggingPeriodSeconds; // 1 block for hour unsigned int block_size = sizeof(Block_Header) + logRecordsInBlock * (record_size + crcSize); unsigned int block_count = total_storage_size / block_size; 

على سبيل المثال ، مع تكرار تسجيل مرة واحدة كل 30 ثانية ، سيكون لدينا 120 إدخالاً في كتلة ، وسيكون حجم الكتلة حوالي 840 بايت. في المجموع ، يمكننا احتواء 39 كتلة في ذاكرة محرك أقراص محمول بحجم 32 كيلوبايت. مع مثل هذه المنظمة ، اتضح أن كل كتلة تبدأ في عنوان محدد بدقة في الذاكرة ، و "الجري عبر" جميع الكتل ليست مشكلة.


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


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


شاشات الكريستال السائل


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


الرسوم البيانية


عند الطلب من خلال خادم الويب المدمج ، تتم قراءة بيانات التسجيل في شكل ثنائي باستخدام JavaScript:


 var xhttp = new XMLHttpRequest(); xhttp.open("GET", "logs.bin", true); xhttp.responseType = "arraybuffer"; xhttp.onprogress = updateProgress; xhttp.onload = function (oEvent) { var arrayBuffer = xhttp.response; if (arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer); … }}; xhttp.send(null); 

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


لنفس السبب ، يتم استخدام مكتبة جافا سكريبت jqPlot لإنشاء الرسوم البيانية ، ويتم تحميل ملفات مكتبة JS نفسها من شبكات CDN الشائعة.


مثال على الجدول الزمني للجهاز:



من الواضح أنه في حوالي الساعة 9:35 تم تشغيل الجهاز للتدفئة ، وبدأت الغلاية في تسخين دائرة التسخين تدريجيًا (المستشعرات T3 ، T4) ، وبعد ذلك بدأت درجة حرارة دائرة المسبح في الزيادة (المستشعرات T1 ، T2). في حوالي الساعة 10:20 ، تحولت الغلاية إلى تسخين الماء الساخن في المنزل ، وانخفضت درجة حرارة دائرة التسخين. ثم بعد 10 دقائق أخرى ، عادت الغلاية لتسخين مياه البركة. في الساعة 10:50 وقع حادث: فجأة تم إيقاف تشغيل مضخة تدوير المياه في المسبح. انخفض تدفق المياه بشكل حاد إلى الصفر ، وتم إيقاف تتابع التدفئة (خط منقط أحمر على الرسم البياني الثاني) ، مما يمنع ارتفاع درجة الحرارة. لكن الجهاز لا يزال في حالة تسخين (خط أحمر على الرسم البياني الثاني). على سبيل المثال إذا تم تشغيل المضخة مرة أخرى وكانت درجات الحرارة طبيعية ، فسيعود الجهاز إلى التسخين. ألاحظ أنه بعد الإغلاق الطارئ للمضخة ، بدأت درجات الحرارة في دائرة ماء التجمع (T1 ، T2) في الزيادة بشكل حاد بسبب ارتفاع درجة حرارة المبادل الحراري. وإذا لم يكن هناك إغلاق حاد للغلاية ، فستكون هناك مشكلة.


خادم الويب المضمن


للتواصل مع العالم الخارجي ، يتم استخدام الفئة القياسية ESP8266WebServer . عند بدء تشغيل الجهاز ، تتم تهيئته كنقطة وصول باستخدام كلمة المرور الافتراضية المحددة في # تعريف AP_PASS. تفتح صفحة الويب تلقائيًا لتحديد شبكة wi-fi المتاحة وإدخال كلمة مرور. بعد إدخال كلمة المرور ، يقوم الجهاز بإعادة التشغيل والاتصال بنقطة الوصول المحددة.


جهاز منتهي


تم وضع الجهاز النهائي في صندوق قطع قياسي للأسلاك. تم قطع فتحة لشاشة LCD فيه ، وثقوب للموصلات.



صور واجهة الجهاز بأوضاع مختلفة

مع عرض الوقت المنقضي بعد التشغيل:



مع حدود معروضة:



الخلاصة


في الختام ، أود أن أقول أنه ، بتطوير مثل هذا الجهاز ، حصلت على تجربة رائعة مع الدوائر ، وتصميم PCB ، ومهارات التثبيت لمكونات SMD ، في هندسة وبرمجة وحدات التحكم الدقيقة ، تذكرت تقريبًا C ++ والمعالجة الدقيقة للذاكرة وموارد تحكم أخرى محدودة. كانت معرفة HTML5 وجافا سكريبت ومهارات تصحيح النصوص في المتصفح مفيدة أيضًا إلى حد ما.


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

Source: https://habr.com/ru/post/ar413955/


All Articles