Sistema local de adquisición de datos autónomos

Continuación de este artículo.
La compañía compró puestos de monitoreo NEXT-M de NEXT Technologies de producción nacional. Para garantizar la visualización del funcionamiento de las unidades de bombeo,
alarma de incendio, voltaje en los arrancadores, temperatura ambiente, nivel de emergencia del agua. El corazón de NEXT-M es ATMEGA 1280 y este hecho fue alentador en términos de la posibilidad de crear su propio kit para necesidades específicas.

La tarea se estableció para crear un sistema de despacho local totalmente autónomo en el menor tiempo posible y al menor costo. La base es el microcontrolador. Desarrollo, fabricación, todo por el propio personal.

El sistema debe funcionar sin depender de redes celulares, servidores, Internet y el sistema de licencias para usar recursos de radiofrecuencia, no usar computadoras o el uso periódico máximo de computadoras portátiles en el sistema de monitoreo y control, sin acceso a objetos por un período prolongado (6-9 meses). La configuración de red tiene una estructura radial. Los datos se recopilan en un punto y luego se envían para su procesamiento a través de canales de comunicación convencionales o como una copia impresa.

El sistema debe proporcionar:

  • monitorear la operación de las unidades de bombeo
  • automatización tecnológica
  • protección de emergencia
  • alarma de emergencia
  • horas de funcionamiento
  • cálculo de la cantidad de electricidad consumida
  • control de temperatura del equipo
  • alarma de incendio
  • lectura remota periódica de información
  • requisitos futuros desconocidos

Condiciones de trabajo:

  • área de cobertura 1 km cuadrados.
  • visibilidad directa entre objetos
  • temperatura de +50 a -50 C
  • humedad hasta 100%
  • depósitos biológicamente activos (moho, bacterias reductoras de sulfato)
  • vibración, no más, máquinas de 1–2 clases según GOST ISO 10816-1-97
  • entorno electromagnético: conmutación de motores eléctricos por contactores KT 6053, arrancadores suaves RVS-DN, equipo de control PID SIEMENS MICROMASTER, radiación en el rango ISM y GSM de acuerdo con los requisitos para estos dispositivos, soldadura por arco manual en el sitio
  • sobretensión de la red, cortes de energía a corto plazo, sobretensiones de rayos, desequilibrio de fase en caso de una línea aérea de circuito abierto en redes de distribución de 6-10 kV.

A pesar de requisitos tan estrictos, la implementación es bastante simple con una solución gradual al problema.

Con todo esto en mente, la placa Arduino Nano 3.0 se convirtió en el "cerebro" de lo concebido. El chal Robotdyn tiene un controlador ATMEGA 328, el regulador de voltaje necesario de 3.3V
800 mA de corriente y convertidor a CH340G UART-USB.

En primer lugar, los contadores de tiempo de funcionamiento se crearon como los más relevantes. Los medidores industriales utilizados anteriormente recogidos en los PIC con un circuito de suministro de energía sin transformador fallaron debido a sobretensiones durante el año de operación. Solo intacto con la ayuda de fuentes de alimentación caseras para 5V permaneció intacto. Para acelerar la instalación y la universalidad de la conexión, se toma una señal sobre el estado de las unidades de los terminales de los dispositivos de conmutación, es decir, Registro de la presencia de la 1ª fase de la tensión con una fuente de alimentación trifásica de 380V. Para coordinar con el controlador, se utiliza un relé intermedio con un devanado de 220 V o un optoacoplador compuesto por un LED y un fotorresistor GL5516 o un optoacoplador PC817. Todas las opciones fueron probadas. El LED está alimentado por un voltaje rectificado con limitación de corriente utilizando dos condensadores CBB22 diseñados para un voltaje de 630 V y conectados en serie por seguridad durante la verificación aleatoria de circuitos con un megaohmímetro.
Lectura del tiempo de funcionamiento utilizando la pantalla LCD ST7735S, transmitiendo datos en tiempo real por el aire utilizando el módulo E01-ML01DP05 a una frecuencia de 2,4 MHz. Este dispositivo contiene un chip nRF24L01 + y un amplificador de recepción-recepción RFX2401C,
Potencia de salida de hasta 100 mW. Antenas espirales diseñadas para el rango deseado en la calculadora en línea del sitio . La elección del tipo de antena se debe a la exclusión de la recepción de ondas reflejadas de las estructuras metálicas circundantes. Las piezas de la antena se imprimen en una impresora 3D. El estado actual de los contadores se almacena en la EEPROM del controlador y se restaura en caso de un corte de energía inesperado. El chip RTC DS3231 proporciona intervalos de tiempo para contar en forma de módulo con una batería de respaldo. Se utilizan tres módulos en la unidad de fuente de alimentación, la fuente de pulso HLK-PM01 600mA 220 / 5V, el convertidor HW-553 y 03962A de 1-5V a 5V son un controlador de batería con un circuito de protección contra cortocircuitos, sobredescarga y sobrecarga. Todos los componentes se compraron en el sitio web de Aliexpress.

