قالب واجهة "المنزل الذكي" على Arduino - الجزء الثاني

استمرار "المنزل الذكي" القائم على اردوينو.

صورة


مرحبا.

لفهم أفضل ، أوصي بقراءة الجزء الأول .

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

حفظ البيانات على الذاكرة يجعل من الممكن إعادة النظام إلى حالته السابقة بعد انقطاع التيار الكهربائي.

هنا يمكنك رؤية ولمس في الوقت الحقيقي.

الفيديو مرفق
ipad.



ستعمل الأزرار على تمكين / تعطيل الدبابيس المقابلة ، وسيؤدي تحريك أشرطة التمرير إلى زيادة / تقليل PWM على D5 و D6.

داخل المؤشرات توجد أزرار نصف دائرية يمكنك من خلالها تعطيل وتمكين PWM. عند تشغيله ، سيتم إرجاع قيمة PWM التي كانت متوقفة عن التشغيل.

سأنتقل مباشرة إلى النقطة ...

اردوينو


أعد ضبط EEPROM أولاً. املأ هذا الرسم:

#include <EEPROM.h>

void setup()
{
  // write a 0 to all 512 bytes of the EEPROM
  for (int i = 0; i < 512; i++)
    EEPROM.write(i, 0);

  // turn the LED on when we're done
  digitalWrite(13, HIGH);
}

void loop()
{
}


الآن البرنامج الرئيسي:
#include <EEPROM.h>

byte d2 = EEPROM.read(2);     //  ( )   EEPROM,  
byte d3 = EEPROM.read(3);
byte d4 = EEPROM.read(4);
int shim1 = EEPROM.read(5); //     EEPROM,  
int shim2 = EEPROM.read(6);
byte d11 = EEPROM.read(11);
byte d12 = EEPROM.read(12);
byte d13 = EEPROM.read(13);

byte descript[5]; // 

void setup() 
{
  Serial.begin(57600);
  pinMode(2, OUTPUT); 
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  
  if(d2) digitalWrite(2, HIGH); else digitalWrite(2, LOW); //    d2  ,  ,  ,   
  delay(500); //     ,  
  if(d3) digitalWrite(3, HIGH); else digitalWrite(3, LOW);
  delay(500);
  if(d4) digitalWrite(4, HIGH); else digitalWrite(4, LOW);
  delay(500);
  analogWrite(5, shim1 * 2.55); //   d5
  delay(500);
  analogWrite(6, shim2 * 2.55); //   d6
  delay(500);
  if(d11) digitalWrite(11, HIGH); else digitalWrite(11, LOW);
  delay(500);
  if(d12) digitalWrite(12, HIGH); else digitalWrite(12, LOW);
  delay(500);
  if(d13) digitalWrite(13, HIGH); else digitalWrite(13, LOW);
}
  
