Mensajes recientes

Páginas: 1 ... 3 4 [5] 6 7 ... 10
41
Kinco / Lectura de temperatura por ModBus RTU y copia al PLC por ModBus TCP (Ethernet)
« Último mensaje por Soporte julio 13, 2022, 12:48:23 pm »
Mostraremos a continuación cómo leer desde el HMI Kinco temperatura de sensores tipo termocupla conectados a un módulo RS-485 con protocolo ModBus RTU. Una vez leída la temperatura, desde el HMI ejecutaremos un macro que copiará la temperatura a registros ModBus TCP de un PLC conectado por Ethernet.

La ventaja de esta configuración, es que el PLC no necesita tener conexión RS-485 para obtener los valores de temperatura, ya que es el HMI quién los obtiene y transfiere al PLC utilizando una conexión Ethernet.

Una vez entendido este ejemplo, puede aplicarlo a cualquier dispositivo ModBus RTU que quiera acceder desde la pantalla HMI y además compartir sus valores por ModBus TCP a un PLC.

DIAGRAMA EN BLOQUES



PREPARAR LOS EQUIPOS

Para este ejemplo necesitará:

  • Pantalla HMI Kinco con puerto Ethernet y RS-485.
  • PLC con conexión ModBus TCP por Ethernet.
  • Módulo de temperatura TC8MB-K o similar, con conexión ModBus RTU por RS-485.
  • Fuente de 12 o 24 Vcc.

REALIZAR EL CONEXIONADO DE LOS EQUIPOS

En el siguiente link puede descargar en formato PDF el diagrama de conexión eléctrica y cableado de los equipos:

www.slicetex.com/hmi/kinco/files/examples/mb_temp_read/plc_wiring.pdf

CARGAR LOS PROYECTOS DE DE EJEMPLO AL HMI Y PLC

Para que el ejemplo funcione es necesario que cargue los proyectos de software en el HMI y en el PLC.
El proceso de carga se explica en sus respectivos manuales.

A continuación puede descargar los proyectos y abrirlos en el entorno de programación del HMI y el PLC respectivamente.

HMI:

El proyecto para la pantalla HMI Kinco lo puede descargar desde el siguiente link:

www.slicetex.com/hmi/kinco/files/examples/mb_temp_read/PLC_Temperature_Module1.zip

Nota[1]: Se utiliza el HMI modelo GL100E en el ejemplo, pero puede cambiar a otro modelo desde el entorno de programación.
Nota[2]: El proyecto del HMI se abre con Kinco DTools.

PLC:

Para el PLC, puede descargar el proyecto desde los siguientes links:

Lenguaje Ladder:

www.slicetex.com/hmi/kinco/files/examples/mb_temp_read/MbTempKincoLadder1.zip

Lenguaje Pawn:

www.slicetex.com/hmi/kinco/files/examples/mb_temp_read/MbTempKincoPawn1.zip

Nota[1]: Se utiliza el PLC modelo STX8140-A2-R en el ejemplo, pero puede cambiar a otro modelo desde el entorno de programación.
Nota[2]: Al abrir el proyecto del PLC, lea el archivo info.txt incluido, allí se explica en detalle el funcionamiento del programa del PLC.
Nota[3]: El proyecto del PLC se abre con StxLadder.

PRUEBA INICIAL

Una vez armado el cableado de los equipos (verificar dos veces) y cargado el software a la pantalla HMI y el PLC, puede energizar los equipos para hacer una prueba de funcionamiento.

En el HMI debería leer la temperatura reportada por todos los canales del módulo de temperatura en una pantalla similar a la siguiente:



Y en el PLC, utilice Virtual-HMI para ver las temperaturas recibidas en el PLC:



Note que si no hay sensor de temperatura conectado al módulo de temperatura, el valor leído será -100 °C. Si la temperatura parece ser errónea, es decir algunos grados de más o de menos, intente conectar en orden inverso los terminales de la termocupla, ya que pueden estar en la posición incorrecta.

Si la pantalla muestra "PLC no response", asegúrese haber cableado correctamente el módulo de temperatura por RS-485, y además que el PLC tenga la dirección IP 192.168.1.81, conectado directamente al HMI con un cable ethernet, o en una red LAN con direcciones de red IP compatible (192.168.1.xxx). Si necesita cambiar estas IP, debe reflejar dichos cambios en el proyecto del HMI.

MÓDULO DE TEMPERATURA

El módulo de temperatura utilizado en este ejemplo es el TC8MB-K, que admite conexión RS-485 (ModBus RTU) y tiene ocho entradas para sensores de temperatura tipo termocupla K.



Los registros ModBus RTU de esté módulo son los siguientes:





Note como la comunicación por defecto es: 9600 bps, 8N1 y dirección RTU = 1.

En la última tabla, cada canal de temperatura tiene la dirección: 32 para el número 1, 33 para el número 2, etc.
Sin embargo, en el HMI Kinco es necesario sumarle "1" a las direcciones ModBus RTU para este módulo.
Por lo tanto nos queda: 33 para el número 1, 34 para el número 2, etc.