Tablero de pan
imagen alt

Contador de 4 canales. En las entradas hay filtros LC para proteger contra interferencias en una línea de comunicación de par trenzado. Los datos sobre el estado de los objetos de control se leen constantemente 1 vez por segundo, y se muestran en color en la pantalla LCD. Las lecturas se actualizan y registran en la memoria no volátil cada 36 segundos. 36 segundos Es 1/100 horas, es en este formato que se requieren datos. Cada 12 segundos La información se transmite sobre el número de segundos de operación para cada unidad de control. La memoria EEPROM tiene un número limitado de ciclos de borrado de escritura, según el fabricante, 100,000 veces. La peor opción es cuando al menos una celda se actualiza constantemente. El tamaño del primer contador es de 4 bytes, este es un número de formato largo, 4 contadores, un total de 16 bytes ocupa un registro. La longitud de la memoria del chip es de 1024 bytes, después de 64 entradas de 4 contadores, la grabación comenzará nuevamente. En la biblioteca EEPROM, el método EEPROM.put no registra, si el valor de la celda y la información que se escribe coincide, no habrá degradación de las celdas. Como resultado, el tiempo de funcionamiento garantizado de la memoria será de más de 7 años. El tiempo de trabajo posible, pero injustificado puede ser mucho más largo.

Diagrama de circuito
imagen alt

Programa en Arduino IDE
// 12 328 bytes (38%)

#include <Adafruit_GFX.h> // Biblioteca de gráficos principales
#include <Adafruit_ST7735.h> // Biblioteca específica de hardware
#include <SPI.h>
#include <EEPROM.h>
#include <Wire.h>
#include <nRF24L01.h>
#include <RF24.h>
Radio RF24 (9, 10); // objeto de radio para trabajar con la biblioteca RF24,
// y números de pin nRF24L01 + (CE, CSN)
#include <DS3231.h>
DS3231 rtc (SDA, SCL);
Tiempo t;

// # define TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // también puedes conectar esto al reinicio de Arduino
// en cuyo caso, establece este #define pin en -1!
// # define TFT_DC 9 // DC = RS = A0- opciones para designar la salida de la elección del registro de comandos o datos.
#define TFT_DC 3

Adafruit_ST7735 tft = Adafruit_ST7735 (TFT_CS, TFT_DC, TFT_RST);

// Opción 2: ¡usa cualquier alfiler pero un poco más lento!
#define TFT_SCLK 13 // ¡configúrelos para que sean los pines que desee!
#define TFT_MOSI 11 // ¡configura estos para que sean los pines que quieras!
// Adafruit_ST7735 tft = Adafruit_ST7735 (TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#include <avr / wdt.h>

cambio de byte = 52;
byte pinState;
bomba larga sin signo [4]; // matriz con recuentos de 4 segundos
flotador m = 3600.0;
dirección int sin signo = 0;
int rc; // variable para contadores
sumprim largo sin signo = 0;
suma larga sin signo = 0;
byte i = 0;
byte k = 34;
unsigned int z = 0;
byte b = B00000001;
byte pumrcounter [4]; // matriz para almacenar los estados de los objetos, 1- off, 0- on
int inicio = 0; //