void loop() 
{  
  if (Serial.available()>4) //     
   {
    if (Serial.read()=='Y') //   ,   'Y',   ,  ,     
     {
      for (byte i=0; i < 5; i++)
        {
           descript[i] = Serial.read(); //       
        } 
        
    if((descript[0] =='+') && (descript[1] =='=') && (descript[2] =='Z')) //  
     {
      switch (descript[3])
       {
         case 'o': // 
         glavnaia(); //  
         break;
         
         case 'A': // d2 
         digitalWrite(2, HIGH); //  d2
         d2 = 1; //     ()
         EEPROM.write(2, d2); //   d2   №2 EEPROM 
         glavnaia(); //  
         break;
         
         case 'a': // d2 
         digitalWrite(2, LOW); //  d2
         d2 = 0; //     ()
         EEPROM.write(2, d2); //   d2   №2 EEPROM 
         glavnaia(); //  
         break; 
 
         case 'B': // d3
         digitalWrite(3, HIGH);
         d3 = 1;
         EEPROM.write(3, d3);
         glavnaia();
         break;
         
         case 'b': // d3
         digitalWrite(3, LOW);
         d3 = 0;
         EEPROM.write(3, d3);
         glavnaia();
         break;          
  
         case 'C': // d4
         digitalWrite(4, HIGH);
         d4 = 1;
         EEPROM.write(4, d4);
         glavnaia();
         break;
         
         case 'c': // d4
         digitalWrite(4, LOW);
         d4 = 0;
         EEPROM.write(4, d4);
         glavnaia();
         break;   
  
         case 'D': // d5  shim1
         shim1++; // 
         if(shim1 > 100) shim1 = 100;  //   ,   
         EEPROM.write(5, shim1); //     №5 EEPROM 
         analogWrite(5, shim1 * 2.55); //   D5 
         glavnaia(); //   
         break;
         
         case 'd': // d5  shim1
         shim1--;
         if(shim1 < 1) shim1 = 0;
         EEPROM.write(5, shim1);
         analogWrite(5, shim1 * 2.55);
         glavnaia();
         break; 
  
         case 'E': // d6  shim2
         shim2++;
         if(shim2 > 100) shim2 = 100;
         EEPROM.write(6, shim2);
         analogWrite(6, shim2 * 2.55);
         glavnaia();
         break;
         
         case 'e': // d6  shim2
         shim2--;
         if(shim2 < 1) shim2 = 0;
         EEPROM.write(6, shim2);
         analogWrite(6, shim2 * 2.55);
         glavnaia();
         break;   
  
         case 'F': //     D5
         shim1 = EEPROM.read(5); //     EEPROM
         analogWrite(5, shim1 * 2.55); //   D5
         glavnaia();
         break;
         
         case 'f': //     D5
         shim1 = 0;
         analogWrite(5, shim1); //   D5,     EEPROM
         glavnaia();
         break;  
 
         case 'G': //     D6
         shim2 = EEPROM.read(6); //     EEPROM
         analogWrite(6, shim2 * 2.55); //   D6
         glavnaia();
         break;
         
         case 'g': //     D6
         shim2 = 0;
         analogWrite(6, shim2); //   D6,     EEPROM
         glavnaia();
         break;  
 
         case 'J': // d11
         digitalWrite(11, HIGH);
         d11 = 1;
         EEPROM.write(11, d11);
         glavnaia();
         break;
         
         case 'j': // d11
         digitalWrite(11, LOW);
         d11 = 0;
         EEPROM.write(11, d11);
         glavnaia();
         break;  
        
         case 'K': // d12
         digitalWrite(12, HIGH);
         d12 = 1;
         EEPROM.write(12, d12);
         glavnaia();
         break;
         
         case 'k': // d12
         digitalWrite(12, LOW);
         d12 = 0;
         EEPROM.write(12, d12);
         glavnaia();
         break;         
      
         case 'M': // d13
         digitalWrite(13, HIGH);
         d13 = 1;
         EEPROM.write(13, d13);
         glavnaia();
         break;
         
         case 'm': // d13
         digitalWrite(13, LOW);
         d13 = 0;
         EEPROM.write(13, d13);
         glavnaia();
         break;
 
         default:
         glavnaia();
       }
     }
   
    else //   ,   
      {
        for(byte i=0; i < 255; i++) 
         {
           Serial.read();    
         } 
      } 
     }    //  if (Serial.read()=='Y')
   }    //   
 
} //  loop

void glavnaia() //  
 {
      Serial.print(d2);//0
      Serial.print(",");
      Serial.print(d3);//1
      Serial.print(",");
      Serial.print(d4);//2
      Serial.print(",");
      Serial.print(0);//3  //   ,   
      Serial.print(",");
      Serial.print(0);//4  //   ,   
      Serial.print(",");
      Serial.print(0);//5 //   ,   
      Serial.print(",");
      Serial.print(0);//6 //   ,   
      Serial.print(",");
      Serial.print(0);//7  //   ,   
      Serial.print(",");
      Serial.print(0);//8 //   ,   
      Serial.print(",");
      Serial.print(d11);//9
      Serial.print(",");
      Serial.print(d12);//10
      Serial.print(",");
      Serial.print(d13);//11 
      Serial.print(",");
      Serial.print(shim1); // 12  
      Serial.print(",");
      Serial.println(shim2); // 13  14   
 }


يوصف تبادل البيانات مع اردوينو هنا أو هنا .

كيف تعمل

الأزرار:

صورة


سيعمل زر (على سبيل المثال D13 ) على تشغيل LED وكتابة الوحدة إلى EEPROM. سيتم إرسال العلم 1 إلى واجهة الويب للإشارة إلى اكتمال الأمر. يضيء الزر.

عند الضغط مرة أخرى ، سيتم إيقاف تشغيل LED وسيتم كتابة الصفر إلى EEPROM. سيتم إرسال العلم 0 إلى واجهة الويب . الزر سيتغير لونه.

