"Casa inteligente" en Arduino para una casa de cambio



Nada fuera de lo común, solo otro controlador Arduino. Con sensores, carretes y una página web. Pero con sus propias características y una aplicación práctica muy específica, aunque bastante banal: la inclusión remota de calefacción eléctrica en el país. Las comillas en el encabezado no son aleatorias, el controlador no es un hogar inteligente en la versión actual, pero sirve como una buena base para ello. (nota: esta frase se agregó el 12/04/18 en función de los comentarios).

Características clave

  • Sensor de parámetros de la red eléctrica - medidor eléctrico "Neva" según RS-485;
  • Modificación remota de la página web de control que se encuentra en la tarjeta SD;
  • Inclusión confiable de un grupo de sensores de temperatura de Dallas en largas filas;
  • Gráficos de cambios de parámetros sin involucrar servicios en la nube;
  • Soluciones a prueba de fallas (vigilancia externa, UPS, reinicio automático del enrutador);
  • Protección del escudo de Internet contra la congelación durante la interferencia de los relés de potencia;
  • Diseño completo en una caja de riel DIN.

Hice este sistema lentamente, como entretenimiento, de vez en cuando lanzando el proyecto durante meses ... Tomó aproximadamente un año y medio desde la idea hasta la implementación :)

Como antes no tenía nada que ver con los microcontroladores, comencé con el kit de inicio con aliexpress, jugué con LED, botones y sensores, entendí algo y comencé a construir un controlador para control y monitoreo remoto. Bueno, la "casa inteligente" no es directa, por supuesto, sino algo así.

El objetivo práctico fue establecer primero uno: encender de forma remota la calefacción en el país. Todavía no he logrado construir una casa (mis manos no llegaron, eh), pero tengo una maravillosa y cómoda cabaña de verano en carne picada calentada por convectores eléctricos. Calienta una casa de cambio que se ha enfriado durante la semana el viernes por la noche, una oportunidad muy tentadora en la temporada de frío.

Sin embargo, la tarea de control de carga remota resultó ser bastante trivial. Arduino más el escudo de Internet, un boceto listo para usar de Internet, y los carretes ya hacen clic en las marcas de verificación en la página web. El objetivo práctico se logró de alguna manera muy rápida y sencilla. Y fue aburrido. Quería algo más interesante

Me propuse un segundo objetivo práctico: monitorear el consumo actual en la red de cabañas de verano. Obtuve sensores de corriente sin pretensiones para las pruebas, jugué. Todo funcionó bien, pero esta opción no era adecuada para el trabajo de combate. No pude encontrar sensores más potentes que en 5A, pero necesitaba al menos 25A.

Y tuve la idea de usar un medidor de electricidad como sensor de potencia. ¡Y fue un gran pensamiento! ¡Y creé un dispositivo así, y vi que era bueno! No sin dificultades, pero completé esta tarea perfectamente, como resultado, con un sentimiento de profunda satisfacción, y lo contaré a continuación :).

Funcional

La primera (y hasta ahora la última) versión de combate del controlador "casa inteligente" tiene esta funcionalidad:

  • Control manual remoto de la activación del relé de potencia a través de un navegador y monitoreo de su estado actual;
  • Monitoreo remoto de los parámetros de una red de suministro de energía trifásica (voltaje, corriente, frecuencia y muchos más elementos innecesarios, que luego apagué);
  • Monitoreo remoto de las lecturas de un medidor de electricidad de dos tarifas;
  • Monitoreo remoto de un grupo de sensores de temperatura;
  • Registro de datos y grabación de eventos en una tarjeta de memoria;
  • Visualice en el navegador los datos de todos los sensores para el día seleccionado en forma de gráficos.

Ideologia

El principio de construir todo el sistema, sin usar servicios en la nube de terceros y servidores de recopilación y visualización de datos. Esto no es ni bueno ni malo. En la etapa inicial de "construcción inteligente", este esquema es suficiente y simple. Aunque impone ciertas restricciones de uso.

Arduino con un escudo de Internet es el único servidor web en el sistema. La página web con la interfaz de administración se almacena en la tarjeta de memoria de Internet y se transmite al navegador cuando se accede mediante la dirección IP especificada. La interacción adicional de la interfaz de usuario con Arduino se lleva a cabo a través de scripts java, cuyos cuerpos no están incrustados en la página web, sino que se almacenan en el almacenamiento de archivos de mi casa con acceso a Internet. Este enfoque reduce el peso de la página web, lo que acelera su lectura desde la tarjeta SD, y le permite modificar el código del script de manera más rápida y fácil.

La lectura del registro de datos para mostrar gráficos se realiza desde la tarjeta de memoria a pedido (presionando un botón en un navegador). Los datos se muestran solo en la sesión actual de la página del navegador, no se guardan en ningún lugar y, cuando vuelve a cargar la página, debe volver a leerla. Esto es una desventaja de la ideología, ya que leer desde una tarjeta de memoria es bastante lento, y obtener una cantidad diaria de datos puede tomar uno o dos minutos (hubo una idea de reelaborar el formato de almacenamiento de datos para reducir su tamaño y acelerar la lectura).

Los valores actuales de los sensores se muestran en la página y se actualizan en tiempo real con la frecuencia del ciclo de bucle, que tengo es aproximadamente 1 Hz.

