FLProg + Nextion HMI. الدرس 2



في الدرس الأخير ، تحدثت عن لوحة Nextion HMI وعن إنشاء مشاريع لهذه اللوحة في محرر Nextion.
في هذا البرنامج التعليمي ، سأوضح لك كيفية التحكم في هذه اللوحة باستخدام برنامج FLProg من لوحة Arduino. على سبيل المثال ، دعنا نجمع أبسط محطة أرصاد جوية ، والتي ستقرأ البيانات من مستشعر درجة الحرارة والرطوبة DHT-22 وعرضها على اللوحة. سيتم أيضًا رسم رسم بياني للتغييرات في هذه المعلمات. سيتم تغيير سطوع الإضاءة الخلفية لشاشة اللوحة باستخدام مقاوم متغير.

اختبار تخطيط مقاعد البدلاء.


تحتاج أولاً إلى تحميل المشروع على اللوحة (ملف المشروع في الأرشيف هو رابط في نهاية المقال هو Lesson2.hmi).
يتكون هذا المشروع من ثلاث شاشات.
يتم استخدام الشاشة الأولى لعرض درجة الحرارة (فهرس الصفحة "page0" - 0).



وتتكون من العناصر التالية:
1 - صورة بصورة ترمومتر كحولي.
2 - عنصر "شريط التقدم". بمساعدتها ، يتم محاكاة مقياس الحرارة.

إعدادات العنصر.


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

معلمات العنصر.


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

معلمات العنصر.


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





يعرض العنصر جزء الصورة المرفقة به (السمة "picc" هي فهرس الصورة في مكتبة الصور). الركن العلوي الأيسر من هذا القسم موجود في إحداثيات الإدراج للعنصر (السمتان "x" و "y") وله عرض العنصر وارتفاعه (السمتان "w" و "h"). أثناء تشغيل برنامج التحكم ، إذا لزم الأمر ، سيتم تغيير ربط العنصر بالصورة.

5. زر.

معلمات العنصر.


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

الرمز في حدث "Touch Press Event".


تُستخدم الشاشة الثانية لعرض الرطوبة (فهرس الصفحة "page1" - 1).


لخلفية الصفحة ، استخدمت صورة مع صورة معدة لمقياس الرطوبة.


ضع في اعتبارك العناصر المضمنة في الصفحة.

1. عنصر "Gaude" الذي سيحاكي تشغيل جهاز قياس الرطوبة.

معلمات العنصر.


نظرًا لأننا سنسيطر عليه من وحدة التحكم ، فإنه يصبح عالميًا. يتم تحديد الصورة المقطوعة (سمة "sta") كخلفية ، ويتم تحديد صورة خلفية الصفحة (سمة "picc") كخلفية.

2. المجال الرقمي.

معلمات العنصر.


سيتم عرض قيمة الرطوبة في هذا المجال. نظرًا لأن اللوحة لا تدعم العمل مع الأرقام الكسرية ، فسنعرض قيمة الرطوبة بدون جزء كسري. يتم تحديد الصورة المقطوعة كخلفية (السمة القيمة "sta" "صورة الاقتصاص"). وكما هي الصورة المستخدمة في القطع ، يتم استخدام نفس الصورة المستخدمة لخلفية الصفحة بأكملها (السمة "picc" هي فهرس الصورة من مكتبة الصور). من أجل جمال العرض ، قمت بتعيين محاذاة إلى اليمين (السمة "xcen" - 2) ، وبجانبها أضع حقل نص (3) بالقيمة "٪". إعدادات الخلفية لها مشابهة لإعدادات حقل الرقم.

خيارات حقل النص (3).


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

إعدادات الزر 4 ("الصفحة السابقة")


في "حدث الضغط باللمس" للزر 4 ("الصفحة السابقة"). رمز


زر إعدادات 5 ("الصفحة التالية")


في "حدث الضغط باللمس" للزر 5 ("الصفحة التالية").


الصفحة الثالثة - رسم بياني للتغيرات في درجة الحرارة والرطوبة (فهرس "page2" - 2).


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

1. عنصر الموجي.

معلمات العنصر.


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

2 و 3 هي ببساطة حقول نصية تظهر محور الرسوم البيانية.

4 - زر العودة. وهو مشابه للزر نفسه على الشاشة السابقة ، باستثناء الرمز الموجود في معالج الأحداث.

الرمز الموجود في "Touch Press Event" للزر 4 ("الصفحة السابقة").


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

المجلس 1. قراءة البيانات من جهاز الاستشعار.


للحصول على قيم درجة الحرارة والرطوبة باستخدام مستشعر DHT-22 ، يتم استخدام كتلة B1 - "DHT11 ، DHT21 ، DHT22" (مكتبة العناصر ، مجلد "المستشعرات").

حظر الإعدادات (يسمى بالنقر المزدوج عليه).


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

نظرًا لأن وحدات تحكم Arduino لا تعمل جيدًا مع أرقام الفاصلة العائمة ، والعمل معها يستهلك الكثير من الذاكرة ، أقوم بترجمة جميع القيم على الفور إلى تنسيق Integer. للقيام بذلك ، استخدم الكتل B3 و B4 - "تحويل Float إلى عدد صحيح" (مكتبة العناصر ، المجلد "تحويل النوع") ، والتي تقطع الجزء الكسري من الرقم. لكي لا تفقد أعشار الدرجة ، يتم ضرب قيمة درجة الحرارة التي تم الحصول عليها من المستشعر أولاً في 10 باستخدام الكتلة B2 - "MUL (*)" (مكتبة العناصر ، مجلد "الرياضيات").
ثم يتم إدخال القيم التي تم الحصول عليها في تنسيق عدد صحيح في المتغيرات المقابلة.