أي أنه في واجهة الويب سيتم عرض الأمر المضمون فقط.

...
         case 'M': // d13
         digitalWrite(13, HIGH); // 
         d13 = 1; //  
         EEPROM.write(13, d13); //    
         glavnaia(); //   
         break;
         
         case 'm': // d13
         digitalWrite(13, LOW);
         d13 = 0;
         EEPROM.write(13, d13);
         glavnaia();
         break;
...


إذا قمت بتشغيل D13 وإلغاء تنشيط arduin ، فعندما تقوم بتشغيل arduin في المرة التالية ، ستقرأ خلية الذاكرة المقابلة:

...
byte d13 = EEPROM.read(13);
...


وإذا كان هناك واحد ، فعندئذٍ سيتم تشغيل LED في كتلة الفراغ ():

...
  delay(500);
  if(d13) digitalWrite(13, HIGH); else digitalWrite(13, LOW);

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

لتعطيل التحكم "التلقائي" ، على سبيل المثال للطرف d2 ، تحتاج إلى إعادة توجيه هذا في بداية الرمز:

...
byte d2 = EEPROM.read(2);
...


على هذا:

byte d2 = 0;


في إعداد الفراغ () ، قم بإزالة السطور:

...
if(d2) digitalWrite(2, HIGH); else digitalWrite(2, LOW); 
delay(500);
...


وفي كتلة التبديل (الوصف [3]) ، علّق على الإدخال في EEPROM ، كما يلي:

...
         //////////////  ///////////////////
         case 'A': // d2 
         digitalWrite(2, HIGH); //  d2
         d2 = 1; //     ()
         //EEPROM.write(2, d2); //   d2   №2 EEPROM 
         glavnaia(); //  
         break;
         
         case 'a': // d2 
         digitalWrite(2, LOW); //  d2
         d2 = 0; //     ()
         //EEPROM.write(2, d2); //   d2   №2 EEPROM 
         glavnaia(); //  
         break; 
...


باهتة:

صورة


يتراوح نطاق قيم PWM من 0 إلى 255 ، يتلقى arduino (من العميل) قيمًا في النطاق من 0 إلى 100 ، والتي يتم ضربها في 2.55 داخل البرنامج وعرضها على "القدم".


         case 'D': // d5  shim1
         shim1++; //  
         if(shim1 > 100) shim1 = 100; //   ,   
         EEPROM.write(5, shim1); //    
         analogWrite(5, shim1 * 2.55); //  
         glavnaia(); //   
         break;
         
         case 'd': // d5  shim1
         shim1--;
         if(shim1 < 1) shim1 = 0;
         EEPROM.write(5, shim1);
         analogWrite(5, shim1 * 2.55);
         glavnaia();
         break; 


إذا تحرك شريط التمرير ، فسيتم إرسال الأمر لزيادة / تقليل PWM بمقدار واحد إلى arduino (وهكذا أثناء تحريك شريط التمرير). متغير Shim1 ++ ؛ يزيد ، يتم تخزين قيمته في الذاكرة ، ويتم تغذية shim1 مضروبًا في 2.55 إلى الدبوس.

بعد ذلك ، يتم إرسال قيمة shim1 إلى واجهة الويب وتعيينها إلى المؤشر والشريط.

سيتم تعيين المؤشر والشريط المنزلق على القيمة التي يضمنها أردوينو.

في حالة فقدان جزء من البيانات ، سينتقل شريط التمرير جانباً.

عند النقر فوق الزر الموجود داخل المؤشر:

صورة


سيتم إرسال shim1 قيادة nulling ل اردوينو

         case 'F': //     D5
         shim1 = EEPROM.read(5); //     EEPROM
         analogWrite(5, shim1 * 2.55); //   D5
         glavnaia();
         break;
         
         case 'f': //     D5
         shim1 = 0;
         analogWrite(5, shim1); //   D5,     EEPROM
         glavnaia();
         break; 

في الوقت نفسه ، لا تتم كتابة أي شيء إلى الذاكرة ، والضغط على الزر التالي سيعيد القيمة من الذاكرة.
(يعد إيقاف تشغيل الضوء أكثر ملاءمة من تغيير شريط التمرير)

واجهه المستخدم