No hay "inteligencia" en el algoritmo ahora. Si advertiré el algoritmo en el futuro, no lo sé, por ahora la versión actual es completamente satisfactoria para mí.

Topología de red

En la cabaña, Internet móvil Yota (módem usb + enrutador wifi). No hay una dirección IP fija, y tampoco hay forma de obtenerla, ni siquiera por dinero. E incluso no hay una dirección IP blanca dinámica, por lo que DynDNS no es aplicable. Solo la dirección IP gris de la red interna de Yota. IPota Yota no es compatible (al menos para 2017 este es el caso). Por lo tanto, encontré solo una forma de llegar al enrutador del país desde el exterior: VPN.

En casa (en la ciudad), Internet por cable con una dirección IP fija blanca. Enrutador, seguido de almacenamiento en red. Se ha generado un servidor VPN en este enrutador doméstico. El enrutador del país está configurado para elevar el túnel VPN PPTP al enrutador doméstico.

El controlador en Arduino está conectado al puerto LAN del enrutador del país y se encuentra detrás de NAT, el puerto 80 se le reenvía. Por lo tanto, puedo acceder a Arduino solo desde mi VPN. En consecuencia, la LAN doméstica y la VPN que tengo son dos segmentos de la misma subred, el acceso es directo allí. En su computadora de trabajo y en un teléfono inteligente, configuró una conexión VPN y también obtuvo acceso a Arduino. No es muy conveniente de usar, pero funciona. Sí, y se proporciona seguridad relativa: sin autorización en mi VPN, nadie más puede acceder a la página de administración del controlador.

El cuello de botella es el túnel VPN al enrutador del país. Cae periódicamente. Además, es la conexión PPTP la que está siendo interrumpida, el acceso a Internet permanece. Y lo peor es que cuando la conexión PPTP se interrumpe, ya no se eleva por sí sola. Incluso reiniciar el enrutador no se guarda. Solo un reinicio completo de su fuente de alimentación con un módem USB, y luego no de inmediato. Debe apagarlo, esperar 10 minutos y volver a encenderlo. Suerte - bueno, no - la próxima iteración. La razón, según el soporte técnico de Zyxel, es que el operador celular bloquea los paquetes PPTP, ya que un lado envía correctamente, el otro escucha correctamente, pero los datos no llegan (tengo enrutadores Zyxel en ambos extremos del túnel VPN). Yota parece ser el culpable, pero lograr algo inteligible de ellos es imposible. O tal vez no Yota.

Perro guardián

Para garantizar un funcionamiento relativamente fluido de la VPN, utilizo un perro guardián del programa de muletas : el enrutador del país se alimenta a través de un relé de potencia controlado por Arduina, y tan pronto como el servidor VPN deja de hacer ping (también hace ping a Arduina), luego de 10 minutos, se corta la alimentación del enrutador durante 10 minutos, luego el enrutador nuevamente Se enciende y se espera que establezca una conexión PPTP en 5 minutos. Si no hay conexión, la siguiente iteración. A veces, este compuesto funciona de manera estable durante semanas e incluso meses, y a veces comienza a romperse casi a diario. Todavía no se ha visto ninguna otra forma de resolver el problema. Como ya dije, Yota no es compatible con IPv6, no da ni vende IP blanca a los físicos, no hay otro proveedor con tarifas normales y ciertamente no hay tráfico ilimitado. Sin embargo, esta decisión, aunque una muleta, pero realiza su tarea muy bien. Ahora siempre tengo una conexión, con muy pocas excepciones, cuando llego al momento de reiniciar.

Además del software, también implementé un watchdog de hardware. Por si acaso. El controlador debería funcionar durante semanas e incluso a veces durante meses en ausencia de mí, y no colgarse. No sabía cómo se comportaría toda esta economía en grandes desventajas, así que estaba a salvo. El perro guardián incorporado en Atmega no funcionó para mí porque no trabajaba en Arduino Mega "fuera de la caja" en absoluto, y para que funcionara tuve que divertirme mucho. Este problema está bien descrito aquí . Además, tiene un intervalo máximo de 8 segundos, lo que me pareció insuficiente. Por lo tanto, utilicé un chip temporizador de vigilancia especializado TPL5000DGST, cuyo intervalo se establece mediante una combinación de tres pines y puede alcanzar los 64 segundos, lo que me conviene perfectamente. Para este chip compré una pequeña placa de prueba, la solde y la fije en el conector con los puertos IO de Arduina (la foto estará más abajo en la sección de ensamblaje). Las pruebas mostraron el funcionamiento confiable de este perro guardián, y me preguntaba con qué frecuencia funcionará en realidad. Para hacer esto, agregué una variable al código del programa donde se almacena la hora y la fecha en que se inició el programa, y ​​esta información se muestra en la página web de control. La práctica ha demostrado que, a diferencia de una VPN, el controlador funciona sin problemas durante mucho tiempo y el temporizador de vigilancia nunca ha sido útil (al escribir el artículo, funcionó por primera vez, no fue en vano). El tiempo de operación continua alcanzó más de 3 meses y podría haber sido más si no tuviera que corregir algo en el código de vez en cuando y volver a actualizar el controlador.

El sensor de parámetros de la red de suministro de energía: el medidor eléctrico Neva