المجلس 2. يعرض قيمة درجة الحرارة على اللوحة.


في هذا المشروع ، أستخدم اتصالات مسماة. يمكنك معرفة المزيد عنها في الدرس المقابل .
من أجل الحد من الحمل على وحدة التحكم ، من المنطقي إرسال البيانات إلى اللوحة فقط عندما تتغير البيانات. لذلك ، نحدد أولاً أن البيانات قد تغيرت. للقيام بذلك ، استخدم الكتلة B5 - "كاشف تغيير الرقم" (مكتبة العناصر ، المجلد - "كتل الأساس"). تتحكم هذه الوحدة في رقم "القيمة" في مدخلاتها ، وعند تغييرها ، فإنها تولد نبضة إخراج لدورة واحدة من تنفيذ البرنامج عند الإخراج.
بعد ذلك ، نقوم بإعداد سلسلة لإرسالها إلى حقل نص اللوحة. أولاً ، نقسم قيمة درجة الحرارة ، مضروبة في 10 ، على ثابت من النوع Float بقيمة 10. وبالتالي نحصل على قيمة درجة الحرارة بجزء كسري. نقوم بذلك باستخدام الكتلة B6 - "DIV (/)" (مكتبة العناصر ، مجلد "الرياضيات"). ثم نقوم بتحويل القيمة التي تم الحصول عليها في تنسيق Float إلى سلسلة باستخدام الكتلة B7 - "تحويل السلسلة" (مكتبة العناصر ، المجلد "نوع التحويل"). ثم نقوم بربط السلسلة الناتجة بسلسلة ثابتة "C" باستخدام الكتلة B8 - "إضافة خطوط" (مكتبة العناصر ، المجلد "خطوط"). يتم تغذية الخط الناتج بإدخال الوحدة لكتابة قيمة السمة إلى لوحة Nextion HMI B9 - "Set Parameter" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> "Elements" folder).
يكتب هذا الكتلة القيمة للسمة المحددة.

معلمة كتلة.

بالنقر المزدوج على الكتلة ، تفتح نافذة محرر الكتلة.


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


في مربع الحوار هذا ، حدد منفذ توصيل اللوحة (في درسنا - SoftwareSerial). إذا قمت بتحديد SoftwareSerial ، يجب عليك أيضًا تحديد الدبابيس المعينة كإشارات RX و TX لمنفذ UART (في حالتنا ، 2 و 3). من الضروري أيضًا تعيين اسم لوحة. يجب أن تكون فريدة. يمكن توصيل عدة لوحات في مشروع ما دام هناك ما يكفي من منافذ UART المجانية. يجب أن يكون اسم كل لوحة فريدًا داخل المشروع. في نفس مربع الحوار ، يمكنك إضافة الصفحات المضمنة في اللوحة. ماذا سنفعل. انقر فوق زر إضافة صفحة. تفتح نافذة إنشاء الصفحة.


في هذه النافذة نحتاج إلى إدخال اسم الصفحة ومعرفها. يمكن تعلم هذه المعلومات من المشروع في محرر Nextin.


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


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


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


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






ننتهي من إنشاء اللوحة باستخدام زر "إنهاء" المألوف.
في محرر الكتلة ، حدد عنصر الصفحة "page0" "نص" باسم "tnt" وسمة "Text (txt)". كقيمة ، حدد الإدخال.


تم تكوين الكتلة.
نحن نعتبر المخطط أكثر.
تجريبيا ، تم تحديد بالتأكيد أن قيمة -40 درجة لمقياس حرارة مسحوب تتوافق مع قيمة 10 في عنصر "شريط التقدم" الموجود عليه ، وقيمة 50 درجة لمقياس حرارة تتوافق مع قيمة تقدم 91 بار. وفقًا لذلك ، نقوم بقياس القيمة باستخدام متغير "درجة الحرارة × 10" باستخدام B10 - كتلة "مقياس" (مكتبة العنصر ، مجلد "القياس") دون أن ننسى أن قيمة درجة الحرارة مضروبة في 10. معلمات هذه الكتلة.


يتم إرسال قيمة درجة الحرارة المقاسة إلى اللوحة باستخدام الكتلة B11 - "Set Parameter" (مكتبة العناصر -> المجلد "Panel Nextion HMI" -> folder "Elements"). إعدادات هذه الكتلة.


تحدد الكتلة التالية B12 - "المقارنة" (مكتبة العناصر ، المجلد "مقارنة") ما إذا كانت درجة الحرارة الحالية تتجاوز النقطة المحددة بالقيمة الافتراضية للمتغير "Setpoint - Hot". إنها 290 (لا تنس أنه في كل مكان لدينا درجات حرارة مضروبة في 10).


تم تكوين الكتلة B12 لإخراج وحدة منطقية عند إخراجها عندما تتجاوز القيمة عند الإدخال "I1" القيمة عند الإدخال "I2".


