Mensajes recientes

Páginas: [1] 2 3 ... 10
1
Kinco / Re:Trend curve
« Último mensaje por camarasajm Hoy a las 10:45:07 »
Estoy usando una Pantalla Hmi - Kinco 10'' Touch Mt4532te y me comunico mediante modbus a un equipo remoto mediante el protocolo.
Me puedo comunicar bien con los datos, solo quiero que se generar el movimiento de la barra de datos del historia.

Adjunto programa.
2
Kinco / Re:Trend curve
« Último mensaje por Soporte junio 11, 2018, 10:44:30 am »
Buenos Tardas, mi consulta es sobre la manera correcta de realizar un gráfico de curva "TREND CURVE".. no puedo hacer que se desplace la barra para datos anteriores y hacer el zoom sobre ellos.

estoy tratando de realizar el modelo de ejemplo.

Buenos días,

¿Qué modelo de HMI y PLC estás utilizando?

¿El componente "Trend curve" de la sección 4.6.1 del manual estas intentando utilizar? ¿Cuál ejemplo?.

Saludos

3
Buenos días Marcos,

En el caso de usar StrFormat con las cadenas "packed" es necesario poner la sentencia "true" en el tercer parámetro, correcto?

Si queres que la cadena resultante sea "packed", utilizar "true". Caso contrario, la salida será "unpacked" independiente del formato de la cadena de entrada.

¿Cuál es el resultado de usar la función de la siguiente manera?

StrFormat(errorMsg[1], DISPLAY_LENGTH, false, !"Falla al inicializar ModBus.")

En este caso, con parámetro "false", en la cadena resultante de salida en errorMsg[1][] vas tener la cadena "Falla al inicializar ModBus.", pero en formato "unpacked".

Es decir, seria lo mismo que hacer:

Código: (Pawn) [Seleccionar]
new errorMsg_Unpacked[] = "Falla al inicializar ModBus."  // Unpacked
Con parámetro "true" la salida seria equivalente a:

Código: (Pawn) [Seleccionar]
new errorMsg_Packed[] = !"Falla al inicializar ModBus."  // Packed
La diferencia esta que el array "errorMsg_Unpacked[]" ocupa 29 celdas *4 = 116 bytes, mientras que errorMsg_Packed[] ocupa 8 celdas * 4 = 32 bytes.



Solo para entender:

Para acceder a cada caracter de errorMsg_Unpacked[] (en el caso que quieras hacerlo), indexas normalmente, ejemplo:

Código: (Pawn) [Seleccionar]
nLcdPrintf(0, 1, LCD_CLRLINE, ""%c %c %c %c %c", errorMsg_Unpacked[0], errorMsg_Unpacked[1],errorMsg_Unpacked[2],errorMsg_Unpacked[3],errorMsg_Unpacked[4])
Imprime "F a l l a"

En el caso de un "packed" string, se agrupan 4 carácter por celda, estando el primer carácter de 8-bit, en la posición más alta. Por lo tanto hay que "desempaquetarlo" para obtener caracter por caracter.

Para ello usamos GetCellChar(cell, char_num), donde "cell" es el entero donde esta el carácter y char_num el número de caracter a obtener (del 0 al 3).

Ejemplo:

Código: (Pawn) [Seleccionar]
nLcdPrintf(0, 1, LCD_CLRLINE, ""%c %c %c %c %c", GetCellChar(errorMsg_Packed[0], 0), GetCellChar(errorMsg_Packed[0], 1),GetCellChar(errorMsg_Packed[0], 2),GetCellChar(errorMsg_Packed[0], 3),GetCellChar(errorMsg_Packed[1], 0))
Imprime "F a l l a"

Saludos!

4
Kinco / Trend curve
« Último mensaje por camarasajm junio 09, 2018, 20:30:04 pm »
Buenos Tardas, mi consulta es sobre la manera correcta de realizar un gráfico de curva "TREND CURVE".. no puedo hacer que se desplace la barra para datos anteriores y hacer el zoom sobre ellos.

estoy tratando de realizar el modelo de ejemplo.



Saludos, Juan
5
Hola Boris,
Excelente, ahora tiene sentido lo extraño que era el error.
Voy a implementar los consejos que escribiste para ahorrar memoria RAM. Me quedo una sola duda respecto a el empaquetamiento de strings
En el caso de usar StrFormat con las cadenas "packed" es necesario poner la sentencia "true" en el tercer parámetro, correcto?
¿Cuál es el resultado de usar la función de la siguiente manera?
StrFormat(errorMsg[1], DISPLAY_LENGTH, false, !"Falla al inicializar ModBus.")

Muchas gracias.
6
Buenas tardes Marcos,

Te paso a detallar las causas del problema y como solucionarlo.

CAUSAS

Luego de analizar el proyecto completo que enviaste por email, encontré que el mismo "colgaba" el PLC en el mismo instante que se transfería el código desde StxLadder a la memoria del PLC, sin ejecutar instrucción alguna de tu código.

Por lo tanto, el problema no es de error de código o de alguna función como StrFormat() que producía misteriosamente cierta interacción de acuerdo a si se comentaba o no.

El problema es de memoria RAM, en este caso, el proyecto utilizaba más memoria RAM que la que tiene asignada el dispositivo para código de usuario, por lo tanto, cuando se cargaba al PLC, interfería con el sistema operativo interno, escribiendo su área de memoria, lo cual generaba fallas aleatorias, de acuerdo a si el proyecto utilizaba más o menos RAM (por ello cuando comentabas, a veces funcionaba y otras no).

El "culpable" fue StxLadder que comprobaba erróneamente la cantidad de RAM utilizada por el proyecto y no te daba advertencia alguna de que estabas superando los limites del modelo de dispositivo que tenés.

SOLUCIÓN

Esto se solucionó en la última versión de StxLadder, la versión 1.9.0 que liberé hoy.

Te recomiendo instalarla.

Esta versión te muestra al compilar en detalle cuanta memoria ROM y RAM utilizas en el proyecto, y cuanto te queda disponible. También, si te excedes, te da un error de compilación para que bajes el consumo.

Por otro lado, también se mejoró el firmware del PLC, que también comprueba previamente si el programa que va a ejecutar no excede sus limites de RAM / ROM. Es decir, un doble-check, entre StxLadder y el PLC. Aumentando la seguridad, y evitando "colgarse" si el programa es inválido, solo prenderia el led RUN ERROR, pero no perderías conectividad (como te pasaba).

La versión de firmware que debés bajar es la 211 o superior para tu modelo de PLC:

http://slicetex.com/hw/stx8091/soft.php#Firmware

APLICACIÓN A TU PROYECTO

Una vez que instales StxLadder versión 1.9.0 y actualices el firmware del PLC a la versión 211, abrí tu proyecto.

Si es el mismo que me pasaste a mí, al compilar deberías ver el siguiente mensaje de error:

Cita de: StxLadder 1.9.0
Error de Memoria: Insuficiente memoria RAM: El proyecto requiere 23268 bytes y el dispositivo tiene disponible 16384 bytes. Disminuya variables globales, variables locales inicializadas, comparta/reutilice variables globales, utilice packed strings, agrupe datos, etc

El mensaje dice que utilizas 23268 bytes de memoria RAM, pero el dispositivo tiene 16384 (16KB).

En el PLC tenés dos memorias, RAM (donde van las variables lectura/escritura) y la ROM (donde van las instrucciones de código para ejecutar la lógica o datos de solo lectura).

La RAM es más pequeña que la ROM, por lo tanto hay que tener más cuidado en definir grandes cantidades de variables, que en escribir código.

El compilador Pawn, considera a los string literales o constantes string como variables que van en RAM, por lo tanto cuando escribís "Falla al inicializar ModBus." en StrFormat(), se coloca en memoria RAM dicha cadena, ocupándote lugar:

Código: (Pawn) [Seleccionar]
StrFormat(errorMsg[1], DISPLAY_LENGTH, false, "Falla al inicializar ModBus.")
La cadena "Falla al inicializar ModBus." tiene 26 caracteres más un terminador "0", en total ocupa 27 posiciones. En Pawn, las cadenas son arrays de enteros, por lo tanto cada posición tiene 4 bytes.

La memoria RAM consumida por esa cadena es de: 27*4=108 bytes.

Es bastante, y más si utilizas muchísimas cadenas en tu código, a la larga ocupas toda la memoria RAM.

Un truco para que una cadena literal (constante) no utilice tanta memoria RAM es haciéndola "packed", en ese caso, el compilador agrupa en cada posición 4 caracteres. Esto se especifica con el operador " ! " antes de una cadena, por ejemplo:

Código: (Pawn) [Seleccionar]
StrFormat(errorMsg[1], DISPLAY_LENGTH, true, !"Falla al inicializar ModBus.")
Ahora la cadena de 27 caracteres ocupa 27 bytes, una reducción importante.

Notar como el tercer parámetro de StrFormat() es "true", indicando que la cadena resultante en errorMsg[] va a ser packed también.

Como la cadena resultante es "packed", podes definir a errorMsg[]  con un tamaño en "celdas" 4 veces menor.

Otro ejemplo:

Código: (Pawn) [Seleccionar]
new String1[] = !"Falla al inicializar ModBus."
Esto solo funciona con cadenas, pero para variables enteras o flotantes, arrays, etc, cada vez que definís uno de forma global o del tipo estático (inicializado dentro de una función), te ocupa 4 bytes de memoria RAM. Por lo tanto, también, usar a discreción e intentar ahorrar lo más que pueda.

LUEGO VOY A PUBLICAR UN POST CON TRUCOS Y CONSEJOS PARA DISMINUIR MEMORIA RAM

Volviendo a tu proyecto, una forma de considerar a todas las cadenas como "packed" por defecto, es utilizando la opción "Packed literal strings" antes de compilar como muestra la siguiente imagen:



Se encuentra en menú "Proyecto > Propiedades > Compilador (pestaña)".

Ahora si volvés a compilar te va a mostrar "Compilación correcta":



Notar como en los mensajes ahora el total de RAM requerida es "10348" bytes, respecto a los "23268" bytes de antes.

Una reducción importante logra la opción Packed literal strings, que considera a todas tus cadenas literales como packed, tal como si le hubieras aplicado el símbolo " ! " a cada una.

Cuando esta opción esta activada, si antepones el símbolo " ! " a la cadena, genera el comportamiento inverso, se transforma en unpacked y ocupa 1 carácter por celda.



Si bien utilizar la opción Packed literal strings ya te permite liberar RAM necesaria para que el proyecto se pueda cargar, te recomiendo no utilizar tantas cadenas, así tenes RAM disponible para futuro uso cuando el proyecto crezca con nuevas funciones o código que le agregues.

En todo caso, hacé las cadenas menos descriptivas, utilizá códigos de error para hacerlas más cortas en extensión, etc.

Por otro lado, al usar el argumento "true" en StrFormat(), te habilita a que puedas reducir el tamaño del array:

Código: (Pawn) [Seleccionar]
new errorMsg[8][DISPLAY_LENGTH+5]
Que si lo analizás, tiene 8*(DISPLAY_LENGTH+5) celdas. Si DISPLAY_LENGTH=34, la cantidad de celdas utilizadas es:

312 celdas = 1248 bytes (bastante)

Si el string que vas a almacenar es "packed" con StrFormat() podrías reducir DISPLAY_LENGTH a 10, para almacenar 39+1 caracteres por linea:

Código: (Pawn) [Seleccionar]
#define DISPLAY_LENGTH 10
new errorMsg[8][DISPLAY_LENGTH]

Ahora, el total seria: 80*4 = 320 (bytes)

Podes ir probando reduciendo código o diferentes alternativas con variables, compilar y ver que opción te genera menos consumo de RAM, hasta que logres un equilibrio.

En el detalle de compilación, donde dice "Data block 6252 bytes", esa es la RAM usada por variables globales, strings, etc.

Luego haré un post resumiendo y explicando mejor como ahorrar RAM, pero esto es lo fundamental.

Saludos!
7
STX8081 / Ejemplo display LCD para I2C y memoria EEPROM
« Último mensaje por Soporte junio 07, 2018, 12:13:50 pm »
Para aquellos que utilizan el display LCD a través de I2C (puerto HP2/HP3), ver siguiente post del foro:

foro.slicetex.com/index.php?topic=269.msg1432#msg1432

Adjuntamos en esta oportunidad el mismo ejemplo, pero que también escribe y lee datos de memoria EEPROM.

Cabe mencionar que las funciones para la memoria EEPROM están descriptas en el Manual de Programación Pawn del PLC.

Ver proyecto adjunto.

Saludos!
8
A continuación adjuntamos el ejemplo "MbTcpServerCountOut.zip" para el PLC que a diferencia del ejemplo "MbTcpServerCounter.zip" conmuta una salida a transistor cada vez que el registro ModBus 40001 es puesto a 0.

Requiere un PLC con salida PWM o transistor rápida.

Esto permite medir tiempos mediante un osciloscopio o analizador lógico en la salida.

Capturas tomadas en salida digital (la duración de cada pulso  alto o bajo es el tiempo entre escritura lectura):





Log tomado desde aplicación Visual C# (sin relación a capturas previas):

Código: (log.txt) [Seleccionar]
Response: 915 ms
Response: 934 ms
Response: 20 ms
Response: 30 ms
Response: 76 ms
Response: 97 ms
Response: 139 ms
Response: 161 ms
Response: 21 ms
Response: 31 ms
Response: 84 ms
Response: 95 ms
Response: 140 ms
Response: 161 ms
Response: 205 ms
Response: 218 ms
Response: 271 ms
Response: 282 ms
Response: 327 ms
Response: 347 ms
Response: 389 ms
Response: 411 ms
Response: 458 ms
Response: 469 ms
Response: 522 ms
Response: 532 ms
Response: 10 ms
Response: 31 ms
Response: 9 ms
Response: 24 ms
Response: 76 ms
Response: 86 ms
Response: 133 ms
Response: 154 ms
Response: 10 ms
Response: 30 ms
Response: 20 ms
Response: 31 ms
Response: 79 ms
Response: 89 ms
Response: 141 ms
Response: 152 ms
Response: 205 ms
Response: 217 ms
Response: 21 ms
Response: 32 ms
Response: 13 ms
Response: 33 ms
Response: 76 ms
Response: 97 ms
Response: 142 ms

9
Kinco / Re:Tiempo de actualización de elementos
« Último mensaje por Soporte junio 04, 2018, 13:21:01 pm »
Buenos días Francisco,

Estuve probando el HMI con tu diseño, y presentaba el problema que describís.

Como no encontré error alguno en el HMI, luego de algunas horas de pruebas, decidí recrear el proyecto desde cero y funcionó perfecto.

Ahora, yo utilicé el el HMIware 2.4 para el diseño, cuando lo abrí con la nueva versión que utilizás en tu proyecto, HMIware 2.5 presentó el mismo problema. Cosa de no creer.

Aparentemente cuando abrís un proyecto creado en versión 2.4 desde el software versión 2.5, pasa esto.

No tuve tiempo para hacer un proyecto desde cero utilizando HMIware 2.5 para ver si así funciona bien.



Pasos a seguir:

Para no dilatar más, te recomiendo desinstalar la versión 2.5 e instalar la versión 2.4 del soft para el HMI en tu PC. En el CD de instalación del paquete de venta esta dicha versión, sino avísame y te comparto algún link de descarga.

Luego abrí el proyecto "HMI_SlicetexTankTest_V1.zip" que te adjunto y probalo, es un "clon" de tu diseño, pero más rustico. Lo único que le falta es actualizar los gráficos y animaciones de los tanques.

Si te funciona bien, seguí utilizando la versión 2.4 del software, ya que no hay forma de abrir un proyecto creado con 2.5 en la versión 2.4 (pero sí al revés, que es lo que no funciona, quizás algo hace mal el soft al actualizar diferentes versiones en proyectos creados con versiones previas).

Seguramente tu diseño, lo basaste en algún diseño de ejemplo de la página, y como fueron creados con versión 2.4, se trasladó el problema. No sé si creando desde cero en 2.5, esto se soluciona, cosa de locos.



Por otro lado, revisando tu código en el PLC, noto que en la Network N026, N027 y N028 escribís en la EEPROM en cada Scan Cycle. Esto no es recomendado, porque agotás la vida útil de la EEPROM con miles de escrituras por segundos, y además crea un retardo de decenas de milisegundos en el Scan Cycle, ya que la EEPROM tiene un tiempo de escritura.

Para evitar esto, te adjunto el proyecto "PLC_TanquesSlicetex_Version_1.zip" para el PLC, que desactiva estos componentes (borralos luego) y en su lugar llama al diagrama "WriteEeprom" cada diez segundos, para guardar los últimos valores, de tal forma de evitar escribir permanentemente en EEPROM.



Me habías comentado de un defasaje de tiempo, el tema de la EEPROM puede ser una causa, pero también, como los segundos/contadores los incrementas desde Principal.sld, y a su vez antes/luego de cada incremento tenes bastante código, esto genera que el procesador pierda tiempo ejecutando componentes antes de incrementar contadores. Este pequeño delay (producido pro ejecutar muchas cosas antes en el Scan Cycle) a la larga puede introducirte el error de tiempo que observás.

Lo ideal seria que trates de agrupar código en fuciones Ladder, y solo llamarlas si es necesario, o con Temporizadores Ladder, llamar a fragmentos de código cada 50 o 100 mS (por ejemplo aquellos que no requieran una repuesta en tiempo real ya sea en el PLC o en HMI, como carga de registros, etc), de tal forma de no ocupar el procesador en la lógica principal para ejecutar todos los componentes al mismo tiempo.

Saludos!
10
Buenas tardes.

Te adjunto un ejemplo StringArrayCheck.zip que replica las cadenas que me pasaste con StrFormat().

Cargalo al PLC, y accedé vía el navegador web a la IP del dispositivo, debería mostrarte las cadenas, o decime si te da error.

Deberías ver algo así:





Por otro lado, como no veo un error que salte a la vista, ¿tenés alguna versión del código del proyecto que te de el error descripto, para que yo pueda reproducirlo?.

Es decir, podrías eliminar/comentar todas las partes que no tengan que ver con el error, dejando solo el código problematico (que al cargar te produce el RunError). Luego desde menú "Archivo > Crear backup del proyecto (zip)", generás el archivo ZIP para adjuntar con el proyecto funcional en cuestión así lo puedo abrir y cargar al PLC.

Las partes que requieran lectura de alguna entrada, comunicacíon de módulo externo, etc, eliminalas, para no tener que cablear hardware externo a la hora de probar el programa, ya que aparenta ser un tema de software puntual.

Saludos!





Páginas: [1] 2 3 ... 10