Como mencioné anteriormente, en mi opinión, nada mejor y más preciso que un medidor de electricidad digital moderno con una interfaz de acceso a datos externos se puede encontrar como un sensor de los parámetros de red de la fuente de alimentación. Elegí el mostrador Neva de la compañía Taypit de San Petersburgo con la interfaz RS-485.

Destaco que un medidor eléctrico con cables de la interfaz 485 conectada permanentemente a él no está oficialmente permitido para usarse como medidor ( actualización : en los comentarios sugirieron que estaba permitido). Por lo tanto, en la red eléctrica de la cabaña, puse dos contadores en serie. El primero es un medidor de electricidad oficial, sellado y registrado, ubicado en el panel de entrada de la calle. El segundo es mi sensor de fuente de alimentación, sin sellar y sin contabilizar, que a la compañía de ventas de energía no le importa, porque no le importa todo lo que se instala después del dispositivo de medición. Este medidor eléctrico ya está ubicado en el panel dentro de la casa de cambio, y en el mismo panel también hay un controlador en Arduino, pero más sobre eso más adelante.

En la cabaña tengo una red de suministro de energía trifásica. En la ciudad, solo puedo depurar en una sola fase. Por lo tanto, adquirí dos metros, un Neva MT-324 trifásico y un Neva MT-124 monofásico. La depuración inicial del controlador se realizó en la mesa en un medidor trifásico con una sola fase conectada, luego se instaló nominalmente en el tablero de la cabaña en modo de operación de combate. La depuración de modificaciones de software posteriores ya se realizó en un contador monofásico más barato en la tabla:



Para conectar el medidor a Arduino, se requiere un convertidor de nivel RS-485 a TTL:


Además, para trabajar con el contador, necesita un puerto serie libre en Arduino. Desafortunadamente, Arduino Uno solo tiene un puerto serie, si lo toma bajo el mostrador, tendría que perder la salida de depuración de la información de texto (monitor de puerto), y sin esto sería imposible escribir un boceto. Por lo tanto, uso Arduino Mega, que tiene varios puertos seriales. Sería posible implementar el segundo puerto serie softovo a través de los puertos digitales de Arduino, pero no encontré una biblioteca adecuada con la capacidad de cambiar otras configuraciones de puerto, excepto la velocidad. Y la configuración del puerto del contador es diferente de la predeterminada: velocidad de 9600 bits, 7 bits de datos, 1 bit de parada, control de paridad, incluso. El objeto serial estándar en Arduino, afortunadamente, le permite realizar esta configuración.

Fue relativamente fácil obtener el protocolo de intercambio con el contador: el fabricante del contador en el dominio público tiene un programa para leer parámetros en Windows, que también tiene un monitor de puerto. Para conectar el medidor a una computadora, utilicé el convertidor de interfaz MOXA 232/432 / 485USB. Algún tiempo para el análisis visual de los paquetes, y seleccioné los comandos principales.

Sin embargo, esto no me pareció suficiente y contacté al fabricante por correo electrónico. Después de un mes de correspondencia con Typit, finalmente logré obtener una lista completa de comandos con interpretación:

Codificación de parámetros MT3XX E4S
Codificación de parámetros NEVA MT124 AS OP (E4P)

actualización 28.10.2019 : explicaciones de los comandos. Los comandos en la tabla se representan como caracteres de texto. Es decir, donde cuesta 0 (cero), debe enviar 0x30. Los puntos y asteriscos son separadores de belleza, no significan nada y no es necesario enviarlos. Al final del comando, se agrega un byte de suma de comprobación, que se calcula teniendo en cuenta el prefijo y el postfix del comando, que no se indican en la tabla. El prefijo para todos los comandos de lectura es 0x01 0x52 0x31 0x02. Este postfix es 0x28 0x29 0x03. Sin embargo, no es necesario enviar un prefijo, y un postfix parece ser obligatorio. Ejemplo: comando de lectura de fecha 09.09.02 * FF. En realidad, debe pasar los códigos de caracteres de texto 000902FF. Es decir, 0x30 0x30 0x30 0x39 0x30 0x32 0x46 0x46. Agregue el prefijo y el postfix, obtenemos el conjunto 0x01 0x52 0x31 0x02 0x30 0x30 0x30 0x39 0x30 0x32 0x46 0x46 0x28 0x29 0x03. Leemos la suma de comprobación como xor de todos los bytes menos 1 y agregamos el byte recibido al final. El prefijo se descarta como opcional. Como resultado, lo enviamos al mostrador: 0x30 0x30 0x30 0x39 0x30 0x32 0x46 0x46 0x28 0x29 0x03 0x68. El comienzo del ciclo de intercambio debe estar precedido por los comandos de inicialización de intercambio, en el siguiente esquema, estos comandos están marcados como // Inicio 1, 2, 3. Una vez que se inicializa el intercambio, puede leer los datos del contador en el ciclo durante un tiempo arbitrariamente largo, pero después de perder la comunicación y quizás después de una prolongada falta de intercambio por otras razones, se necesita reinicializar.

Además, la cuestión técnica es escribir un ciclo de sondeo de parámetros en Arduino y mostrarlos para empezar en el monitor de puerto. El tiempo de un ciclo fue de aproximadamente un segundo. Sin embargo, en la versión final del proyecto con registro de datos en una unidad flash y sensores de temperatura de sondeo, este tiempo aumentó a 4 segundos. Esto no me convenía en absoluto y tuve que sumergirme en la optimización. Como resultado, nuevamente logré un segundo intervalo sin perder funcionalidad. Por cierto, reescribí el boceto desde cero dos o tres veces hasta que encontré la arquitectura correcta y los algoritmos económicos.