تشكل الكتل B13 و B14 و B15 دوائر الكشف عن تغيير الإشارة المنفصلة. الكتل B13 و B14 - Rtrig (مكتبة العناصر ، مجلد "المشغلات") ، عندما تظهر حافة متقدمة لإشارة منفصلة ، تعطي نبض إخراج لمدة دورة واحدة من البرنامج. تكتشف الكتلة B14 ، بسبب الانعكاس عند دخلها ، الحافة الخلفية للإشارة "تجاوز العتبة". Block B15 –OR (مكتبة العناصر ، المجلد "العناصر الأساسية") ، إذا كانت هناك وحدة منطقية في أي من المدخلات ، فإنها تخرج وحدة منطقية إلى مخرجاتها. وبالتالي ، يتم تشكيل إشارة "إرسال البيانات عند تجاوز العتبة". في الحافة الأمامية لهذه الإشارة ، يتم إرسال أمر لتغيير لون خط حقل النص الذي يعرض درجة الحرارة الحالية. يتم الإرسال باستخدام الكتلة B17– "Set Parameter" (مكتبة العناصر -> المجلد "Nextion HMI Panel" ->مجلد العناصر). إعدادات هذه الكتلة.


يتم تحديد القيمة المرسلة في الأمر باستخدام الكتلة B16 - "Switch" (مكتبة العناصر ، المجلد "Switch"). تقوم هذه الكتلة ذات المستوى المنطقي المنخفض عند إدخالها بنقل القيمة من الإدخال "0" إلى الإخراج ، ومع ارتفاع ، من الإدخال "1". يتم تعيين قيم الألوان المزودة لمدخلات المحول باستخدام الكتل B44 و B45 - "Color ثابت Hight Color" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> folder "Color"). يتم تحديد اللون في محرر الكتلة (انقر مرتين على الكتلة).


لتحديد اللون ، انقر فوق الزر "تغيير". يفتح منتقي الألوان.


في ذلك ، بتعيين قيمة المكونات R (أحمر) ، G (أخضر) و B (أزرق) ، يتم تحديد اللون الضروري.
أيضا ، على الحافة الأمامية للإشارة "إرسال البيانات عند تجاوز العتبة" ، يتم إرسال أمر لتغيير ربط الصورة المقطوعة. يحدث هذا باستخدام الكتلة B19 - "Set Parameter" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Elements").
إعدادات هذه الكتلة.


يتم تحديد فهرس الصور باستخدام الكتلة B18 - "Switch" (مكتبة العناصر ، المجلد "Switch"). تم وصف عمله أعلاه. يمكن عرض قيمة الفهرس للصورة المطلوبة في مشروع محرر Nextion في مكتبة الصور.

مع الانتهاء من نقل بيانات درجة الحرارة. دعنا ننتقل إلى الرطوبة.

المجلس 3. اختتام الرطوبة.


كما هو الحال في درجة الحرارة ، ننشئ أولاً إشارة "إرسال البيانات عند تغير الرطوبة". نقوم بذلك باستخدام الكتلة B20 - "كاشف تغيير الرقم" (مكتبة العناصر ، المجلد - "كتل الأساس"). تم وصف تشغيل هذه الوحدة سابقًا. ترسل هذه الإشارة القيمة إلى حقل رقمي يعرض الرطوبة. يتم ذلك باستخدام الكتلة B21– "Set Parameter" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Elements").
إعدادات هذه الكتلة.


من الناحية التجريبية ، تم تحديده بالتأكيد أنه بالنسبة لقيمة الرطوبة 0٪ لمقياس الرطوبة المرسومة في تصميم اللوحة ، فإن عنصر "Gayge" الذي يرسم السهم هو 314 وللرطوبة بنسبة 100٪ هو 226. تتراوح من -46 (0٪) إلى 226 (100٪). وفقًا لهذه البيانات ، نقوم بتكوين الكتلة B22 - "Scale".
معلمات الكتلة.


نظرًا لأن قيم عنصر "المقياس" لا يمكن أن تكون سالبة ، لحساب زاوية السهم عند هذه القيم ، في حالة القيمة السالبة ، تتم إضافة القيمة 360 إليها. نقوم بذلك باستخدام كتلة B23- "SUMM (+)" (مكتبة العناصر ، مجلد الرياضيات). نحدد أن الرقم أقل من 0 باستخدام الكتلة B26 - "المقارنة" (مكتبة العناصر ، المجلد "مقارنة"). يتحكم ناتجه في المفتاح B24 - "Switch" (مكتبة العناصر ، المجلد "Switch") ويتم إرسال القيمة المحددة إلى اللوحة باستخدام الكتلة B25 - "Set Parameter" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Elements" )
إعدادات هذه الكتلة.


تعرض اللوحة التالية رسمًا بيانيًا للتغيرات في درجة الحرارة والرطوبة.


كما كتبت في بداية الدرس ، لا يعرف عنصر Waveform كيف يكون عنصرًا عامًا ويتم إعادة رسمه في كل مرة تفتح فيها الصفحة التي يوجد فيها. علينا التحايل على هذا القيد. أولاً ، حدد رقم الصفحة التي يتم تحميلها حاليًا على اللوحة. للقيام بذلك ، استخدم الكتلة B27 - "الحصول على معرف الصفحة الحالية" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Page"). في إعدادات هذه الكتلة ، ما عليك سوى تحديد اللوحة التي سنصل إليها مع هذا الطلب.