Por otro lado, el valor de temperatura es un entero de 16-bits con signo multiplicado por 10. Es decir, el valor 200 corresponde a 20 °C.
Cuando no hay sensor conectado, el valor por defecto es -1000, es decir -100 °C.

Link a hoja de datos completa:

https://slicetex.com/modules/temperature/tc8mb-k/docs/TC8MB-K-DS.pdf

DETALLES DE FUNCIONAMIENTO DEL HMI

Para practicar ejemplos de comunicación ModBus TCP entre el HMI y el PLC, recomendamos bajar y practicar por separado los ejemplos disponibles en nuestra página de manuales de la pantalla Kinco, que puede accederla desde aquí.

A continuación mostraremos las particularidades a prestar atención en el proyecto del HMI para hacer funcionar este ejemplo.

Una vez abierto el proyecto de ejemplo desde el software Kinco DTools vamos a la estructura del proyecto al área de conexión, como muestra la siguiente imágen:



Aquí el PLC está conectado por ModBus TCP (Ethernet) y su conexión "Net" se llama "PLC_0_1", mientras que el módulo de temperatura está conectado por ModBus RTU (RS-485), y su conexión "COM0" se llama "PLC_1_1". Ambos nombres se utilizarán como referencia en el proyecto para conectarnos a uno u otro dispositivo.

En la misma figura, hacemos doble-click en el dibujo de la pantalla HMI para ingresar a sus atributos:



Una vez en los atributos del HMI, buscamos la solapa "COM0 Setting":



En está última ventana, especificamos los parámetros de comunicación del puerto COM0, ver áreas resaltadas en amarillo.
Elegimos los valores de conexión que requiere el módulo de temperatura conectado por RS-485 (ver más arriba), por lo tanto Type=RS485, Baud Rate=9600, Data Bit=8, Parity Check=none, Stop Bit=1.

El siguiente paso es mostrar desde la pantalla HMI el valor de temperatura del módulo, accediendo directamente a un registro del módulo. Para ello, vamos al "Frame0" del HMI en la sección de estructura del proyecto, y aparecerá la siguiente ventana:



Hacemos doble-click en el objeto "NI5", que es el primer componente numérico que se muestra.

Aparecerá la siguiente ventana:



Las partes coloreadas en amarillo son las importantes.

Como esté componente numérico lee un registro ModBus y muestra su valor, configuramos lo siguiente para que acceda el módulo de temperatura:

PLC No: Elegimos PLC_1_1 (que es la conexión RS-485 al módulo, ver más arriba)
Addr Type: 4X (esto indica "leer un registro ModBus)
Address: 33 (dirección del registro ModBus a leer, ver más arriba).

Luego, en la misma ventana, vamos a la solapa "Numeric Data":



Aquí "adaptamos" el valor leído del registro, ya que si recordamos, es un número de 16-bits con signo, y cuyo valor está multiplicado por 10. Entonces, seleccionamos:

Data type: signed int (entero con signo)
Data Width: WORD (16-bits)
Integer: 5 (solo nos interesan 5 digitos de parte entera)
Decimal: 1 (solo nos interesa 1 dígito de parte decimal, es decir, dónde poner el punto o lo que es lo mismo a dividir por 10).
Show Plus Sign: tildar (muestra el signo)
Min: -9999 (valor mínimo a mostrar, podemos colocar cualquiera para límitar el valor a mostrar)
Max: 9999 (valor máximo a mostrar, podemos colocar cualquiera para límitar el valor a mostrar)

Listo, le damos click a "OK" para cerrar la ventana y aplicar los cambios.

Todos los controles numéricos de este "Frame0" están configurados iguales, pero con una dirección "Address" de ModBus diferente, para que lea los ocho canales de temperatura.

Ya fue explicado como mostrar la temperatura leyendo directamente el módulo por ModBus RTU.

Ahora será necesario explicar cómo enviar los valores de temperatura leídos por ModBus RTU (RS-485) al PLC utilizando ModBus TCP (Ethernet).

Esto lo haremos utilizando MACROS en el HMI. Un macro es un pequeño código escrito con un listado de operaciones que puede llamarse como una función desde el HMI.

Este macro será el encargado de leer 8 registros por ModBus RTU (dirección 33 a 40) desde el módulo y escribirlos por ModBus TCP (dirección 40041 a 40048) al PLC.

Para agregar un macro al HMI vaya a menú "Option > Macrocode ...". Allí una ventana le pedirá un nombre para el macro.

Como en el ejemplo ya está creado el macro, vaya al árbol de la estructura del proyecto, busque "Macro File" y haga click sobre "copy_temperature_array.c", como se muestra a continuación:



En esta nueva ventana puede escribir el código del macro. Pero antes, explicaremos como declarar los parámetros utilizados como variables dentro del código del macro.



En la sección "Parameters" puede agregar una variable nueva haciendo click-izquierdo y seleccionando "Add variable".

En este ejemplo ya fueron agregadas dos variables tipo array: "MODULE_TEMP" y "PLC_TEMP".
Una variable se utilizará para leer los registros del módulo, y la otra para escribir los registros del PLC.

Haga doble-click sobre "MODULE_TEMP" aparecerá la siguiente ventana:



En las partes en amarillo se elige:
Data Type: unsigned short (entero de 16 bits sin signo, no utilizaremos signo aquí)
PLC No: PLC_1_1 (es la conexión ModBus RTU, RS485)
Address Type: 4x (para leer un registro ModBus)
Address: 33 (dirección del primer canal de temperatura)
Array Variable: Tildar, ya que declararemos un array de 8 elementos.
R/W: Read (operación de lectura)
Array Length: 8 (tamaño del array y cantidad de registros a solicitar).

Cerramos la ventana.

Ahora haga doble-click sobre "PLC_TEMP" aparecerá la siguiente ventana:



En las partes en amarillo se elige:
Data Type: unsigned short (entero de 16 bits sin signo, no utilizaremos signo aquí)
PLC No: PLC_0_1 (es la conexión ModBus TCP, Ethernet)
Address Type: 4x (para leer un registro ModBus)
Address: 40041 (dirección del primer registro a escribir en el PLC)
Array Variable: Tildar, ya que declararemos un array de 8 elementos.
R/W: Write (operación de escritura)
Array Length: 8 (tamaño del array y cantidad de registros a escribir).

Cerramos la ventana.

Una vez declaradas ambas variables, podemos utilizarla en el código del macro.

El código que utilizamos es el siguiente:

Código: (Kinco HMI Macro) [Seleccionar]
int MacroEntry()
{
int i;

/* Copiamos la temperatura desde los registros del módulo ModBus RTU (RS-485) a los registros del PLC ModBus TCP (Ethernet) */

for(i=0; i<8; i++)
{
PLC_TEMP[i] = MODULE_TEMP[i];
}

return 0;
}

El código es muy simple. En un ciclo "for" incrementamos la variable "i" desde 0 a 7.

En cada incremento copiamos el array MODULE_TEMP del módulo de temperatura al array PLC_TEMP del PLC. En otras palabras, leemos los registros ModBus RTU desde el módulo y los escribimos en los registros ModBus TCP del PLC.

Código: (Kinco HMI Macro) [Seleccionar]
PLC_TEMP[i] = MODULE_TEMP[i];
Finalmente queda ejecutar el macro copy_temperature_array.c en el HMI para que periódicamente envié los valores de temperatura al PLC. En el HMI hay varios métodos para ejecutar un macro (ver manual del HMI), por ejemplo utilizando un temporizador o mediante "PLC Control". Nosotros utilizaremos "PLC Control".

En "PLC Control" configuraremos el HMI para que constantemente lea el registro 40040 del PLC mediante ModBus TCP. Si el valor leído, ha cambiado, es decir, difiere de la última lectura, se ejecuta el macro copy_temperature_array.c, y por lo tanto el HMI obtiene la temperatura del módulo y la copia a los registros del PLC.

Con este método, debemos procurar en el PLC cambiar el valor del registro 40040  periódicamente (o cada vez que necesitemos) para que la temperatura copiada al PLC esté actualizada.

Entonces, vamos a menú "Components > PLC Control" y aparece la siguiente pantalla:



Si queremos agregar una nueva regla, tocamos en "Add". Pero como en el proyecto ya está agregada, tocamos con doble-click la única definida y se muestra la siguiente pantalla:



La parte en amarillo es la importante a prestar atención:

PLC No: PLC_0_1 (Seleccionamos la conexión ModBus TCP, Ethernet)
Addr. Type: 4X (para leer un registro ModBus)
Address: 40040 (dirección del registro en el PLC a leer)
Control Type: Execute Macro Program (ejecutar macro cuando se cumpla la condición)
Macro ID: copy_temperature_array.c (seleccionamos el macro que queremos ejecutar)
Execute Method: Word register value changed (cuando el registro 40040 cambie de valor, ejecutar el macro)

Salimos de la ventana.

Listo, ahora cuando el PLC cambié el el valor del registro 40040 el HMI buscará los valores de temperatura y los copiará al PLC.

Consejo: En el PLC podemos definir una variable entera e incrementarla constantemente, luego copiar dicha variable al registro 40040, y de esta manera cumplimos la condición que espera el HMI, ya que el registro 40040 tendrá un valor diferente constantemente. En los ejemplos de código para el PLC suministrado, hacemos esto.

Esto es todo, si necesita ejemplos básicos para utilizar el HMI con el PLC los puede encontrar en el siguiente link:

www.slicetex.com/hmi/kinco/docs.php#Examples

La nota de aplicación AN022 detalla como usar ModBus TCP con el PLC:

www.slicetex.com/docs/an/an022

Consúltenos si tiene dudas, éxitos  8)