قم بتنزيل الأرشيف وفك ضغطه إلى مجلد العمل الخاص بالخادم (افتراضيًا هو / var / www) ، على سبيل المثال - / var / www / knopki_shimpolz (قد يكون لديك مجلد خاص بك).

في المتصفح ، انتقل إلى your_ router / knopki_shimpolz / . ستظهر الصورة التالية:

صورة


كيف يعمل من

المستحسن فتح ملف index.html من الأرشيف وقراءة التعليقات.

باهتة:

عند تحميل الصفحة الأولى ، يتم تنشيط وظيفة التحديث - show ()؛ (في المستقبل ، يعمل مع فاصل زمني محدد) ويتم طلب قيم PWM من arduins جنبًا إلى جنب مع البيانات الأخرى:

/**/
show();
setInterval(show,2000);  /*     */
function show(){  /*   */
if(flagobnov == 1) { /*        */
            $.ajax({ 
                type: "GET",
                url: "box2.php?df=o", /*    */
                timeout:200, /*  (),          */          
                cache: false,       
                success: function(data){   
                                          
                           var vars = data.split(","); /*      */
                           if(vars.length == dlina){ /*    (   ) */
                               
                               /*d2*/
                               if(vars[0] == 1) { $(".d2otkl").show(); $(".d2vkl").hide(); }  /*      /     */
                               else if(vars[0] == 0) { $(".d2otkl").hide(); $(".d2vkl").show(); } 

                               /*d3*/
                               if(vars[1] == 1) { $(".d3otkl").show(); $(".d3vkl").hide(); }
                               else if(vars[1] == 0) { $(".d3otkl").hide(); $(".d3vkl").show(); }

                               ...

                               shim1 = vars[12]; /*    */ 
                               sh1(); /*       */ 

                               shim2 = vars[13]; 
                               sh2();

                               ...     


بعد تلقي قيمة shim1 ، ينتقل البرنامج إلى الوظيفة sh1 () ؛

function sh1(){ /*    */
  var $ppc = $('.progress-pie-chart'),
    percent = shim1,
    deg = 360*percent/100;
  if (percent > 50) {
    $ppc.addClass('gt-50');
  }
  else $ppc.removeClass('gt-50');
  $('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)');
  $('.ppc-percents span').html(percent+' %       D5  '); /*    - D5 */
  sl1();
}

يتم عرض القيمة shim1 على المؤشر (الدائرة الخضراء) ويتم نقل العمل إلى الوظيفة sl1 () ؛

الدالة sl1 () ؛ يضبط شريط التمرير وفقًا لقيمة shim1

function sl1(){ /*   */
       $( "#slider" ).slider({
       value : shim1,
       min : 0,
       max : 100,
       step : 1,
       slide: function( event, ui ) {
       
       ...

شريحة الوظيفة: الوظيفة (الحدث ، واجهة المستخدم) تتوقع أن يتحرك شريط التمرير.

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

تم تعطيل التحديث ⇨

flagobnov = 0;


يتم التحقق في أي اتجاه يتم تحريك شريط التمرير (لأعلى أو لأسفل))

if( ui.value > shim1 ){

else if( ui.value < shim1 ){


يتم إرسال رمز إلى Arduine يشير إلى زيادة (نقصان) PWM بمقدار ⇨

$.ajax({  
    type: "GET",  
    url: "box2.php?df=D", /*          */


نحصل على قيمة PWM جديدة من arduins ونستدعي وظيفة عرض المؤشر (sh1 ()؛) مع القيمة الجديدة ⇨

shim1 = vars[12]; /*         */
sh1(); /*       */


قم بتشغيل التحديث ⇨

flagobnov = 1; 


الوظيفة ( sh1 ()؛ ) ، بدورها ، ترسم مؤشرًا وتنقل التحكم إلى الوظيفة ( sl1 () ؛).

تقوم الوظيفة ( sl1 ()؛ ) بتعيين شريط التمرير وفقًا لقيمة PWM الجديدة وتتوقع حركة شريط التمرير التالية.

الرمز ككل:
function sh1(){ /*    */
  var $ppc = $('.progress-pie-chart'),
    percent = shim1,
    deg = 360*percent/100;
  if (percent > 50) {
    $ppc.addClass('gt-50');
  }
  else $ppc.removeClass('gt-50');
  $('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)');
  $('.ppc-percents span').html(percent+' %       D5  '); /*    - D5 */
  sl1();
}

function sl1(){ /*   */
       $( "#slider" ).slider({
       value : shim1,
       min : 0,
       max : 100,
       step : 1,
       slide: function( event, ui ) {  /*     ,   ,           */
       flagobnov = 0; /*     ,    "" */
           if( ui.value > shim1 ){ /*      ,    */
		$.ajax({  
		    type: "GET",  
		    url: "box2.php?df=D", /*          */
                    timeout:200,
                    cache: false,  
                    success: function(data){                       
                         var vars = data.split(",");
                         if(vars.length == dlina) 
                             { 
			       shim1 = vars[12]; /*         */
			       sh1(); /*       */
			     }  
                    }   
 	        });
           }

           else if( ui.value < shim1 ){ /*      ,    */
		$.ajax({  
		    type: "GET",  
		    url: "box2.php?df=d", /*          */
                    timeout:200,
                    cache: false,  
                    success: function(data){                       
                         var vars = data.split(",");
                         if(vars.length == dlina) 
                             { 
			       shim1 = vars[12]; /*         */
			       sh1(); /*       */
			     }  
                    }   
 	        });
           }

        flagobnov = 1; /*   */
       }
    });
}


يتم ضمان قيمة المؤشر وموضع شريط التمرير لتتوافق مع القيمة في اردوينو.

يؤدي الضغط على الزر "إيقاف تشغيل PWM على الفور" إلى إرسال الأمر لإعادة تعيين PWM إلى arduino ، وسيطلب الزر "تشغيل PWM فورًا" من arduino قيمة PWM التي كانت قبل إعادة التعيين.

/* d5  */
/*    D5*/
$(".d5shimvkl").click(function(){
                    $.ajax({  
		             type: "GET",  
		             url: "box2.php?df=F",
                             timeout:200,
                             cache: false,  
                             success: function(data)
                                {                       
                                  var vars = data.split(",");
                                    if(vars.length == dlina) 
                                       { 
                                          shim1 = vars[12]; /*         */
					  sh1(); /*       */
                                       }  
                                }   
 	                   }); 
                     return false;
                  
	});

/*    D5*/
$(".d5shimotkl").click(function(){
                    $.ajax({  
		             type: "GET",  
		             url: "box2.php?df=f",
                             timeout:200,
                             cache: false,  
                             success: function(data)
                                {                       
                                  var vars = data.split(",");
                                    if(vars.length == dlina) 
                                       { 
                                          shim1 = vars[12]; /*         */
					  sh1(); /*       */
                                       }  
                                }   
 	                   }); 
                     return false;
                  
	});


مظهر خارجي


موضع المؤشرات ، تغير لونها وخطها في ملف shim.css

/*   */
.progress-pie-chart {
  width: 200px;
  height: 200px;
  top: 90px; /*  */
  left: 80px; /*  */
  border-radius: 50%;
  background-color: #E5E5E5;
  position: absolute;
}
...
.ppc-percents span {
  display: block;
  font-size: 26px; /*   */
  font-weight: 600; /*   */
  font-family: Arial, Helvetica, sans-serif; /**/
  color: #161616; /*   */
  text-shadow: 0px 1px 2px #7c7c7c; /*    */
}


يمكن تغيير حجم وموضع أشرطة التمرير في ملف slai.css

.ui-slider { 
position: relative; 
width: 200px; /*   */
text-align: left; 
outline: none; 
}
...
/*   */
.ui-slider-horizontal .ui-slider-handle { 
width: 50px; /*  */
height: 50px;
margin-left: -25px; 
outline: none;
box-shadow: 0 0 10px 3px rgba(0,0,0,0.3);
border-radius: 4px;
border: 1px solid #2b2c2b;
cursor: pointer;
}
...
/* */
s1 { 
position: absolute; 
top: 360px; 
left: 80px;
font-size: 26px; /*   */
font-weight: 600; /*   */
font-family: Arial, Helvetica, sans-serif; /**/
color: #161616; /*   */
text-shadow: 0px 1px 2px #7c7c7c; /*    */
}

/* */
s2 { 
position: absolute; 
top: 360px; 
left: 420px;
font-size: 26px; /*   */
font-weight: 600; /*   */
font-family: Arial, Helvetica, sans-serif; /**/
color: #161616; /*   */
text-shadow: 0px 1px 2px #7c7c7c; /*    */
}


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

شكرا.

All Articles