تتم مقارنة رقم الصفحة الذي تم الحصول عليه من هذه الكتلة مع فهرس الصفحة التي نحتاجها (2) باستخدام الكتلة B28 - "المقارن" (مكتبة العناصر ، المجلد "مقارنة"). إذا كانت الصفحة المطلوبة مفتوحة ، يتم كتابة الوحدة المنطقية في المتغير "فتح صفحة المخطط" ، إذا لم تكن كذلك ، عندها صفر منطقي.
باستخدام الكتلة B29 - "Generator" (مكتبة العناصر ، مجلد "Timers") ، يتم إنشاء إشارة لتسجيل النقطة التالية على الرسم البياني. تولد هذه الكتلة نبضات بمدة نبضة معينة وتوقف مؤقت.
حظر الإعدادات.


نوع المولد المختار هو "جهاز متعدد متماثل متناظر" ، مما يعني أن مدة النبضة تساوي مدة التوقف. عند ضبط مدة النبض على 5 ثوانٍ ، على التوالي ، سيكون الإيقاف المؤقت هو نفسه 5 ثوانٍ. ستأتي الحافة الأمامية للنبض كل 10 ثوانٍ. يتم تمييز هذه الواجهة من خلال الكتلة B30 - "Rtrig" (مكتبة العناصر ، المجلد "Triggers") ، ويتم كتابتها في المتغير "Command لتسجيل النقطة التالية".
على الحافة الأمامية لإشارة "فتح صفحة الرسم البياني" ، والتي سيتم تحديدها باستخدام الكتلة B31 - "Rtrig" (مكتبة العناصر ، مجلد "المشغلات") ، سيتم إنشاء إشارة "إرسال سجل الرسم البياني". بهذه الإشارة ، سيتم إرسال محتويات المصفوفات إلى اللوحة على الرسم البياني ، حيث يتم تخزين قيم النقاط التي تعرض الرسم البياني للتغيير. بالنسبة لدرجة الحرارة ، سيتم ذلك باستخدام الكتلة B32 - "إرسال المصفوفة إلى الرسم البياني" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Graph"). تم تكوين الكتلة باستخدام محرر الكتلة.


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


في هذا المحيط ، يجب عليك إدخال اسم الصفيف ، اكتب (استخدم Byte ، حيث يأخذ عنصر Waveform قيمة قصوى تبلغ 255). يتم أخذ الحجم يساوي عرض الرسم البياني (330).
بعد الإنشاء ، حدد اللوحة والصفحة والعنصر والقناة التي سيتم رسم الرسم البياني عليها.


بنفس الطريقة ، نقوم بتكوين الكتلة لإرسال مصفوفة مع بيانات الرطوبة إلى لوحة B33 - "إرسال المصفوفة إلى الرسم البياني" (مكتبة العناصر -> مجلد "Nextion HMI Panel" -> مجلد "الرسم البياني"). في إعداداته ، نقوم بإنشاء صفيف آخر لتخزين هذه البيانات.


الآن تحتاج إلى إعداد البيانات للرسم البياني لدرجات الحرارة. سيكون لهذا المخطط خط على طول محوره بارتفاع 160 نقطة من أسفل المخطط. من أجل جعل التغيرات في درجة الحرارة أكثر وضوحًا ، نقسم قيمة متغير "درجة الحرارة × 10" على 5 (أي كما لو كان ضرب قيمة درجة الحرارة الحقيقية في 2) باستخدام الكتلة B35 وإضافة الإزاحة إليها باستخدام الكتلة B36. سيتم إدخال النتيجة في متغير "درجة الحرارة مع تحول للرسم البياني".
باستخدام الكتلة B37 - "Stack" (مكتبة العناصر ، "صفائف" المجلد) ، يتم كتابة النبض من المتغير "Command لتسجيل النقطة التالية" إلى الصفيف بواسطة درجة الحرارة مع إزاحة الرسم البياني باستخدام مبدأ المكدس (يتم حذف العنصر الأول من الصفيف ، يتم تحويل الباقي بواحد ، ويتم كتابة القيمة الأخيرة). تم تعيين معلمة الكتلة باستخدام محرر الكتلة.


في المحرر ، حدد الصفيف المطلوب بالنقر فوق الزر "تحديد".
بنفس الطريقة ، نقوم بتكوين كتلة B34 - "Stack" (مكتبة العناصر ، "صفائف" المجلد) لكتابة قيم الرطوبة في الصفيف عن طريق التحديد في الصفيف المقابل.
إذا كانت صفحة الرسم البياني مفتوحة ، يكتمل نقل المصفوفات إلى الرسم البياني ، ويتم تلقي أمر تسجيل النقطة التالية ، ثم يتم إرسال قيم النقاط الجديدة إلى الرسوم البيانية المقابلة. يعد ذلك ضروريًا لمواصلة إنشاء الرسومات أثناء عرض الصفحة. تتم مراقبة الامتثال لهذه الشروط باستخدام الكتلة B38 - "AND" (مكتبة العناصر ، المجلد "العناصر الأساسية"). تصدر هذه الكتلة وحدة عند إخراجها إذا كانت هناك وحدة منطقية في جميع مدخلاتها. يتم إرسال قيمة درجة الحرارة التالية مع التحول إلى الرسم البياني باستخدام الكتلة B40 - "إضافة نقطة إلى الرسم البياني" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> مجلد "الرسم البياني").
حظر الإعدادات.