configuración nula () {

rtc.begin ();
radio.begin (); // Inicia la operación nRF24L01 +
radio.setChannel (120); // canal de transmisión de datos (de 0 a 127).
radio.setDataRate (RF24_250KBPS); // velocidad de transferencia de datos (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel (RF24_PA_MAX); // potencia del transmisor (RF24_PA_MIN = -18dBm, RF24_PA_LOW = -12dBm,
// RF24_PA_HIGH = -6dBm, RF24_PA_MAX = 0dBm)
radio.openWritingPipe (0xAABBCCDD11LL); // Abra la tubería con el identificador para la transferencia de datos.

// Para establecer la hora, descomente las líneas necesarias
//rtc.setDOW(1); // día de la semana
//rtc.setTime(21, 20, 0); // Hora, en formato de 24 horas.
//rtc.setDate(29, 10, 2018); // Fecha, 29 de octubre de 2018

tft.initR (INITR_BLACKTAB); // inicializa un chip ST7735S, pestaña negra
// Use este inicializador (descomentar) si está usando un TFT de 1.44 "
//tft.initR(INITR_144GREENTAB); // inicializa un chip ST7735S, pestaña RED rcB
tft.setTextWrap (falso); // Permitir que el texto salga del borde derecho
tft.setRotation (2); // para BLACK PCB y RED tft.setRotation (0) o no.
tft.fillScreen (ST7735_BLACK); // limpia la pantalla

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // trabajos de ajuste de software, alto nivel-
// los objetos monitoreados “no funcionan”, “1” se escribe en los 4 puertos principales de D, la cuenta no funciona.

para (rc = 0; rc <4; rc ++)
{
tft.setCursor (3, rc * 10 + shift); // muestra el número de posiciones de los objetos de control
tft.print (rc + 1);
}

tft.setCursor (12, 0); // genera 3 líneas de texto
tft.println ("DESARROLLADORES Y CONSTRUIR"); // alabar a tus seres queridos
tft.setCursor (24, 10); // o derechos de autor malvados
tft.print ("DESARROLLADOR MM");
tft.setCursor (28, 20);
tft.print ("BUILD-ER DD");

// recuperación de datos //////////////////////////////////////////////// ////////////

for (z = 0; z <1023; z + = 16) {// Itera en todas las celdas de su industria
// y escribe en la matriz de 4 variables bomba, 4 bytes cada contador, porque
// variable sin signo largo. Contadores 4, un registro de los 4 toma 16 bytes.
EEPROM.get (z, bomba [0]); // entonces, sin un bucle for, menos volumen
EEPROM.get (z + 4, bomba [1]);
EEPROM.get (z + 8, bomba [2]);
EEPROM.get (z + 12, bomba [3]);

// asignación de un nuevo valor siguiente de la suma de 4-x contadores
sumidero = (bomba [0] + bomba [1] + bomba [2] + bomba [3]);

// compara el nuevo valor de la suma de 4 contadores en la variable sumprim con el valor anterior en la variable
// sumsec y si la cantidad anterior es menor o igual que la nueva suma, se asigna una nueva mayor o igual
// valor sumsec.

if (sumsec <= sumprim) {
sumsec = sumprim; //

// y el valor actual z se asigna a la variable de dirección, z es la dirección del comienzo del bloque de 16 bytes de 4 valores
// contadores grabados al mismo tiempo (porque al sondear un puerto, todos sus 8 bits se graban simultáneamente
// incluyendo nuestros 4 bits deseados de puerto D).
dirección = z;
}
}

// Una vez más, el acceso a la memoria de epromprom en la dirección inicial del bloque es de 16 bytes a partir de 4 valores de los contadores registrados
// último, es decir valores antes de apagar o reiniciar debido a un bloqueo. Grabar último
// valores de contadores para una matriz de 4 variables bomba.

EEPROM.get (dirección, bomba [0]);
EEPROM.get (dirección + 4, bomba [1]);
EEPROM.get (dirección + 8, bomba [2]);
EEPROM.get (dirección + 12, bomba [3]);

dirección + = 16; // aumenta la dirección para escribir el siguiente bloque sin sobrescribir los datos del último registro

// fin de recuperación de datos ///////////////////////////////////////////// ///////////////////

attachInterrupt (0, count, RISING); // pin D2, habilita la operación de interrupción, cada segundo que llegan
// pulsos de RTC DS3231 de salida SQW

wdt_enable (WDTO_8S); // inicia el temporizador de vigilancia, reinicia el controlador en caso de bloqueo, tiempo,
// para el que necesita enviar el comando de reinicio del temporizador wdt_reset (y evitar reiniciar durante el funcionamiento normal - 8 segundos.
// para las pruebas, no se recomienda establecer el valor en menos de 8 segundos. En este caso, el temporizador se reinicia antes
// cavando, y cada segundo.

}