42
STX8180 / Re:Creación de archivo bin de log con fecha en el nombre
« Último mensaje por Soporte julio 05, 2022, 20:00:39 pm »
Buenas tardes Miguel,

1. probamos sólo el archivo samplelog3B (con la modificación del nombre del archivo log con la fecha) y observamos que  no crea el nuevo archivo con la fecha siempre. Realizamos el log, por ejemplo hoy y todo ok, le adelantamos la hora al equipo para que cambie la fecha...nos esperamos unos instantes y hacemos un nuevo log  pero observamos que no aparece el nuevo archivo con la nueva fecha...no siempre lo hace  y cuando lo hace vamos adelantando la fecha y van apreciendo los archivos con la fecha nueva...

Cuando adelanta la hora, ¿lo hace con el log detenido?. Ya que en el ejemplo se crea el link al último log YYYYMMDD.bin  en "/web/loglist.htm" cuando se llama a la función SamplersStart(), y esta se llama cuando arranca el log. Si el log está en progreso, por más que cambie la hora, no se llama a la función y no añade el link. Pero si se generará el archivo de log YYYYMMDD.bin.

¿ Podrá verificar si el archivo con la fecha está en la memoria ?.

Es decir, ingresando al link directamente de la fecha en cuestión:

http://192.168.1.81/web/YYYYMMDD.bin

A lo mejor si se está creando el archivo de log en la tarjeta, pero no se está listando en la página web.

En ese caso, puede ser que en la función SamplersStart() no se está generando el link al log en el archivo "/web/loglist.htm".

Si se fija en el ejemplo en la línea:

Código: (Pawn) [Seleccionar]
if(DiskFileExist(File) == 0 || DiskFileExist("/web/loglist.htm") == 0)

La misma pregunta, si el archivo YYYYMMDD.bin no existe o el archivo "/web/loglist.htm" no existe, entonces, agregar un enlace.

Por lo que, solo si el archivo YYYYMMDD.bin no existe, se lista en la página web, ya que la idea es que agregue el link si es un log nuevo, para no repetir el enlace. Si el archivo existe, no se listará. Habría que modificar la lógica con alguna otra comprobación para que lo liste.

Lo mismo que si cambia la fecha durante el log, no se generará el enlace, porque no se llama a esta función.

Aviseme si es así.

...mañana quitaremos  la opción de sincronización a traves de la red, ¿puede ser esto algo que afecte a que el equipo tome la hora de la compu aunque modifiquemos la hora directamente?

Si, la actualización por red, puede interferir con la hora colocada manualmente, ya que si adelantan, se volverá a atrasar cuando sincronice con la red la fecha/hora. Pero pienso que es por lo anterior.