تم إعداد كتلة إرسال قيمة الرطوبة التالية إلى مخطط B39 أيضًا - "إضافة نقطة إلى المخطط" (مكتبة العناصر -> المجلد "Nextion HMI Panel" -> المجلد "Chart").


انتهى مع اختتام الجدول الزمني.

لوحة 5. ضبط سطوع الإضاءة الخلفية.


تتم قراءة قيمة مجموعة الإضاءة الخلفية باستخدام المقاوم المتغير باستخدام كتلة الإدخال التناظرية "السطوع". نظرًا لأن قيمة سطوع إضاءة اللوحة محددة في النطاق من 0 إلى 100 ، فإننا نقيس قيمة القراءة من النطاق 0-1023 إلى النطاق 0-100 باستخدام كتلة B41 - "مقياس".
حظر الإعدادات.


ثم نحدد حقيقة حدوث تغيير في هذه القيمة باستخدام الكتلة B42 - "كاشف لتغيير الرقم". تحتوي هذه الكتلة على إعدادات غير قياسية صغيرة.


لكي لا يتم تغيير السطوع لكل حركة للمقاوم المتغيرة ، يتم تعيين النطاق النهائي في الوحدة بقيمة 5. أي ، ستعمل الوحدة عندما تتغير قيمة الإدخال بأكثر من 5 في أي من الاتجاهين. عندما يتم تشغيل الوحدة ، سيتم إرسال أمر إلى اللوحة لتعيين سطوع إضاءة خلفية جديد باستخدام الكتلة B43 - "تعيين مستوى الإضاءة الخلفية" (مكتبة العناصر -> مجلد "Nextion HMI Panel" -> مجلد "النظام").
إعدادات الحظر


اكتمل العمل على برنامج وحدة التحكم.

بالنسبة لأولئك الذين يرغبون في التعليمات البرمجية للرسم التخطيطي الناتج.
#include <SoftwareSerial.h>
#include "DHT.h"
DHT _dht1(4, DHT22);

SoftwareSerial Serial100(2, 3);