Implementación de software de intercambio con un contador

El código se extrae del contexto de mi gran boceto de trabajo. Compilado, pero de esta forma, nunca lo ejecuté. Lo doy solo como un ejemplo, y no como un programa de trabajo terminado. Aunque en teoría todo debería funcionar de esta forma.

El código está escrito para dos tipos de contadores simultáneamente, el monofásico MT-124 y el trifásico MT-324. El tipo de contador se selecciona en el programa automáticamente mediante la palabra de respuesta del comando de inicialización.

Cito el código tal como está, sin belleza y sin comentarios adicionales, excepto los que escribí para mí. Y sí, no soy un programador, y ni siquiera estudio para ello, así que no deberías echarme por la calidad del código, pero puedes aprender a codificar: EnergyMeterNeva.ino

Una gran ventaja adicional del medidor de electricidad es un reloj confiable y preciso en tiempo real. No tuve que proporcionarle al sistema un módulo adicional, que aún debe encontrarse no solo de todos modos, sino de alta calidad. La hora actual precisa al segundo que obtengo del contador, entre otros datos. Sí, con respecto al tiempo atómico, el tiempo del contador cambia ligeramente (unos segundos), no sé con qué está conectado, una configuración de fábrica de baja calidad u otra cosa, pero la precisión es excelente, solo con un ligero sesgo.

En raros momentos, cuando se apaga la electricidad en la cabaña y el medidor deja de estar disponible, obtengo la hora actual del temporizador interno de Arduina. Cuando el medidor eléctrico está funcionando y sus datos están disponibles, reescribo el temporizador interno de Arduina con el valor del medidor en cada bucle de bucle. Cuando el contador se cae, la hora actual sigue marcando el temporizador Arduina.

Además de leer los parámetros, el contador, por supuesto, se puede programar. Es decir, la interfaz funciona tanto para leer como para escribir. Sin embargo, con tales dificultades, estaba tratando de obtener un protocolo para leer comandos que ni siquiera insinué al fabricante sobre la solicitud de un protocolo de grabación. En primer lugar, no lo necesitaba, excepto tal vez solo un poco de tiempo para moverlo. En segundo lugar, sospecho que estos datos ya no son públicos, ya que pueden utilizarse con fines fraudulentos.

Sensores de temperatura

Ya realicé una prueba de sensores de temperatura con un ejemplo de boceto por separado anteriormente.Ahora solo quedaba integrar su encuesta en el proyecto principal. No fue dificil. Los nueve sensores que he trabajado funcionaron sin problemas cuando encendí 1-Wire en paralelo. El rango de lecturas entre ellos fue de aproximadamente 0.5 grados, lo que muestra la inutilidad de usarlos con una precisión máxima de 0.0625 grados. Recogí los sensores para la prueba en un paquete y lo envolví en varias capas de polietileno adhesivo. Para mayor precisión, coloqué el paquete verticalmente y esperé un día para igualar completamente la temperatura. Las lecturas de todos los sensores no resultaron iguales.

Sin embargo, no comencé a arruinar la precisión de convertir la temperatura de los sensores mismos. Es más fácil redondear las lecturas mediante programación, y no obtendría los beneficios desde el momento de la encuesta, ya que se me ocurrió un algoritmo en el que el tiempo de espera de conversión no es un retraso inútil vacío (750). La lógica habitual para trabajar con sensores es emitir primero un comando para iniciar la conversión de temperatura, luego esperar a que termine la conversión (esos mismos 750 ms como mínimo) y luego leer los datos. Hice lo contrario, lo que me permitió excluir un intervalo de espera vacío: primero leí los datos de los sensores y luego comencé inmediatamente la conversión. Y aunque todo el resto del código en el ciclo LOOP funcionará, los datos solo tienen tiempo para prepararse para la lectura en la próxima ronda. Con el tiempo, obtengo los datos de los sensores en este caso un poco más tarde: el ciclo LOOP dura aproximadamente 1-1.5 segundos, pero esto no es absolutamente crítico.

«85» «0». , , . — . , . , ( ) .

-, - : DS18x20_Temperature.ino

: TempSensors_DS18B20.ino

Para el correcto funcionamiento de los sensores en el bus de 1 cable, se debe instalar una resistencia pull-up de 4.7 kΩ entre la línea de datos y la fuente de alimentación. Fue conveniente para mí soldar una resistencia SMD entre los pines del bloque de terminales, pero encontré solo 5.1 kOhm en un estuche adecuado y lo puse (es visible en la foto en la sección de ensamblaje en el lado inferior de la placa). Todo funciona bien

Mis sensores de temperatura están conectados eléctricamente en paralelo en una línea larga (+5, gnd y datos), las 9 piezas, pero complicado. Físicamente, los cables de par trenzado están conectados por una estrella para la conveniencia de cablear sensores alrededor del objeto. Yo uso dos pares en cada brazo de cable. Un par es la potencia del sensor. El segundo par es una línea de datos que atraviesa un cable hasta el sensor y regresa a través del segundo cable. Por lo tanto, es posible separar los cables con una estrella del escudo, pero eléctricamente es una estrella solo en potencia, y según los datos es una línea. Esta opción de conexión resultó ser más confiable al trabajar en líneas largas, con una conexión paralela simple, hubo muchas fallas al leer los datos. Aquí hay un bosquejo de tal esquema:



No acorté las colas de medio metro de los cables de tres hilos de los sensores, las conecté tal como estaban, resultó que no era crítico.

En total, hay tres cables para las cabinas, dos para sensores externos, uno para cada uno y uno para los siete restantes internos. Estos siete sensores internos están conectados de la misma manera, pero dentro de un cable largo y con ramas cortas (ver la forma de T inferior en el boceto). En algún lugar había suficiente cola estándar de medio metro del sensor para ramificar, en algún lugar se ramificó con la ayuda del mismo par trenzado.

Circuito de conmutación del sensor de dos hilos, con el llamado No utilicé energía parasitaria (cuando los sensores reciben energía a través de la línea de datos) porque ... ¿por qué? En cualquier caso, tomaría cables de cuatro pares, simplemente porque los tenía. No hay problemas al tender el cable en las cabinas. Y el circuito de suministro de energía parásito es crítico para la cantidad de corriente consumida en algunos modos de operación, podrían surgir problemas innecesarios.

La longitud total del par trenzado en las cabañas era de aproximadamente 25 metros. Piezas para sensores externos: 5 y 10 metros, y una pieza interna de diez metros con ramas para siete sensores. Todo funciona casi a la perfección. Solo ocasionalmente se cruzan guiones en lugar de valores de temperatura. Esto significa que los datos de un sensor en particular no se leyeron correctamente. Pero esto ocurre tan raramente (me doy cuenta una vez al mes tal vez) que no causa ningún problema.

El

escudo de Ethernet de acceso remoto se compró para acceso remoto a Arduino. Con una biblioteca incorporada, trabajar con ella, como todo lo demás en Arduino, resultó ser bastante simple.

Funcionalmente, mi esquema de trabajo es el siguiente. Se ha creado un servidor web en Arduino que, cuando un cliente (navegador) accede a él, genera una página web con información diversa. La actualización automática de los datos en la página se implementa mediante el sondeo de JavaScript del servidor por temporizador.

La página también tiene un conjunto de controles para controlar los actuadores conectados a Arduino - relés de potencia que cambian la carga - calentadores eléctricos e iluminación.

No tomé un baño de vapor con el diseño de la página web, especialmente porque se necesitaba una cantidad mínima de datos de texto para cargarla más rápido, por lo tanto, el html más primitivo y eso es todo:



En lugar de datos, incrusté etiquetas en el código html, que al momento son reemplazadas por datos reales cuando el servidor genera la página. Cuando los datos se actualizan automáticamente a pedido de javascript, se transfieren al navegador directamente desde el microcontrolador en formato JSON.

El código de la página se encuentra en un archivo en la tarjeta de memoria y se carga al acceder al servidor. Para una modificación más rápida y conveniente del código de la página, incorporé el mecanismo para actualizarlo yo mismo. En la parte inferior, debajo del bloque de controles básicos, hay un cuadro de texto y un botón Enviar. Copio el nuevo código html en el campo de texto, presiono el botón, después de lo cual el script java envía datos al servidor web del controlador, que primero lo guarda en un archivo en spool. Si la transferencia se realizó correctamente, el archivo principal se reemplaza por un búfer y la página se actualiza automáticamente. Eso es todo.Cambios aceptados.

Cito los fragmentos de código de mi implementación de este mecanismo.
En la página html incorporamos el formulario:

<script type="text/javascript" src="http://domain/send_HTM.js"></script></pre> <pre style="font-size: 14px;"><form> <br><br> CONTROL.HTM:<br> <textarea cols="100" rows="20" wrap="off" id="htm"></textarea><br> <input type="button" value="" onclick="send_HTM();"><br> <div id="progress" style="display:none"> <div id="label">  :</div> <div style="width:800px;border:1px solid #000"> <div id="bar" style="background:#00f;height:10px;width:0px"></div> </div> </div> </form> 

El botón "Enviar" inicia el siguiente script Java : send_HTM.js

En el boceto en la función para procesar solicitudes de servidor web por prefijos en la solicitud 'CONTROL.HTM' (comenzar a enviar el archivo), 'htmlineN' (enviar línea No.) y 'END_CONTROL.HTM' (finalizar el envío del archivo), determinamos las siguientes acciones:

 File acceptHtmFile; ................ if (fl_accept_htm) //  'CONTROL.HTM' { SD.remove(CTRL_HTM); acceptHtmFile = SD.open(CTRL_HTM, FILE_WRITE); //     if (!acceptHtmFile) //      -    { #ifdef DEBUG_SD Serial.println("SD-card not found"); #endif client.print("FAIL"); client.stop(); } else client.print("OK_OPEN_FILE"); acceptHtmMode = true; break; } if (fl_htmline) //  'htmlineN' { int b = acceptHtmFile.println(tag); if (b == 0) { client.print("FAIL"); acceptHtmMode = false; cntHtmModeIteration = 0; } else { client.print("OK"); } cntHtmModeIteration = 0; break; } if (fl_endhtm) //  'END_CONTROL.HTM' { SD.remove(CONTROL_HTM); acceptHtmFile.close(); File htmlFile = SD.open(CONTROL_HTM, FILE_WRITE); //    acceptHtmFile = SD.open(CTRL_HTM); //    for (int i = 0; i < acceptHtmFile.size(); i++) { digitalWrite(PIN_WATCHDOG_DONE, 1); htmlFile.write(acceptHtmFile.read()); digitalWrite(PIN_WATCHDOG_DONE, 0); } acceptHtmFile.close(); htmlFile.close(); client.print("OK_CLOSE_FILE"); acceptHtmMode = false; cntHtmModeIteration = 0; break; } 