bucle vacío () {
// ciclo vacío, aquí habrá control sobre el modo de operación fuera de fase del motor eléctrico
}

cuenta vacía () {

tft.setTextColor (ST7735_WHITE); // establece el color de la fuente
t = rtc.getTime (); // tiempo de lectura
tft.setCursor (5, 120); // establecer la posición del cursor
tft.fillRect (5, 120, 50, 7, ST7735_BLACK); // área de salida de tiempo libre
tft.print (rtc.getTimeStr ()); // mostrar horas

wdt_reset (); // restablece el temporizador de vigilancia cada ciclo, es decir, un segundo

for (rc = 0; rc <4; rc ++) // inicio del ciclo para verificar el estado de la entrada
// bits de puerto al estado de lectura anterior de los bits de puerto D
{
pinState = (PIND >> 4) & (b << rc);

if (pumrcounter [rc]! = pinState) {// y si no coincide, entonces
pumrcounter [rc] = pinState; // asigna la variable de estado del bit de puerto al nuevo valor 1/0
}
// indicación del estado de los objetos de control de color
// BLUE es una pequeña falla de la pantalla existente (¿o biblioteca?), RGB y BGR se mezclan.
if (pinState == (b << rc)) {
tft.fillRect (15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // para cuentas de bajo nivel, cambie VERDE a AZUL
} más {
tft.fillRect (15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // para una cuenta de bajo nivel, cambie AZUL a VERDE
bomba [rc] + = 1; // agrega 1 segundo al contador de tiempo de ejecución
}
}

k ++;
si (k == 36) {
k es 0;

tft.fillRect (30, turno, 97, 40, ST7735_BLACK); // borra el área de salida del tiempo de ejecución
tft.fillRect (60, 120, 73, 7, ST7735_BLACK); // y fechas

tft.setCursor (60, 120); // establecer la posición del cursor
tft.print (rtc.getDateStr ()); // muestra la fecha en la pantalla LCD

for (rc = 0; rc <4; rc ++) // lecturas de tiempo de operación de salida en enteros, décimos y
{
tft.setCursor (30, rc * 10 + shift); // centésimas de hora con un desplazamiento de 10 píxeles hacia abajo en la pantalla
tft.println (bomba [rc] / m);
}

// registrar valores de tiempo de funcionamiento "en bruto" (en segundos) en EEPROM ////////////////////////////

para (rc = 0; rc <4; rc ++)
{
EEPROM.put (dirección, bomba [rc]);
dirección + = sizeof (flotante); // incrementa la variable de dirección de registro
}
}

// envía datos por aire desde datos que indican cuántos bytes enviar.
if ((k == 6) || (k == 18) || (k == 30)) {

datos largos sin firmar;

radio.write (& start, sizeof (start));

para (i = 0; i <4; i ++) {
datos = bomba [i];
radio.write (& data, sizeof (data));
}
}
}

Algunos comentarios al final. La cuenta va a un nivel lógico bajo en las entradas.
Resistencias de suspensión R2-R5 36 kOhm para la versión con fotoresistores GL5516. En el caso de optoacopladores y relés de fototransistor, suministre 4.7-5.1 kOhm. Arduino Nano v3.0 bootloader reemplazado con Arduino Uno usando el programador TL866A para la operación correcta de vigilancia. Los fusibles se corrigen para funcionar a voltajes superiores a 4,3 V. No se utilizó el circuito de reinicio externo R6 C3. En el programa de ejemplo, la frecuencia del transmisor no corresponde al rango sin licencia, el rango de 2.4 MHz está limitado a las frecuencias de 2400.0-2483.5 MHz.
El rango del transmisor del E01-ML01DP05 es de 2400-2525 MHz. El ancho de banda de un canal es de 1 MHz, cuando se configura la velocidad como "RF24_2MBPS", el canal radio.setChannel (120) especificado y el siguiente, es decir, estarán ocupados la banda será de 2 MHz.
Continuación

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


All Articles