2. El equipo se va a dejar trabajando 5 dias (5 muestrasxseg) para unas pruebas con el usuario, por lo que 1ero lo pusimos a trabajar nosostros de esa manera el viernes 1 de julio  solo activando el log (el timeout lo comentamos // para que no tuviera efecto),  y el sabado vimos que sólo guardo lo del viernes hasta las 11:59:59 pm. Creemos que deberia poder guardar lo de los 5 dias en un sólo archivo o que en cada termino de día realice un corte y continue guardando datos en el siguiente nuevo archivo del siguiente dia.

Si son 5 días, con esa configuración debería crear un archivo por día.

¿Revisaste si están en la tarjera o solo viste si aparecen listados en la página web?.

Porque estimo que pasa lo que te comenté antes, al no llamar a SamplersStart(), cuando cambia de día, el nuevo archivo no añade a la lista en /web/loglist.htm.

Se retraso un poco las pruebas con ususario por otro tema pero al indicarnos que es lo que van hacer quisimos probarlo así. Hablando de la aplicación en un modo tendría sentido la prueba, pues si un temblor iniciara a las 11:59:40 pm (es algo remoto verdad) grabando por 30 segundos, deberia creo, continuar el resto delos 10 seg en los 1eros segundos del dia siguiente , ya sea en el mismo archivo o en uno nuevo.

Si, totalmente, debería crear dos archivos en esa configuración, que yo pienso que los está creando bien la función DiskLogAddArray() y registrando los datos, pero no se están listando al no llamar a SamplersStart() en cada cambio de día.

Fijate de corroborar eso y vemos como buscarle la vuelta para que los liste en la página al cambiar de día.

Saludos!
43
STX8180 / Re:Creación de archivo bin de log con fecha en el nombre
« Último mensaje por Miguel Gomez julio 04, 2022, 21:51:22 pm »
Gracias por el soporte acerca de como extraer en archivo csv, sin embargo aún no hemos hecho esta cambio o mejora, ya que nos detuvimos en lo siguiente, son 2 puntos:

1. probamos sólo el archivo samplelog3B (con la modificación del nombre del archivo log con la fecha) y observamos que  no crea el nuevo archivo con la fecha siempre. Realizamos el log, por ejemplo hoy y todo ok, le adelantamos la hora al equipo para que cambie la fecha...nos esperamos unos instantes y hacemos un nuevo log  pero observamos que no aparece el nuevo archivo con la nueva fecha...no siempre lo hace  y cuando lo hace vamos adelantando la fecha y van apreciendo los archivos con la fecha nueva...mañana quitaremos  la opción de sincronización a traves de la red, ¿puede ser esto algo que afecte a que el equipo tome la hora de la compu aunque modifiquemos la hora directamente?

2. El equipo se va a dejar trabajando 5 dias (5 muestrasxseg) para unas pruebas con el usuario, por lo que 1ero lo pusimos a trabajar nosostros de esa manera el viernes 1 de julio  solo activando el log (el timeout lo comentamos // para que no tuviera efecto),  y el sabado vimos que sólo guardo lo del viernes hasta las 11:59:59 pm. Creemos que deberia poder guardar lo de los 5 dias en un sólo archivo o que en cada termino de día realice un corte y continue guardando datos en el siguiente nuevo archivo del siguiente dia.

Se retraso un poco las pruebas con ususario por otro tema pero al indicarnos que es lo que van hacer quisimos probarlo así. Hablando de la aplicación en un modo tendría sentido la prueba, pues si un temblor iniciara a las 11:59:40 pm (es algo remoto verdad) grabando por 30 segundos, deberia creo, continuar el resto delos 10 seg en los 1eros segundos del dia siguiente , ya sea en el mismo archivo o en uno nuevo.

gracias por los consejos o correcciones
44
El ejemplo DiskSamplerLog1 vemos que imprime las muestras en formato csv pero en la paginaweb, no como archivo descargable. Queremos usar el DiskSamplerLog4 (por ser configurable) con la habilidad de escribir a un archivo descargable csv  ya que  las muestras  necesitadas ahora son de 5  veces por segundo.

Podrian ilustrarnos sobre como usar el DiskLogAddString, porque tenemos en la compilación un error en la última fila (el ultimo canal. Logrmos descargar archivo csv pero contenido en formato distinto, binario.

Buenos días Miguel,

Le paso el link al ejemplo DiskSamplerLog1 modificado para que tenga las opciones de DiskSamplerLog4 :

www.slicetex.com/docs/an/an036/files/examples/DiskSamplerLog1B.zip

Si bien, al ser algo tan genérico el ejemplo, es recomendable que en su proyecto lo optimice.

En este caso se ha modificado en función SamplersInit() de archivo Samplers.p para que los archivos del log tengan extensión CSV.

Código: (Pawn) [Seleccionar]
DiskLogInit(1, "vin", "csv", "/web", 36000, 500, DISKLOG_OPT_PPPPPXXX|DISKLOG_OPT_SEMICOLON|DISKLOG_OPT_CIRCULAR|DISKLOG_OPT_FAST_WRITE)

También, como le expliqué en otro ejemplo, puede modificarlo en este lugar para que tengan en el nombre de archivo la fecha YYYYMMDD.csv, si es necesario.

En el evento @OnVinBufFullA() se utiliza el código original del ejemplo DiskSamplerLog1, prácticamente sin cambios, siendo la parte fundamental DiskLogAddString() que escribe texto en el archivo CSV.

Código: (Pawn) [Seleccionar]
@OnVinBufFullA()
{   
   new TimeStart
   
   //
   // Guardar estampa de tiempo del inicio del evento.   
   //
   
   TimeStart = TimeGetMillis()   
   
   //
   // Copiar todas las muestras desde el buffer interno del "sampler" al array temporales.
   //
   // Nota: Las muestras de cada canal son colocadas en una dimensión del array por vez.
   // Como el array tiene dos dimensiones, utilizamos solo un índice para seleccionar el canal,
   // ver definición del array en Samplers.inc.
   //
   
   for(new Ch=0; Ch < SAMPLERS_CH; Ch++)
   {
      VinGetBuf(Ch+1, VinBuf[Ch], 0, SAMPLERS_BUF_SIZE)
   }
   
   //
   // Guardar todas las muestras VIN en la entrada del log de tarjeta Micro-SD.
   //
   
   for(new i=0; i < SAMPLERS_BUF_SIZE; i++)
   {         
      //
      // Atención: El siguiente códígo es para SAMPLERS_CH=5, si es diferente, debe adaptar la función
      // DiskLogAddString() para que tome más o menos argumentos de acuerdo a la cantidad de canales.
      //
     
      if(SAMPLERS_CH == 5)
      {
         // Agregar una entrada con formato de cadena de texto al canal 1 del DiskLog de la tarjeta Micro-SD.
         // Nota[1]: Separamos cada valor con ";" para que cumpla con el formato de archivo CSV.
         // Nota[2]: Los valores analógicos son "float" y llevan punto decimal. En Excel debe especificar si un número tiene "." o "," para el decimal.
         // Nota[3]: Puede convertir a voltaje con VinToVoltage() en una variable intermedia y luego aplicar la función MathScale() para converir a unidades de ingeniería.
         DiskLogAddString(1, "%f;%f;%f;%f;%f",  \
                             VinToVoltage(1, VinBuf[0][i], 12),     \
                             VinToVoltage(2, VinBuf[1][i], 12),     \
                             VinToVoltage(3, VinBuf[2][i], 12),     \
                             VinToVoltage(4, VinBuf[3][i], 12),     \
                             VinToVoltage(5, VinBuf[4][i], 12))
      }
      else
      {
         // Error!... Si SAMPLERS_CH es distinto a 5, debe adaptar este código
         // para que imprima en el archivo CSV más/menos canales.
         DiskLogAddString(1, "Adaptar codigo en @OnVinBufFullA!")
      }
   }
   
   //
   // Calcular tiempo insumido de procesamiento por el evento para mostrar en la página web.
   //
   
   SamplerEventTimeMS = TimeGetMillis() - TimeStart
}


Notar como la función DiskLogAddString() se encarga de imprimir las muestras al archivo de texto en formato CSV:

Código: (Pawn) [Seleccionar]
         DiskLogAddString(1, "%f;%f;%f;%f;%f",  \
                             VinToVoltage(1, VinBuf[0][i], 12),     \
                             VinToVoltage(2, VinBuf[1][i], 12),     \
                             VinToVoltage(3, VinBuf[2][i], 12),     \
                             VinToVoltage(4, VinBuf[3][i], 12),     \
                             VinToVoltage(5, VinBuf[4][i], 12))

Es lo logra con la cadena de formato "%f;%f;%f;%f;%f", donde cada código %f indica que debe remplazarse por un valor float del argumento variable de la función. Colocamos punto y coma ";" como separador, ya que así es el formato CSV.

Por ejemplo, el primer código %f corresponde a VinToVoltage(1, VinBuf[ 0 ][ i ], 12), que convierte a voltaje la muestra almacenada en el array VinBuf[][] del canal 1 a voltaje (ver manual). Ya que las muestras almacenadas por los SAMPLER están en formato binario, por lo que primero se convierten a voltaje y luego lo imprimimos a texto.

También puede colocar el valor de voltaje en una variable intermedia, por ejemplo, en el array Voltage[] y luego imprimir con DiskLogAddString():

Código: (Pawn) [Seleccionar]

new Float: Voltage[6]

Voltage[1] = VinToVoltage(1, VinBuf[0][i], 12)
Voltage[2] = VinToVoltage(2, VinBuf[0][i], 12)
Voltage[3] = VinToVoltage(3, VinBuf[0][i], 12)
Voltage[4] = VinToVoltage(4, VinBuf[0][i], 12)
Voltage[5] = VinToVoltage(5, VinBuf[0][i], 12)

DiskLogAddString(1, "%f;%f;%f;%f;%f",  Voltage[1] , Voltage[2] , Voltage[3], Voltage[4], Voltage[5])

Entonces, si quiere convertir a unidades de ingeniería, puede utilizar la función MathScale(InValue, InMin, InMax, OutMin, OutMax) de forma simple. Esta función, escala el valor InValue entre los límites InMin e InMax a los valores OutMin y OutMax.

Por ejemplo, supongamos que 0V representan 10 °C, mientras que 5V representan 85 °C, hacemos:

MathScale(InValue, 0, 5, 10, 85)

Cualquier valor de InValue entre 0 y 5 será escalado proporcionalmente entre 10 y 85.

Si fuera corriente, por ejemplo supongamos que 4 mA representan 10 °C, mientras que 20 mA representan 85 °C, hacemos:

MathScale(InValue, 4, 20, 10, 85)

Cualquier valor de InValue entre 4 y 20 será escalado proporcionalmente entre 10 y 85.

Entonces, yendo a DiskLogAddString(), podemos remplazar como:

Código: (Pawn) [Seleccionar]

new Float: Sensors[6]

Sensors[1] = MathScale(VinToVoltage(1, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[2] = MathScale(VinToVoltage(2, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[3] = MathScale(VinToVoltage(3, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[4] = MathScale(VinToVoltage(4, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[5] = MathScale(VinToVoltage(5, VinBuf[0][i], 12), 0, 5, 10, 85)

DiskLogAddString(1, "%f;%f;%f;%f;%f",  Sensors[1] , Sensors[2] , Sensors[3], Sensors[4], Sensors[5])

Obviamete, si son 6 canales, debés agregar una %f más al código de formato:

Código: (Pawn) [Seleccionar]
DiskLogAddString(1, "%f;%f;%f;%f;%f;%f",  Sensors[1] , Sensors[2] , Sensors[3], Sensors[4], Sensors[5], Sensors[6])

Es cuestión de que lo dejes optimizado y prolijo para tu proyecto específico.

Los códigos de formato admisibles para DiskLogAddString() son los mismos que para la función nLcdPrintf(), por ejemplo %f para float, y %d para enteros, podés ver una explicación de lo códigos en el Manual de Programación, buscar nLcdPrintf(), sección 9.2.

Saludos!

45
Hola que tal.
El ejemplo disksampler1 vemos que imprime las muestras en formato csv pero en la paginaweb, no como archivo descargable. Queremos usar el disksampler4 (por ser configurable) con la habilidad de escribir a un archivo descargable csv   ya que  las muestras  necesitadas ahora son de 5  veces por segundo.

Podrian ilustrarnos sobre como usar el disklogaddstring, porque tenemos en la compilación un error en la última fila (el ultimo canal. Logrmos descargar archivo csv pero contenido en formato distinto, binario.

gracias
46
Kinco / Re:Que no muestre "PLC No Response"
« Último mensaje por Soporte junio 30, 2022, 10:44:25 am »
Buenos días.

No, no se puede deshabilitar la notificación de errores.

Al menos no aparece ninguna opción en el software ni en el manual para hacerlo.

Solo se puede cambiar el contenido del mensaje de error o aumentar el tiempo de espera antes de mostrar el error.

Quizás, lo que podés hacer, es mostrar la información de cada PLC en ventanas separadas. Si mal no recuerdo, el HMI solo corrobora la conexión de los elementos de la ventana que está activa o mostrándose en el momento.

Saludos!
47
Kinco / Que no muestre "PLC No Response"
« Último mensaje por Jose junio 29, 2022, 14:30:26 pm »
Hola y gracias de antemano, el tema es que tengo conectada la HMI kinco a dos PLCs, uno al COM0 y el otro al COM1 pero no siempre están los dos PLCs encendidos, y si conecto solo uno me sale el mensaje de PLC 2 no response.
Quería saber si se puede deshabilitar esta función
Gracias
48
STX8180 / Re:Log combinado de entrada analógica voltaje y corriente
« Último mensaje por Soporte junio 28, 2022, 21:07:49 pm »
Puede combinarse en un log las muetras de digamos 4 canales VIO como entrada 4-20 y 3 como entrada de voltaje? es decir, conociendo que los canales del 1 al 4 serán usados en corriente y del 5 al 7 como voltaje.

Buenas tardes Miguel.

Si, puede combinarse en este caso.

En el ejemplo mencionado, DiskSamplerLog4, se configura por defecto los canales VIO como entradas de voltaje.

Pero esto no impide, que los canales VIO1:4 se configuren como entradas de corriente 4-20 mA (CIN), y los canales VIO5:7 sea entradas de voltaje (VIN). Esto lo hacés en la función SamplersInit() del ejemplo.

Entonces, podés remplazar:

Código: (Pawn) [Seleccionar]
   for(new Ch=1; Ch <= SAMPLERS_CH; Ch++)
   {
      VioInitVin(Ch, VIO_TYPE_VIN_SINGLE, VIO_VIN_RANGE_N5V_5V, VIO_VIN_SAMPLES_NONE)
   }

Por:

Código: (Pawn) [Seleccionar]

      // Configurar canales VIO1:4 como entradas analógicas CIN de corriente 4-20 mA.
      VioInitCin(1, VIO_TYPE_CIN, VIO_CIN_RANGE_DEFAULT, VIO_CIN_SAMPLES_NONE)
      VioInitCin(2, VIO_TYPE_CIN, VIO_CIN_RANGE_DEFAULT, VIO_CIN_SAMPLES_NONE)
      VioInitCin(3, VIO_TYPE_CIN, VIO_CIN_RANGE_DEFAULT, VIO_CIN_SAMPLES_NONE)
      VioInitCin(4, VIO_TYPE_CIN, VIO_CIN_RANGE_DEFAULT, VIO_CIN_SAMPLES_NONE)

      // Configurar canales VIO5:7 como entradas analógicas VIN de voltaje simple.
      VioInitVin(5, VIO_TYPE_VIN_SINGLE, VIO_VIN_RANGE_N5V_5V, VIO_VIN_SAMPLES_NONE)
      VioInitVin(6, VIO_TYPE_VIN_SINGLE, VIO_VIN_RANGE_N5V_5V, VIO_VIN_SAMPLES_NONE)
      VioInitVin(7, VIO_TYPE_VIN_SINGLE, VIO_VIN_RANGE_N5V_5V, VIO_VIN_SAMPLES_NONE)


Nota: Recordar luego desde la página Web del ejemplo, especificar muestrear 7 canales analógicos.

Como el ejemplo utiliza los "SAMPLERS" para muestrar a una tasa fija, lo que lee es voltaje, y eso es lo que se graba en el archivo binario, independiente de como esté configurado el canal VIO.

Por ello, luego en la aplicación de Visual C# cuando hacés el procesamiento de datos, al obtener el voltaje de los canales VIO1:4 (que son de corriente de acuerdo al PLC), debés dividir el valor de voltaje por "84.1945", que es la resistencia en Ohms utilizada para la medición de corriente internamente (ver figura 85, página 110 en la hoja de datos, allí se muestra el resistor "Rcs" utilizado cuando se configura como entrada de corriente tipo CIN).

Resumiendo, en C# para los canales VIO1:4, hacés la siguiente división:

Voltaje / 84.1945 = Corriente en amperes

Notar que la corriente resultante está en amperes, si la querés en mili-amperes, para que se represente mejor, debés multiplicar por 1000.

(Voltaje / 84.1945) * 1000 = Corriente en mili-amperes

Y ese nuevo valor, es el que podés colocar en el archivo CSV o escalarlo a unidades de ingeniería.

Para los canales VIO5:7 no le aplicás la conversión a corriente, ya que son voltaje.

Eso es todo, avísame si lo podés realizar o no se entiende algo.

Saludos!

Atención: Al utilizar canales VIO como entradas de corriente 4-20 mA (CIN), no aplicar voltajes directos mayores a +/- 4.21 V al terminal VIO, ya que puede generar excesiva corriente y dañar la entrada (por el resistor que se activa internamente). Se recomienda leer hoja de datos para conexionado con sensores de 4-20 mA, sección 11.25.7, página 110. Si hay dudas, consulte.
49
STX8180 / Log combinado con entrada analógica de voltaje y corriente
« Último mensaje por Miguel Gomez junio 28, 2022, 18:18:26 pm »
Hola que tal,
Puede combinarse en un log las muetras de digamos 4 canales VIO como entrada 4-20 y 3 como entrada de voltaje? es decir, conociendo que los canales del 1 al 4 serán usados en corriente y del 5 al 7 como voltaje, hemos visto con ejemplos las funciones para setear como 4-20, pero para combinar en un log, el ejemplo disklog4  supone en voltaje  todos los canales que se requieran muestrear. Tienes ejemplo al respecto? 


saludos y gracias por comentarios.
50
STX8180 / Re:Establecer voltaje en salida analógica
« Último mensaje por Soporte junio 24, 2022, 20:06:28 pm »
Nuevamente. Implemente el siguiente script  y funciona bien a nivel VirtualHMI..pero no veo voltaje en la salida VOUT1, leí por ahí que hay un jumper, esto es así para el STX8081? para poder ver voltaje de 1 a 5 V en el canal. Intentamos otras funciones que vienen en el manual pero de igual forma no vemos la tensión que queremos.

Hola Miguel.

Los canales VIO tienen función múltiple, pueden ser entradas o salidas de diversos tipos, por lo tanto, antes hay configurarlos por software.

En el caso del modelo STX8180 no hace falta manipular ningún jumper.

Para que un canal VIO sea salida de voltaje (no corriente, eso es una función diferente) de 0 a 10V, lo podés configurar con la siguiente función antes de utilizarlo:

Código: (Pawn) [Seleccionar]
   
   // Canal VIO1: Salida de voltage, alias VOUT1.
   // Rango: 0 a 10V.
   // Voltaje inicial: 0V
   
   VioInitVout(1, VIO_TYPE_VOUT, VIO_VOUT_RANGE_0V_10V, 0)

La constante VIO_VOUT_RANGE_0V_10V indica rango 0 a 10V.
Mientras que el primer argumento es el número de canal VIO (en este caso 1) y el último argumento es el voltaje inicial (en este caso 0V).
Los canales VIO que pueden ser salida de voltaje son todos, desde VIO1 a VIO11.

Las constantes para rango válidos son:

Código: (Pawn) [Seleccionar]
VIO_VOUT_RANGE_0V_10V      // Output range: 0V to 10V
VIO_VOUT_RANGE_N5V_5V      // Output range: +/-5V
VIO_VOUT_RANGE_N10V_0V    // Output range: -10V to 0V

Luego de inicializar el canal VIO como salida analógica de voltaje VOUT, podés utilizar la función VoutWriteVolt() para escribir o establecer el voltaje de salida. Por ejemplo:

Código: (Pawn) [Seleccionar]
//
// Escribir salida analógica número 1 (VOUT1) con voltaje de 5.5V.
//

VoutWriteVolt(1, 5.5)

Notar que el voltaje pasado a la función (en este caso 5.5) debe estar dentro del rango de voltaje, sino, se recorta el voltaje al límite.

Para medir este voltaje con el voltímetro, debés hacerlo entre el canal VIO seleccionado y el terminal A1G (masa analógica).

En la página de ejemplos del modelo STX8180 hay ejemplos para las salidas analógicas, buscar "Escribir salidas analógicas de voltaje (VOUT)" en la página de ejemplo, lo podés encontrar en el siguiente link:

www.slicetex.com/hw/stx8180/examples.php

El ejemplo que pasaste, también esta disponible adaptado para el modelo STX8180 en la página mencionada, el link directo es:

www.slicetex.com/hw/stx8180/examples/VoutPawn1.zip

Este ejemplo, utiliza el canal VIO5 en vez del VIO1, pero podés modificarlo fácilmente cambiando el número de canal 5 por 1.

Saludos y buen fin de semana!





Páginas: 1 ... 3 4 [5] 6 7 ... 10