Le modèle d'interface pour la "maison intelligente" sur Arduino - la deuxième partie

Suite du "Smart Home" basé sur Arduino.

image


Bonjour.

Pour une meilleure compréhension, je recommande la lecture de la première partie .

Cette partie décrit le contrôle en douceur de l'éclairage ( gradateur , ci-après dénommé PWM), ainsi que le stockage des valeurs dans la mémoire EEPROM non volatile.

La sauvegarde des données en mémoire permet de ramener le système à son état précédent après une panne de courant.

Ici, vous pouvez voir et toucher en temps réel.

La vidéo est jointe
ipad.



Les boutons activeront / désactiveront les broches correspondantes, et le déplacement des curseurs augmentera / diminuera le PWM sur D5 et D6.

À l'intérieur des indicateurs se trouvent des boutons semi-circulaires avec lesquels vous pouvez instantanément désactiver et activer PWM. Lorsqu'elle est activée, la valeur PWM qui était lorsqu'elle était désactivée sera renvoyée.

Je vais aller droit au but ...

Arduino


Réinitialisez d'abord l'EEPROM. Remplissez ce croquis:

#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()
{
}


Maintenant le programme principal:
#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   
 }


L'échange de données avec Arduino est décrit ici ou ici .

Comment fonctionnent les

boutons:

image


Un bouton (par exemple D13 ) allumera la LED et enregistrera l'unité dans l'EEPROM. Le drapeau 1 sera envoyé à l'interface Web indiquant que la commande est terminée. Le bouton s'allume.

Lorsque vous appuyez à nouveau, la LED s'éteint et zéro est écrit dans l'EEPROM. Le drapeau 0 sera envoyé à l'interface Web . Le bouton changera de couleur.

Autrement dit, dans l'interface Web, seule la commande garantie sera affichée.

...
         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;
...


Si vous allumez D13 et désactivez l'arduin, la prochaine fois que vous allumez l'arduin, il lira la cellule de mémoire correspondante:

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


Et s'il y en avait un, alors dans le bloc setup () void la LED s'allumera:

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

Une pause avant d'allumer est nécessaire pour que tous les consommateurs ne s'allument PAS en même temps (par exemple, il s'agit d'un chalet d'été et les radiateurs dans différentes pièces sont contrôlés par l'arduino).

Pour désactiver le contrôle «automatique», par exemple pour la broche d2 , vous devez rediriger ceci au début du code:

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


sur ce:

byte d2 = 0;


Dans void setup (), supprimez les lignes:

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


Et dans le bloc commutateur (descript [3]), commentez l'entrée dans l'EEPROM, comme ceci:

...
         //////////////  ///////////////////
         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; 
...


Variateur:

image


La plage de valeurs PWM est de 0 à 255, l'arduino reçoit (du client) des valeurs dans la plage de 0 à 100, qui sont multipliées par 2,55 à l'intérieur du programme et affichées sur le «pied».


         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; 


Si le curseur se déplace, la commande d'augmentation / diminution de PWM de un est envoyée à l'arduino (et ainsi de suite lors du déplacement du curseur). Variable Shim1 ++; augmente, sa valeur est stockée en mémoire et shim1 multiplié par 2,55 est envoyé à la broche.

Après cela, la valeur de shim1 est renvoyée à l'interface Web et affectée à l'indicateur et au curseur.

L'indicateur et le curseur se verront attribuer la valeur garantie par l'arduino.

Si une partie des données est perdue, le curseur se déplacera.

Lorsque vous cliquez sur le bouton à l'intérieur de l'indicateur:

image


La commande de mise à zéro shim1 sera envoyée à arduino

         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; 

En même temps, rien n'est écrit dans la mémoire et appuyer sur le bouton suivant renverra la valeur de la mémoire.
(il est plus pratique d'éteindre la lumière que de déplacer le curseur)

Interface



Téléchargez l' archive et décompressez-la dans le dossier de travail du serveur (par défaut c'est / var / www), par exemple - / var / www / knopki_shimpolz (vous pouvez avoir votre propre dossier).

Dans le navigateur, accédez à votre_ routeur / knopki_shimpolz / . L'image suivante apparaîtra:

image


Fonctionnement

Il est conseillé d'ouvrir le fichier index.html à partir de l'archive et de lire les commentaires.

Dimmer:

Au premier chargement de page, la fonction de mise à jour est activée - show (); (à l'avenir, cela fonctionne avec un intervalle défini) et les valeurs PWM sont demandées aux Arduins avec d'autres données:

/**/
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();

                               ...     


Après avoir reçu la valeur de shim1 , le programme passe à la fonction 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();
}

La valeur shim1 est affichée sur l'indicateur (cercle vert) et le travail est transféré vers la fonction sl1 () ;

Fonction sl1 (); définit le curseur en fonction de la valeur shim1

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

Diapositive de fonction : la fonction (événement, ui) s'attend à ce que le curseur se déplace.

Lorsque le curseur est déplacé dans une direction ou une autre d'une division, l'algorithme suivant fonctionne: La

mise à jour est désactivée ⇨

flagobnov = 0;


Il est vérifié dans quelle direction le curseur est déplacé (vers le haut ou vers le bas))

if( ui.value > shim1 ){

else if( ui.value < shim1 ){


Un symbole est envoyé à Arduine indiquant d'augmenter (diminuer) le PWM d'une unité ⇨

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


Nous obtenons une nouvelle valeur PWM des Arduins et appelons la fonction de rendu d'indicateur (sh1 ();) avec la nouvelle valeur ⇨

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


Activez la mise à jour ⇨

flagobnov = 1; 


La fonction ( sh1 (); ), à son tour, dessine un indicateur et transfère le contrôle à la fonction ( sl1 () ;).

La fonction ( sl1 (); ) définit le curseur en fonction de la nouvelle valeur PWM et attend le prochain mouvement du curseur.

Code dans son ensemble:
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; /*   */
       }
    });
}


La valeur de l'indicateur et la position du curseur sont garanties pour correspondre à la valeur dans l'arduino.

En appuyant sur le bouton "Désactiver instantanément le PWM" envoie la commande pour réinitialiser le PWM à l'arduino, et le bouton "Activer instantanément le PWM" demandera à l'arduino la valeur PWM qui était avant la réinitialisation.

/* 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;
                  
	});


Apparence


La position des indicateurs, leur couleur et leur police changent dans le fichier 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; /*    */
}


La taille et la position des curseurs peuvent être modifiées dans le fichier 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; /*    */
}


C'est tout, dans la prochaine partie, nous envisagerons de connecter des capteurs de température et d'allumer / éteindre divers appareils en fonction de la température, et également d'ajouter le mode veille pour l'interface Web.

Remercier.

All Articles