CONTROL_HTM y CTRL_HTM define aquí los nombres de los archivos html. El primero es el archivo principal, el segundo es el archivo de búfer. En la matriz de etiquetas char se encuentra el texto de la cadena recibida, seleccionada de la solicitud. La lógica es la siguiente: cuando se reciben datos, se escriben en el archivo en spool, al final de la recepción, el archivo en spool se sobrescribe en el archivo principal. Todavía no podía entender cómo simplemente cambiar el nombre de los archivos, la biblioteca estándar SD no tiene esa función, por lo que la copia estúpida de carácter por carácter, que lleva mucho tiempo.

Sería conveniente almacenar el código de la página web de control no en la tarjeta de memoria del controlador, sino en la máquina del cliente, o descargarlo de algún recurso externo. Pero la prohibición de solicitudes entre dominios no permite esto. Javascripts pueden enviar sus solicitudes solo al norte desde donde fueron cargadas. En este caso, los cuerpos de los javascripts se pueden cargar desde cualquier lugar, solo es importante desde dónde se cargó la página con su llamada.

Registro de datos

El escudo de Ethernet tiene una ranura para tarjeta micro-SD a bordo. Fue por su presencia que decidí escribir datos en los archivos de registro. Para trabajar con una tarjeta de memoria, también hay una biblioteca incorporada, y administrar la lectura y escritura de archivos con ella es generalmente elemental.

Para guardar la cantidad de datos, construí el algoritmo de registro para que el registro solo ocurra cuando los datos cambien en más de un umbral predeterminado. Para temperatura es 0.1 °, para voltaje es 0.2V. Los datos de un día se escriben en un archivo. A las cero horas, se crea un nuevo archivo. Elegí el formato de texto plano, con delimitadores, para que pueda controlar rápidamente el contenido de los archivos durante la depuración, y habría una capacidad simple de cargar en Excel.

Las restricciones de diseño no le permiten insertar / quitar convenientemente una tarjeta de memoria, por lo que utilicé una tarjeta grande. Según mis cálculos, se completará durante varios años, después de lo cual será necesario desmontar la carcasa, quitar la tarjeta de memoria y limpiarla.

No veo el punto de registrar el código, todo es completamente trivial allí: un registro banal de texto en un archivo. Y este código se extiende por todo el boceto (no solo se registran los parámetros de los sensores, sino también una variedad de eventos únicos), es difícil de aislar.

Gráficos

Como motor de gráficos, utilizo la biblioteca de visualización java amavart altamente flexible. La biblioteca es gratuita y está disponible para descargar y usar sin conexión. También ubiqué esta biblioteca en mi NAS con acceso permanente a Internet. Conectarlo y usarlo con la configuración predeterminada no es difícil, sin embargo, para obtener la vista que necesitaba, tuve que jugar mucho. Una gran cantidad de ejemplos en el sitio y la disponibilidad de documentación detallada ayudaron.

Por ejemplo, daré el javascript del dibujo de horarios. En sí mismo, es inútil, ya que solo funciona en conjunto con un servidor web y con una página html, y puede estar vinculado a otros scripts (fue hace mucho tiempo, no recuerdo todos los detalles). Pero la configuración de apariencia de mis gráficos está contenida y puede obtenerlos desde allí: get_log.js

La gran ventaja de la biblioteca amchart es que puede dibujar los gráficos correctos a partir de datos desgarrados. Como mencioné anteriormente, en el registro guardo datos solo cuando cambian. Es decir, esto sucede de forma asíncrona y aleatoria. Es posible que no haya datos nuevos durante varios minutos y luego, en unos segundos, cambiarán varias veces. En consecuencia, las entradas en el registro van con intervalos de tiempo arbitrarios. Amchart toma esto en cuenta por sí solo cuando renderiza, no tengo que interpolar los datos antes de renderizar. Acabo de enviar la matriz de datos tal como está, y veo un hermoso gráfico que es uniforme en el tiempo.

Descubrí solo un inconveniente de esta biblioteca: no sabe cómo (bueno, o todavía no entiendo cómo) actualizar humanamente los gráficos en tiempo real. Puede agregar nuevos datos a los existentes, pero el rediseño se realiza cada vez por completo de toda la matriz de datos, y esto ralentiza enormemente el navegador. Sin embargo, la propia ideología de leer datos de Arduina para renderizar a pedido desde el navegador es defectuosa por su falta de optimización, por lo que no tenía sentido luchar por una actualización rápida en tiempo real.

La decisión correcta sería organizar un servidor separado para almacenar y visualizar datos, desde donde Arduina en tiempo real los datos caerían un poco y se almacenarían en la base de datos, y desde donde podrían enviarse rápidamente al usuario en un navegador para su visualización.

Ahora los gráficos se ven así (en el ejemplo del día en que no hay nadie en la casa de cambio y, en consecuencia, no hay consumo de energía). Cuando se producen los datos actuales, la escala se establece automáticamente para que todo encaje bien y los valores de los niveles actuales aparecen en el eje vertical:



Los gráficos se muestran en la misma página donde tiene lugar el control, directamente debajo del bloque de control principal.

No proporciono intencionalmente un conjunto completo de fuentes de proyecto por varias razones:

  1. No se puede iniciar ya que está en cualquier red que no sea la mía, ya que no intenté hacer que el proyecto sea portátil, y está rígidamente vinculado a mis direcciones y mi topología de red.
  2. Estoy seguro de que la ideología general del proyecto sufre muchos problemas, ya que este es mi primer intento en el área en la que no soy bueno para entender. Por lo tanto, no propongo a nadie que se repita todo el proyecto de esta forma. Compartí solo esos momentos en los que tengo menos confianza.
  3. El proyecto se ha realizado durante mucho tiempo y durante mucho tiempo, y nunca recordaré todos los detalles y no podré explicar una serie de soluciones. El volumen del boceto es muy grande (para mis estándares, alrededor de 2 mil líneas), hay más de una docena de scripts Java que sirven, no hice un diagrama esquemático de la plancha. Es decir, no puedo evitar el asesoramiento sobre la mayoría de los problemas.

Asamblea

Desde el principio me propuse el objetivo: hacer un dispositivo terminado, y no solo un diseño con un montón de publicaciones en la mesa:



E inmediatamente decidí que quiero colocar el dispositivo dentro del panel eléctrico. Hay comida y un mostrador, y en general, es conveniente.

Para esto, se requería un caso dinrek. Al principio pensé en desarrollarlo e imprimirlo en una impresora 3D. Pero no tengo mi propia impresora 3D, y lo que mis colegas que trabajan en sus impresiones de impresoras autoensambladas no me convencieron en absoluto en la calidad de su apariencia. Encontré cajas listas para usar en un riel DIN (de varios tamaños) a la venta, se ven bien, son convenientes de usar (plegables) y también hay una tarjeta ciega lista para usar.

Compré el estuche más grande, para que no solo Arduino con el escudo de Internet pudiera caber en él, sino también un relé para cambiar la carga:









El siguiente fue un proceso largo y fascinante de instalación de todos los tripas en el caso. En este negocio, incluso adquirí un soldador maravilloso con la función de sueño (los soldadores que tenía todavía eran de la época soviética):



Para la instalación, compré un montón de todo tipo de bastidores, tornillos, arandelas y tuercas. Primer montaje de montaje:





Para conectar los cables a los contactos superiores, era necesario usar pines doblados, de lo contrario no encajaba en la caja:



Las arandelas aislantes tuvieron que cortarse en algunos lugares:



Y en algunos lugares, se doblará más perversamente, levantará el tornillo de la manga y recortará la manga elaboradamente:





Para una sola reubicación no había suficientes puntos de pivote, por lo que colgaba solo en dos puntos:



Ensamblaje ensamblado con bloques de terminales:



Luego, la nave comenzó a convertirse gradualmente en cables. La placa se usó solo para el cableado de alimentación y para la conexión a bloques de terminales. Para las conexiones de señal, utilicé el cable MS-16 (me gusta más), para la alimentación no pasó a través del voltaje (hasta 100 V), por lo que MGTF:



Monté LED en el panel frontal, solde las resistencias limitadoras de corriente directamente a las patas de los LED y las cerré con termocontracción:



Como resultado, obtuvimos un relleno tan barbudo:



Y aquí hay una bufanda con un microcircuito de vigilancia, protegida en las entrañas de mi creación, justo encima del convertidor de nivel RS-485-TTL:





Toda la estructura es plegable, todo se puede quitar, desconectar y reemplazar sin soldar, a excepción de una bufanda con un ojo de perro, se suelda a los pines del conector, se viste en varios puertos IO de Arduina.

En la caja:



Corté aberturas para los conectores de Arduina en la pared de plástico de la caja. Primero hice los agujeros exactamente de acuerdo con el tamaño de los conectores, pero el ensamblaje en la caja debe iniciarse en diagonal (de lo contrario, simplemente no funciona) y los conectores no pasaron, tuve que desperdiciar un poco:



Al encender el producto terminado en la mesa, todo funcionó de inmediato:





En el panel frontal trajo:

  • Cuatro LED rojos: indicación de carga;
  • Dos verdes: comunicación con el contador y con el servidor VPN;
  • Dos amarillas son de repuesto;
  • Una amarilla: indicación de reinicio del enrutador;
  • Uno rojo es la nutrición;
  • Y un botón de reinicio.

Para obtener 5 voltios de 220, utilicé una fuente de alimentación dinerey con ajuste de nivel de salida, la energía se suministró directamente al microcontrolador, evitando el convertidor de entrada de 7-12 a 5 voltios. Esto fue conveniente por varias razones. En primer lugar, la potencia del convertidor incorporado en algún momento no fue suficiente, la corriente allí es limitada. En segundo lugar, todavía era necesario suministrar el relé con 5 voltios. En tercer lugar, el tablero es un factor de forma dinrek conveniente en términos de instalación. Por lo tanto, aquí:




Prueba

Todo estaba puesto sobre la mesa, todo funcionaba como debería, era hora de instalar el controlador en el escudo y comprobarlo en modo de combate.

