La plantilla de interfaz para el "hogar inteligente" en Arduino - la segunda parte

Continuación de la "Casa inteligente" basada en Arduino.

imagen


Hola.

Para una mejor comprensión, recomiendo leer la primera parte .

Esta parte describe el control suave de la iluminación ( atenuador , en adelante denominado PWM), así como el almacenamiento de valores en la memoria EEPROM no volátil.

Guardar datos en la memoria permite devolver el sistema a su estado anterior después de un apagón.

Aquí puedes ver y tocar en tiempo real.

Se adjunta el video.
ipad.



Los botones habilitarán / deshabilitarán los pines correspondientes, y al mover los controles deslizantes aumentará / disminuirá el PWM en D5 y D6.

Dentro de los indicadores hay botones semicirculares con los que puede deshabilitar y habilitar PWM instantáneamente. Cuando se enciende, se devolverá el valor PWM que estaba cuando se apagó.

Iré directo al punto ...

Arduino


Primero reinicie la EEPROM. Rellene este boceto:

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


Ahora el programa 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   
 }


El intercambio de datos con arduino se describe aquí o aquí .

Cómo funcionan los

botones:

imagen


Un botón (por ejemplo, D13 ) encenderá el LED y escribirá la unidad en la EEPROM. El indicador 1 se enviará a la interfaz web indicando que el comando se ha completado. El botón se ilumina.

Cuando se presiona nuevamente, el LED se apagará y se escribirá cero en la EEPROM. La bandera 0 se enviará a la interfaz web . El botón cambiará de color.

Es decir, en la interfaz web solo se mostrará el comando garantizado.

...
         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 enciende D13 y desenergiza el arduin, la próxima vez que encienda el arduin, se leerá la celda de memoria correspondiente:

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


Y si hubiera uno, entonces en el bloque vacío de configuración () el LED se encenderá:

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

Es necesario hacer una pausa antes de encender para que todos los consumidores NO enciendan al mismo tiempo (por ejemplo, esta es una casa de verano, y los calentadores en diferentes habitaciones están controlados por el arduino).

Para deshabilitar el control "automático", por ejemplo, para el pin d2 , debe redirigir esto al comienzo del código:

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


en este:

byte d2 = 0;


En la configuración nula (), elimine las líneas:

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


Y en el bloque de interruptores (descriptivo [3]) comente la entrada en la EEPROM, así:

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


Regulador de intensidad:

imagen


El rango de valores PWM es de 0 a 255, el arduino recibe (del cliente) valores en el rango de 0 a 100, que se multiplican por 2.55 dentro del programa y se muestran en el "pie".


         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 el control deslizante se mueve, el comando para aumentar / disminuir PWM en uno se envía al arduino (y así sucesivamente mientras se mueve el control deslizante). Shim1 ++ variable; aumenta, su valor se almacena en la memoria y shim1 multiplicado por 2.55 se alimenta al pin.

Después de eso, el valor de shim1 se devuelve a la interfaz web y se asigna al indicador y al control deslizante.

Al indicador y al control deslizante se le asignará el valor garantizado por el arduino.

Si se pierde parte de los datos, el control deslizante se moverá a un lado.

Cuando haces clic en el botón dentro del indicador:

imagen


El comando de anulación shim1 se enviará a 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; 

Al mismo tiempo, no se escribe nada en la memoria, y presionar el botón siguiente devolverá el valor de la memoria.
(es más conveniente apagar la luz que cambiar el control deslizante)

Interfaz



Descargue el archivo comprimido y descomprímalo en la carpeta de trabajo del servidor (por defecto es / var / www), por ejemplo - / var / www / knopki_shimpolz (puede tener su propia carpeta).

En el navegador, vaya a your_ router / knopki_shimpolz / . Aparecerá la siguiente imagen:

imagen


Cómo funciona

Es recomendable abrir el archivo index.html del archivo y leer los comentarios.

Atenuador:

en la primera carga de la página, la función de actualización se activa - show (); (en el futuro, funciona con un intervalo establecido) y los valores PWM se solicitan a los arduins junto con otros datos:

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

                               ...     


Después de recibir el valor de shim1 , el programa entra en la función 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();
}

El valor shim1 se muestra en el indicador (círculo verde) y el trabajo se transfiere a la función sl1 () ;

Función sl1 (); establece el control deslizante de acuerdo con el valor shim1

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

Función slide: function (event, ui) espera que el control deslizante se mueva.

Cuando el control deslizante se desplaza en una dirección u otra por una división, el siguiente algoritmo funcionará: La

actualización está desactivada ⇨

flagobnov = 0;


Se verifica en qué dirección se mueve el control deslizante (arriba o abajo))

if( ui.value > shim1 ){

else if( ui.value < shim1 ){


Se envía un símbolo a Arduine indicando que aumenta (disminuye) PWM en uno ⇨

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


Obtenemos un nuevo valor PWM de los arduins y llamamos a la función de representación del indicador (sh1 ();) con el nuevo valor ⇨

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


Encienda la actualización ⇨

flagobnov = 1; 


La función ( sh1 (); ), a su vez, dibuja un indicador y transfiere el control a la función ( sl1 () ;).

La función ( sl1 (); ) establece el control deslizante de acuerdo con el nuevo valor PWM y espera el próximo movimiento del control deslizante.

Código en su conjunto:
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; /*   */
       }
    });
}


Se garantiza que el valor del indicador y la posición del control deslizante corresponden al valor en el arduino.

Al presionar el botón "Apagar instantáneamente el PWM" se envía el comando para restablecer el PWM al arduino, y el botón "Encender el PWM al instante" le preguntará al arduino el valor PWM que estaba antes de reiniciar.

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


Apariencia


La posición de los indicadores, su color y fuente cambian en el archivo 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; /*    */
}


El tamaño y la posición de los controles deslizantes se pueden cambiar en el archivo 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; /*    */
}


Eso es todo, en la siguiente parte consideraremos conectar sensores de temperatura y encender / apagar varios dispositivos por temperatura, y también agregaremos el modo de suspensión para la interfaz web.

Gracias.

All Articles