byte _FLPArray142003126[330] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
byte _FLPArray239384258[330] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int _SUETFLPATemp = 0;
byte _nextionSaveDataVAL_P0_E2;
long _nextionSaveDataPCO_P0_E3;
String _nextionSaveDataTXT_P0_E3;
byte _nextionSaveDataPICC_P0_E4;
int _nextionSaveDataVAL_P1_E2;
long _nextionSaveDataVAL_P1_E4;
String _nextionCommandTempString;
struct _nextionLissenStruct {
  char code;
  String result;
  long number;
};
_nextionLissenStruct _nextionTempLissen;
int nextionGetPageIdTempVar = 0;
int NextionPanel_47525121_PageIdOut = 0;
int _hasNumberChangeInTemp = 0;
int _gtv1;
int _gtv2;
int _gtv3 = 290;
bool _gtv4 = 0;
bool _gtv5 = 0;
int _gtv6;
unsigned long _dht1Tti = 0UL;
float _dht1t = 0.00;
float _dht1h = 0.00;
bool _changeNumber1_Out = 0;
int _changeNumber1_OLV;
bool _nextionSetAttr1_isNU = 0;
bool _nextionSetAttr1_oldState = 0;
bool _nextionSetAttr2_isNU = 0;
bool _nextionSetAttr2_oldState = 0;
bool _trgrt1 = 0;
bool _trgrt1I = 0;
bool _trgrt2 = 0;
bool _trgrt2I = 0;
bool _nextionSetAttr3_isNU = 0;
bool _nextionSetAttr3_oldState = 0;
long _swi1;
bool _nextionSetAttr4_isNU = 0;
bool _nextionSetAttr4_oldState = 0;
byte _swi2;
bool _nextionSetAttr5_isNU = 0;
bool _nextionSetAttr5_oldState = 0;
bool _changeNumber2_Out = 0;
int _changeNumber2_OLV;
int _swi3;
bool _nextionSetAttr6_isNU = 0;
bool _nextionSetAttr6_oldState = 0;
bool _trgrt3 = 0;
bool _trgrt3I = 0;
bool _gen1I = 0;
bool _gen1O = 0;
unsigned long _gen1P = 0UL;
bool _trgrt5 = 0;
bool _trgrt5I = 0;
bool _nextionAddPointToWave1_OldState = 0;
bool _nextionAddPointToWave2_OldState = 0;
bool _SFLPAS1;
bool _SFLPAS2;
bool _nextionSendArraytToWave1_OldState = 0;
bool _nextionSendArraytToWave2_OldState = 0;
bool _nextionSetLighting1_OldStae = 0;
bool _changeNumber3_Out = 0;
int _changeNumber3_OLV;
void setup()
{
  Serial100.begin(9600);
  _dht1.begin();
  nextionSendCommand("", 100);
  nextionAck(100);
  nextionSendCommand("page 0", 100);
  delay(100);
  nextionAck(100);
}
void loop()
{ nextionGetPageIdTempVar = nextionAskPageNamper(100);
  if ( ! (nextionGetPageIdTempVar < 0) ) {
    NextionPanel_47525121_PageIdOut = nextionGetPageIdTempVar;
  };
  if (_isTimer(_dht1Tti, 5000)) {
    _dht1Tti = millis();
    float tempDht4;
    tempDht4 = _dht1.readTemperature();
    if (!(isnan(tempDht4))) {
      _dht1t = tempDht4;
    }
    tempDht4 = _dht1.readHumidity();
    if (!(isnan(tempDht4))) {
      _dht1h = tempDht4;
    }
  }



  _gtv1 = (int((_dht1t) * (10)));
  _gtv2 = (int(_dht1h));
  if ((_gtv1) > (_gtv3)) {
    if (_trgrt1I) {
      _trgrt1 = 0;
    } else {
      _trgrt1 = 1;
      _trgrt1I = 1;
    }
  } else {
    _trgrt1 = 0;
    _trgrt1I = 0;
  };
  if ((_gtv1) > (_gtv3))
  {
    _swi1 = 63488;
  }
  else
  {
    _swi1 = 2016;
  }
  if (!((_gtv1) > (_gtv3))) {
    if (_trgrt2I) {
      _trgrt2 = 0;
    } else {
      _trgrt2 = 1;
      _trgrt2I = 1;
    }
  } else {
    _trgrt2 = 0;
    _trgrt2I = 0;
  };
  if ((_gtv1) > (_gtv3))
  {
    _swi2 = 2;
  }
  else
  {
    _swi2 = 0;
  }
  if (_changeNumber1_Out) {
    _changeNumber1_Out = 0;
  } else {
    _hasNumberChangeInTemp = _gtv1;
    if (_hasNumberChangeInTemp != _changeNumber1_OLV) {
      _changeNumber1_OLV = _hasNumberChangeInTemp;
      _changeNumber1_Out = 1;
    }
  }
  if (_changeNumber1_Out) {
    if (! _nextionSetAttr1_oldState ) {
      _nextionSetAttr1_oldState = 1;
      _nextionSetAttr1_isNU = 1;
      _nextionSaveDataTXT_P0_E3 =  ((( _floatToStringWitRaz((_gtv1) / (10.00), 1))) + (String(" C"))) ;
    }
  } else {
    _nextionSetAttr1_oldState = 0;
  } if (_nextionSetAttr1_isNU) {
    _nextionCommandTempString = String("page0.tnt.txt=\"") + _nextionSaveDataTXT_P0_E3 + String("\"");
    nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
    _nextionSetAttr1_isNU = 0;
  } if (_changeNumber1_Out) {
    if (! _nextionSetAttr2_oldState ) {
      _nextionSetAttr2_oldState = 1;
      _nextionSetAttr2_isNU = 1;
      _nextionSaveDataVAL_P0_E2 =  (map((_gtv1), (-400), (500), (10), (91))) ;
    }
  } else {
    _nextionSetAttr2_oldState = 0;
  } if (_nextionSetAttr2_isNU) {
    _nextionCommandTempString = String("page0.tpb.val=") + String(_nextionSaveDataVAL_P0_E2);
    nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
    _nextionSetAttr2_isNU = 0;
  } if (( (_trgrt1) || (_trgrt2) )) {
    if (! _nextionSetAttr3_oldState ) {
      _nextionSetAttr3_oldState = 1;
      _nextionSetAttr3_isNU = 1;
      _nextionSaveDataPCO_P0_E3 =  _swi1 ;
    }
  } else {
    _nextionSetAttr3_oldState = 0;
  }
  if (nextionAskPageNamper(100) == 0) {
    if (_nextionSetAttr3_isNU) {
      _nextionCommandTempString = String("page0.tnt.pco=") + String(_nextionSaveDataPCO_P0_E3);
      nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
      _nextionCommandTempString = "ref tnt";
      nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
      _nextionSetAttr3_isNU = 0;
    }
  } else {
    _nextionSetAttr3_isNU = 1;
  }
  if (( (_trgrt1) || (_trgrt2) )) {
    if (! _nextionSetAttr4_oldState ) {
      _nextionSetAttr4_oldState = 1;
      _nextionSetAttr4_isNU = 1;
      _nextionSaveDataPICC_P0_E4 =  _swi2 ;
    }
  } else {
    _nextionSetAttr4_oldState = 0;
  }
  if (nextionAskPageNamper(100) == 0) {
    if (_nextionSetAttr4_isNU) {
      _nextionCommandTempString = String("page0.tci.picc=") + String(_nextionSaveDataPICC_P0_E4);
      nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
      _nextionCommandTempString = "ref tci";
      nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
      _nextionSetAttr4_isNU = 0;
    }
  } else {
    _nextionSetAttr4_isNU = 1;
  }
  if (((map((_gtv2), (0), (100), (-46), (226)))) < (0))
  {
    _swi3 = ((map((_gtv2), (0), (100), (-46), (226)))) + (360);
  }
  else
  {
    _swi3 = (map((_gtv2), (0), (100), (-46), (226)));
  }
  if (_changeNumber2_Out) {
    _changeNumber2_Out = 0;
  } else {
    _hasNumberChangeInTemp = _gtv2;
    if (_hasNumberChangeInTemp != _changeNumber2_OLV) {
      _changeNumber2_OLV = _hasNumberChangeInTemp;
      _changeNumber2_Out = 1;
    }
  }
  if (_changeNumber2_Out) {
    if (! _nextionSetAttr5_oldState ) {
      _nextionSetAttr5_oldState = 1;
      _nextionSetAttr5_isNU = 1;
      _nextionSaveDataVAL_P1_E4 =  _gtv2 ;
    }
  } else {
    _nextionSetAttr5_oldState = 0;
  } if (_nextionSetAttr5_isNU) {
    _nextionCommandTempString = String("page1.humN.val=") + String(_nextionSaveDataVAL_P1_E4);
    nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
    _nextionSetAttr5_isNU = 0;
  } if (_changeNumber2_Out) {
    if (! _nextionSetAttr6_oldState ) {
      _nextionSetAttr6_oldState = 1;
      _nextionSetAttr6_isNU = 1;
      _nextionSaveDataVAL_P1_E2 =  _swi3 ;
    }
  } else {
    _nextionSetAttr6_oldState = 0;
  } if (_nextionSetAttr6_isNU) {
    _nextionCommandTempString = String("page1.humG.val=") + String(_nextionSaveDataVAL_P1_E2);
    nextionSendCommand(_nextionCommandTempString.c_str(), 100);  nextionAck(100);
    _nextionSetAttr6_isNU = 0;
  } if (1) {
    if (! _gen1I) {
      _gen1I = 1;
      _gen1O = 1;
      _gen1P = millis();
    }
  } else {
    _gen1I = 0 ;
    _gen1O = 0;
  }
  if (_gen1I) {
    if ( _isTimer ( _gen1P , 5000 )) {
      _gen1P = millis();
      _gen1O = ! _gen1O;
    }
  }
  if (_gen1O) {
    if (_trgrt5I) {
      _trgrt5 = 0;
    } else {
      _trgrt5 = 1;
      _trgrt5I = 1;
    }
  } else {
    _trgrt5 = 0;
    _trgrt5I = 0;
  };
  if (_gtv4) {
    if (_trgrt3I) {
      _trgrt3 = 0;
    } else {
      _trgrt3 = 1;
      _trgrt3I = 1;
    }
  } else {
    _trgrt3 = 0;
    _trgrt3I = 0;
  };
  _gtv4 = (NextionPanel_47525121_PageIdOut) == (2);
  _gtv5 = _trgrt5;
  if (_trgrt3) {
    if ( ! _nextionAddPointToWave1_OldState) {
      _nextionAddPointToWave1_OldState = 1;
      if (nextionAskPageNamper(100) == 2) {
        for (int nextionSATWTemp = 0;  nextionSATWTemp < 330;  nextionSATWTemp ++) {
          _nextionCommandTempString = String ("add 1,1,") + String (_FLPArray142003126[nextionSATWTemp]);
          nextionSendCommand(_nextionCommandTempString.c_str(), 100);
        } delay (50);
      }
    }
  } else {
    _nextionAddPointToWave1_OldState = 0;
  }

  if (_trgrt3) {
    if ( ! _nextionAddPointToWave2_OldState) {
      _nextionAddPointToWave2_OldState = 1;
      if (nextionAskPageNamper(100) == 2) {
        for (int nextionSATWTemp = 0;  nextionSATWTemp < 330;  nextionSATWTemp ++) {
          _nextionCommandTempString = String ("add 1,0,") + String (_FLPArray239384258[nextionSATWTemp]);
          nextionSendCommand(_nextionCommandTempString.c_str(), 100);
        } delay (50);
      }
    }
  } else {
    _nextionAddPointToWave2_OldState = 0;
  }

  if (_gtv5) {
    if (!_SFLPAS1) {
      _SFLPAS1 =  1;
      for (_SUETFLPATemp = 0; _SUETFLPATemp < 329; _SUETFLPATemp = _SUETFLPATemp + 1 ) {
        _FLPArray239384258[_SUETFLPATemp ] = _FLPArray239384258[_SUETFLPATemp + 1];
      }  _FLPArray239384258[329] = _gtv2;
    }
  }  else {
    _SFLPAS1 = 0;
  }
  _gtv6 = ((_gtv1) / (5)) + (160);
  if (_gtv5) {
    if (!_SFLPAS2) {
      _SFLPAS2 =  1;
      for (_SUETFLPATemp = 0; _SUETFLPATemp < 329; _SUETFLPATemp = _SUETFLPATemp + 1 ) {
        _FLPArray142003126[_SUETFLPATemp ] = _FLPArray142003126[_SUETFLPATemp + 1];
      }  _FLPArray142003126[329] = _gtv6;
    }
  }  else {
    _SFLPAS2 = 0;
  }
  if (( (_gtv5) && (!(_trgrt3)) && (_gtv4) )) {
    if ( ! _nextionSendArraytToWave1_OldState) {
      _nextionSendArraytToWave1_OldState = 1;
      if (nextionAskPageNamper(100) == 2) {
        _nextionCommandTempString = String ("add 1,0,") + String (_gtv2);
        nextionSendCommand(_nextionCommandTempString.c_str(), 100); delay (50);
      }
    }
  } else {
    _nextionSendArraytToWave1_OldState = 0;
  }

  if (( (_gtv5) && (!(_trgrt3)) && (_gtv4) )) {
    if ( ! _nextionSendArraytToWave2_OldState) {
      _nextionSendArraytToWave2_OldState = 1;
      if (nextionAskPageNamper(100) == 2) {
        _nextionCommandTempString = String ("add 1,1,") + String (_gtv6);
        nextionSendCommand(_nextionCommandTempString.c_str(), 100); delay (50);
      }
    }
  } else {
    _nextionSendArraytToWave2_OldState = 0;
  }

  if (_changeNumber3_Out) {
    _changeNumber3_Out = 0;
  } else {
    _hasNumberChangeInTemp = (map(( (analogRead (0))), (0), (1023), (0), (100)));
    if (((_hasNumberChangeInTemp > _changeNumber3_OLV) && ((_hasNumberChangeInTemp - _changeNumber3_OLV ) > 5)) || ((_hasNumberChangeInTemp < _changeNumber3_OLV) && ((_changeNumber3_OLV - _hasNumberChangeInTemp ) > 5) ))
    {
      _changeNumber3_OLV = _hasNumberChangeInTemp;
      _changeNumber3_Out = 1;
    }
  }
  if (_changeNumber3_Out) {
    if (!(_nextionSetLighting1_OldStae)) {
      _nextionSetLighting1_OldStae = 1;
      _nextionCommandTempString = String("dim=") + String((map(( (analogRead (0))), (0), (1023), (0), (100))));
      nextionSendCommand(_nextionCommandTempString.c_str(), 100);
    }
  } else {
    _nextionSetLighting1_OldStae = 0;
  }




}
bool _isTimer(unsigned long startTime, unsigned long period )
{
  unsigned long currentTime;
  currentTime = millis();
  if (currentTime >= startTime) {
    return (currentTime >= (startTime + period));
  } else {
    return (currentTime >= (4294967295 - startTime + period));
  }
}
String  _floatToStringWitRaz(float value, int raz)
{
  float tv;
  int ti = int(value);
  String ts = String(ti);
  if (raz == 0) {
    return ts;
  }
  ts += ".";
  float tf = abs(value - ti);
  for (int i = 1; i <= raz; i++ )
  {
    tv = tf * 10;
    ti = int(tv);
    ts += String(ti);
    tf = (tv - ti);
  }
  return ts;
}
void nextionSendCommand(const char* cmd, byte port )
{
  while (Serial100.available()) {
    Serial100.read();
  }
  Serial100.print(cmd);
  Serial100.write(0xFF);
  Serial100.write(0xFF);
  Serial100.write(0xFF);
}
boolean nextionAck( byte port )
{
  uint8_t bytes[4] = {0};
  Serial100.setTimeout(20); if (sizeof(bytes) != Serial100.readBytes((char *)bytes, sizeof(bytes))) {
    return 0;
  }

  if ((bytes[1] == 0xFF) && (bytes[2] == 0xFF) && (bytes[3] == 0xFF)) {
    switch (bytes[0]) {
      case 0x00:
        return false; break;
      case 0x01:
        return true; break;
      default:
        return false;
    }
  }
}
struct _nextionLissenStruct nextionListen( byte port )
{
  char _bite;
  char _end = 0xff;
  String cmd;
  _nextionLissenStruct temp;
  int countEnd = 0;
  delay(10);
  while (Serial100.available() > 0) {
    if (Serial100.available() > 0) {
      _bite = Serial100.read();
      cmd += _bite;
      if (_bite == _end) {
        countEnd++;
      }
      if (countEnd == 3) {
        break;
      }
    }
  }
  temp.result = "";
  temp.code = 'z';
  temp.number = 0;
  switch (cmd[0]) {
    case 'e':
      temp.code = 'e';
      countEnd = 0;
      for (uint8_t i = 0; i < cmd.length(); i++) {
        if (cmd[i] == _end) {
          countEnd++;
        }
        temp.result += String(cmd[i], HEX);
        if (countEnd == 3) {
          return temp;
        }
        temp.result += " ";
      }
      break;
    case 'f':
      temp.code = 'f';
      temp.result = String(cmd[1], DEC);
      return temp;
      break;
    case 'g':
      temp.code = 'g';
      temp.result = String(cmd[2], DEC) + "," + String(cmd[4], DEC) + "," + String(cmd[5], DEC);
      return temp;
      break;
    case 'h':
      temp.code = 'h';
      temp.result = String(cmd[2], DEC) + "," + String(cmd[4], DEC) + "," + String(cmd[5], DEC);
      temp.result = "68 " + temp.result;
      return temp;
      break;
    case 'p':
      temp.code = 'p';
      temp.result = cmd.substring(1, cmd.length() - 3);
      return temp;
      break;
    case 'q':
      temp.code = 'q';
      temp.number = (cmd[4] << 24) | (cmd[3] << 16) | (cmd[2] << 8) | (cmd[1]);
      return temp;
      break;
    default:
      return temp;
      break;
  }
  return temp;
}
int nextionAskPageNamper(byte port)
{
  int result;
  _nextionLissenStruct temp;
  nextionSendCommand("sendme", port);
  temp = nextionListen(port);
  if ((temp.code == 'f') && (temp.result != "")) {
    result = temp.result.toInt();
  } else {
    result = -1;
  }
  return result;
}


فيديو قصير مع مظاهرة.


أرشفة مع مشروع اللوحة ومشروع وحدة التحكم.
في الدرس التالي ، سوف نتعلم كيفية التحكم في وحدة تحكم Arduino من اللوحة.

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


All Articles