Pero primero, conecté todo "en el moco", literalmente empujando todos los callos a otro escudo, de baja corriente para probar los sensores de temperatura en condiciones reales en largas líneas tendidas en un canal de cable con cables de alimentación de ~ 220V:



Como puede ver en la foto de arriba, hasta ahora intenté controlar el reinicio del enrutador mediante el uso de la toma Senseit "inteligente". Sin embargo, este dispositivo con un costo loco de 5 mil (para 2016) resultó ser extremadamente defectuoso y de mal humor. Durante el año de uso, en repetidas ocasiones me obligó a llegar a la cabaña de manera imprevista en momentos inoportunos, para eliminar manualmente este milagro de la ingeniería y el pensamiento de marketing desde un profundo inconveniente en términos de comunicaciones GSM. Con la transición a mi controlador Arduino, que resultó ser más confiable que un ejemplo, me sentí aliviado de dejar esta basura "profesional" en una hermosa caja en una caja y olvidarme de ella.



La prueba fue exitosa, no hubo fallas y fue posible proceder a la instalación final en un lugar regular:



Sí, este es el escudo ABB TwinLine 800x300x225 IP55, por valor de 25 mil rublos. sin relleno (y relleno por otros 15 mil aproximadamente). Y sí, está instalado en una casa de cambio de 6x2. Todos tienen sus propias cucarachas. Sí, recogí todas las eléctricas yo mismo . Y también construyó una casa de cambio, sí. No, no soy electricista. Y no un constructor.



En las profundidades del escudo, ubiqué una pequeña fuente de alimentación ininterrumpida Powercom WOW 300 , allí se enciende su LED verde y, a la izquierda y arriba, su enchufe de entrada:



Tiene una duración de ~ 40 minutos de duración de la batería del dispositivo Arduino, un enrutador con módem USB y Wi-Fi, y cámaras de vigilancia IP Full HD.

Y aquí puede ver los enchufes blancos de dos consumidores ininterrumpidos: la unidad de fuente de alimentación Arduino y el escudo de baja corriente, donde se encuentran el enrutador y la unidad de fuente de alimentación para la cámara de vigilancia exterior. Esta línea va con una ruptura a través del contactor, que es controlado por Arduino, solo para el mismo perro guardián de software que reinicia el enrutador en caso de una caída de VPN (la cámara se reinicia al mismo tiempo, aunque no lo necesita). Las líneas superiores de pares trenzados de los sensores de temperatura están conectadas al controlador:



Debo decir que nunca confiaría en el cambio de una carga potente a pequeños relés chinos azules, a pesar de los parámetros de estos relés, que parecen permitir que esto se haga. Por lo tanto, el uso de contactores modulares normales Legrand cat. No. 4 125 01 con la posibilidad de control manual se estableció de inmediato. Es decir, los relés dentro del cuerpo del controlador controlan los contactores, y los contactores ya controlan la carga. Es confiable Pero la potencia del enrutador y la cámara se lleva a cabo solo a través de este pequeño relé chino azul, la corriente allí es pequeña, por lo que es posible.

En el primer lanzamiento de combate, estaba muy decepcionado. Sobre la mesa, experimenté todo excepto la carga. Por qué Los contactores hacen clic y queda claro que cambiarán la carga. Pero no, era necesario experimentar. Potentes electroconvectores introdujeron interferencia en el sistema en el momento de abrir los contactos, lo que condujo a una congelación garantizada del escudo de Internet. Y para sacarlo de la depresión solo fue posible eliminando el poder, un simple reinicio no ayudó. Buscó en Google: sí, este chino tiene ese problema. Y la biblioteca no maneja esta situación. Es decir, la pieza de hierro es mala y el software no es muy bueno.

Ya pensé que todo se había ido. Incluso ordené relés de estado sólido, pero ellos, escoria, son más grandes en altura y no encajarían en mi diseño. Pero luego pensé que aún podría ser posible suprimir la interferencia. Buscó en Google nuevamente, encontró condensadores especiales de supresión de ruido (los llamados condensadores de tipo X). Simplemente los conecté en paralelo al control de bobinado de los contactores, y ¡he aquí! Los bloqueos desaparecieron por completo. Durante el año pasado de operación, no se ha registrado un solo caso:







Pero de esta manera puedes mirar dentro de la caja:





Bueno, la vista final de la visera con el plastrón (no se proporcionaron enchufes en el kit):



Para la depuración y el parpadeo, el cable USB se conecta al controlador y se almacena dentro del protector detrás de una puerta cerrada (no se conectará temporalmente a esta foto):





El sistema ha estado funcionando durante casi un año, sobrevivió a las heladas hasta 20 grados sin ningún problema.

En general, estoy satisfecho con el resultado. Sin embargo, para tareas más o menos funcionales, Arduino es claramente débil. Más de una vez me quedé sin memoria y tuve que cortar y optimizar. Y la velocidad del trabajo, especialmente con una tarjeta de memoria, no me conviene en absoluto. Por lo tanto, las implementaciones futuras de tales manualidades, si las hubiera, me gustaría basarme en algo más poderoso. Los colegas me dan una Raspberry Pi, una buena opción, creo.

Alguien podría decir: "¿Cuántas dificultades hay en aras de una tarea tan primitiva?", Y probablemente tenga razón. Para mí, toda esta empresa es un pasatiempo, con poca justificación para el significado. Por lo tanto, estaba buscando entretenimiento en todo lo que pudiera :)

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


All Articles