Continuación de la "Casa inteligente" basada en Arduino.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()
{
for (int i = 0; i < 512; i++)
EEPROM.write(i, 0);
digitalWrite(13, HIGH);
}
void loop()
{
}
Ahora el programa principal:#include <EEPROM.h>
byte d2 = EEPROM.read(2);
byte d3 = EEPROM.read(3);
byte d4 = EEPROM.read(4);
int shim1 = EEPROM.read(5);
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);
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);
delay(500);
analogWrite(6, shim2 * 2.55);
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')
{
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':
digitalWrite(2, HIGH);
d2 = 1;
EEPROM.write(2, d2);
glavnaia();
break;
case 'a':
digitalWrite(2, LOW);
d2 = 0;
EEPROM.write(2, d2);
glavnaia();
break;
case 'B':
digitalWrite(3, HIGH);
d3 = 1;
EEPROM.write(3, d3);
glavnaia();
break;
case 'b':
digitalWrite(3, LOW);
d3 = 0;
EEPROM.write(3, d3);
glavnaia();
break;
case 'C':
digitalWrite(4, HIGH);
d4 = 1;
EEPROM.write(4, d4);
glavnaia();
break;
case 'c':
digitalWrite(4, LOW);
d4 = 0;
EEPROM.write(4, d4);
glavnaia();
break;
case 'D':
shim1++;
if(shim1 > 100) shim1 = 100;
EEPROM.write(5, shim1);
analogWrite(5, shim1 * 2.55);
glavnaia();
break;
case 'd':
shim1--;
if(shim1 < 1) shim1 = 0;
EEPROM.write(5, shim1);
analogWrite(5, shim1 * 2.55);
glavnaia();
break;
case 'E':
shim2++;
if(shim2 > 100) shim2 = 100;
EEPROM.write(6, shim2);
analogWrite(6, shim2 * 2.55);
glavnaia();
break;
case 'e':
shim2--;
if(shim2 < 1) shim2 = 0;
EEPROM.write(6, shim2);
analogWrite(6, shim2 * 2.55);
glavnaia();
break;
case 'F':
shim1 = EEPROM.read(5);
analogWrite(5, shim1 * 2.55);
glavnaia();
break;
case 'f':
shim1 = 0;
analogWrite(5, shim1);
glavnaia();
break;
case 'G':
shim2 = EEPROM.read(6);
analogWrite(6, shim2 * 2.55);
glavnaia();
break;
case 'g':
shim2 = 0;
analogWrite(6, shim2);
glavnaia();
break;
case 'J':
digitalWrite(11, HIGH);
d11 = 1;
EEPROM.write(11, d11);
glavnaia();
break;
case 'j':
digitalWrite(11, LOW);
d11 = 0;
EEPROM.write(11, d11);
glavnaia();
break;
case 'K':
digitalWrite(12, HIGH);
d12 = 1;
EEPROM.write(12, d12);
glavnaia();
break;
case 'k':
digitalWrite(12, LOW);
d12 = 0;
EEPROM.write(12, d12);
glavnaia();
break;
case 'M':
digitalWrite(13, HIGH);
d13 = 1;
EEPROM.write(13, d13);
glavnaia();
break;
case 'm':
digitalWrite(13, LOW);
d13 = 0;
EEPROM.write(13, d13);
glavnaia();
break;
default:
glavnaia();
}
}
else
{
for(byte i=0; i < 255; i++)
{
Serial.read();
}
}
}
}
}
void glavnaia()
{
Serial.print(d2);
Serial.print(",");
Serial.print(d3);
Serial.print(",");
Serial.print(d4);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(d11);
Serial.print(",");
Serial.print(d12);
Serial.print(",");
Serial.print(d13);
Serial.print(",");
Serial.print(shim1);
Serial.print(",");
Serial.println(shim2);
}
El intercambio de datos con arduino se describe aquí o aquí .Cómo funcionan losbotones: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':
digitalWrite(13, HIGH);
d13 = 1;
EEPROM.write(13, d13);
glavnaia();
break;
case 'm':
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':
digitalWrite(2, HIGH);
d2 = 1;
glavnaia();
break;
case 'a':
digitalWrite(2, LOW);
d2 = 0;
glavnaia();
break;
...
Regulador de intensidad: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:El comando de anulación shim1 se enviará a arduino case 'F':
shim1 = EEPROM.read(5);
analogWrite(5, shim1 * 2.55);
glavnaia();
break;
case 'f':
shim1 = 0;
analogWrite(5, shim1);
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:Cómo funcionaEs 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){
if(vars[0] == 1) { $(".d2otkl").show(); $(".d2vkl").hide(); }
else if(vars[0] == 0) { $(".d2otkl").hide(); $(".d2vkl").show(); }
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 ');
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 shim1function 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á: Laactualizació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 ');
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.
$(".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;
});
$(".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.