Mostrar Mensajes

Esta sección te permite ver todos los mensajes hechos por este usuario, recuerda que solo puedes ver los mensajes en áreas en donde tu tienes acceso.


Mensajes - Soporte

Páginas: [1] 2 3 ... 88
1
Voy a fraccionar la generación del CSV. Igualmente me parece que los límites son más altos de los que me ponés en tu post.
Para que tengas una referencia, actualmente la línea que genera el string CSV tiene:
- 328 caracteres en el código fuente pawn
- Imprime 20 variables %
- El string CSV generado tiene 85 caracteres

Mientras cadena resultante total, la que se imprime finalmente (una vez que los códigos de formato son remplazados), no supere los 199 caracteres estaría bien. Superado este valor, puede ocupar otras áreas de memoria y traer errores (esta cadena dinámica no se limita internamente).

Saludos!

2
Buenos días Pablo, qué tal,

... pareciera que cuando se genera la página mediante WebServerPrintStr(), hubiera alguna limitación en cuanto al número de caracteres que puede tener el renglón; aparentemente serían 90 caracteres. Cuando llega al caracter 90 el string se trunca. Puede ser ?
Esta es la sintaxis utilizada (todo es 1 renglón Pawn):
WebServerPrintStr("%02d/%02d/%02d,%02d:%02d:%d,%s,%d,%d,%d,%s,%d,%s,%02d/%02d,%02d:%02d,%02d/%02d,%02d:%02d,%d.%d,%d.%d,%d.%d,FIN", Dia, Mes, Anio, Hora, Min, Seg, DATO1, DATO2, DATO3, DATO4, DATO5, DATO6, DATO7, DATO8, DATO9, DATO100, DATO11, DATO12, DATO13, DATO14, DATO15, DATO16, DATO17, DATO18, DATO19, DATO20, DATO21)

Para la función WebServerPrintStr(), el límite de la cadena que contiene el formato, es decir "%d, %d, etc", es de 99 caracteres. Y la cadena resultante final, una vez que los formatos son remplazados por sus valores al llamar a la función e impresa en la página, es de 199 caracteres. Así mismo, la cantidad de variables en la lista variable de argumentos no debería sobrepasar los 10.

Si debés imprimir gran cantidad de variables en la misma página, podrías subdividirlo en varias llamadas a WebServerPrintStr(), por ejemplo:

Código: (Pawn) [Seleccionar]
case 1:
WebServerPrintStr("%d, %d, %d, %d,", value1, value2, value3, value4)
case 2:
WebServerPrintStr("%d, %d, %d, %d,", value1, value2, value3, value4)
case 3:
WebServerPrintStr("%d, %d, %d, %d,", value1, value2, value3, value4)
case 4:
WebServerPrintStr("%d, %d, %d, %d", value1, value2, value3, value4)

Es un poco más lento, pero para gran cantidad de valores, es la única forma.

También, te recomiendo usar separador punto y coma ";" para CSV, ya que es más estándar para luego importar desde Excel, si esa es la finalidad.

De paso: la instrucción en lenguaje Pawn que genera ese string es larga (tiene como 480 caracteres)... hay alguna limitación en el compilador para el largo de un renglón de código fuente?  Me surgió esta duda buscando de resolver el problema del punto anterior...

No menciona una limitación de ese tipo, que no quiere decir que no la tenga, pero en cuanto a la cadena, debería estar dentro de los límites mencionados arriba para esa función.

Saludos!

3
Kinco / Re:Consulta HMI KINCO + PUERTO SERIE ASCII
« : noviembre 09, 2022, 11:56:21 am »
Lo poco que encontré utilizan el Universal ASCII Slave. pero justamente no se a donde ir a leer ni como tratar lo que llega.

Sí, pero no especifica como debe ser el formato de los datos para que lo interprete el HMI. A lo mejor el fabricante puede darte más información, pero creo que es un protocolo que requiere un formato en la misma cadena.

Por otra parte conoces o me recomendarías algún HMI que si pudiese hacer esto que necesito.

Generalmente los HMI vienen listo para utilizar con el PLC, por ello implementan protocolos y no dan mucha libertad, menos para tomar la cadena y procesarla a medida.

Lo otro que puede ser, es que desde el PLC leas la cadena, interpretes el número o extraigas la parte de la cadena útil y se lo pases a la pantalla.

Por ejemplo con este PLC utilizando las funciones del puerto serie en lenguaje Pawn:

https://www.slicetex.com/hw/stx8091/dx.php

Saludos!


4
Kinco / Re:Consulta HMI KINCO + PUERTO SERIE ASCII
« : noviembre 09, 2022, 11:02:08 am »
Tengo una HMI Kinco MT4434TE la cual necesito leer en el puerto serie del HMI un String o cadena de datos de un equipo que envía permanentemente valores.
Ejemplo: "<STX>000025<CR>"
luego mostrarlo por pantalla.

Buenos días.

Hasta donde sé no podrías hacerlo. El HMI permite seleccionar una lista de protocolos predefinidos para la comunicación e interpretación de datos, para así posteriormente poder mapear los datos en registros/variables cuya dirección corresponde a un botón, indicador, entrada numérica, etc.

Por ejemplo, un protocolo universal soportado es ModBus RTU (que generalmente encontrás en equipos a medida), sino, los específicos para cada PLC (Siemens, ABB, etc).

En tu caso es una cadena de datos que no correspondería a un protocolo soportado, sino que es arbitraria, por lo tanto, el HMI no la va a poder procesar.

Saludos!

5
Extra, si necesitás agregar Logs, pero solo para pruebas, y no en el código de producción, podés utilizar directivas de preprocesamiento para incluir código opcionalmente de acuerdo al valor de una constante, y evitar crear dos proyectos diferentes.

Ejemplo:

Definimos en un archivo de cabeceras, por ejemplo Globals.inc, la constante DEBUG_LOG:

Código: (Pawn) [Seleccionar]
#define DEBUG_LOG    (1)
Luego, en un archivo Pawn, por ejemplo, DebugLog.p, las funciones para hacer entradas de log, por ejemplo:

Código: (Pawn) [Seleccionar]
stock DebugLogInit()
{
   DiskMount()
   DiskLogInit(1, "log", "txt", "/", 100000, 9, DISKLOG_OPT_PPPPPPPX|DISKLOG_OPT_CIRCULAR|DISKLOG_OPT_FAST_WRITE)
}

stock DebugLogFuncName(const FunctionName[])
{
   DiskLogAddString(1, FunctionName)
}

Finalmente, desde el código del proyecto escribimos en cada llamada a función que queramos añadir su nombre al log lo siguiente:

Código: (Pawn) [Seleccionar]
#if DEBUG_LOG  == 1
DebugLogFuncName("NombreFuncion1)
#endif

// ... CÓDIGO DEL PROYECTO ...

#if DEBUG_LOG  == 1
DebugLogFuncName("NombreFuncion2)
#endif

Si DEBUG_LOG  == 1 se agregan entradas al log, si es 0, directamente no se incluye en el código.

En en log aparecerán las entradas con los textos NombreFuncion1, NombreFuncion2, etc

6
Buenas tardes Cristian,

La forma más simple de hacer un log es mediante la función:

DiskWriteLogString(Options, PathStr[], FormatStr[], ...)

Donde:

  • Options: Opciones para el log, usar DISK_WRITELOG_OPT_DEFAULT para opciones por defecto.
  • PathStr: Ruta al archivo, por ejemplo "log.txt"
  • FormatStr: Cadena con formato, por ejemplo "Hola Mundo!" o "Temperatura %f" (%f será remplazado por un valor float de la lista de argumentos variables.
  • ...: Argumentos con variables separadas por coma (opcional).

Ejemplo:

Código: (Pawn) [Seleccionar]
// Agregar mensaje de log con la temperatura del sistema.
DiskWriteLogString(DISK_WRITELOG_OPT_DEFAULT, "/log.txt", "Sistema listo, temperatura %f [C]", SysTempRead())

El código anterior creará una entrada similar a la siguiente si la temperatura es de 25.4 °C:

03/11/2022 19:45:03 Sistema listo, temperatura 25.4 [C]

Para que el ejemplo funcione, se debe montar una sola vez la tarjeta Micro-SD antes de utilizarla, por ejemplo al iniciar el PLC con el siguiente código:

Código: (Pawn) [Seleccionar]
   // Montar disco Micro-SD.
   DiskMount()

Ejemplo completo:

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



El método anterior no define la longitud del archivo, ni su tamaño máximo, lo cual, para log extensos, puede llenar la memoria o hacer archivos gigantes. Una forma más eficiente es utilizar las funciones DiskLog.

Primero montamos el disco como vimos antes:

Código: (Pawn) [Seleccionar]
DiskMount()
Luego inicializamos el canal número 1 de DiskLog (este número lo usaremos luego para loguear cada entrada) para que permita hasta 9 archivos de log, con un máximo de 100000 entradas cada uno, con un prefijo "log" de nombre y extensión "txt". El archivo se almacena en la raiz del disco "/".

Código: (Pawn) [Seleccionar]
DiskLogInit(1, "log", "txt", "/", 100000, 9, DISKLOG_OPT_PPPPPPPX|DISKLOG_OPT_CIRCULAR|DISKLOG_OPT_FAST_WRITE)
Los archivos resultantes serán: log1.txt, log2.txt y así hasta log9.txt. Cuando se llega a log9.txt, se vuelve a log1.txt porque está colocada la opción DISKLOG_OPT_CIRCULAR. Cada archivo tendrá un máximo de 100000 entradas.

Finalmente, para agregar una entrada de texto al log, utilizamos la función DiskLogAddString() pero especificando el canal 1 del DiskLog:

Código: (Pawn) [Seleccionar]
// Agregar mensaje de log con la temperatura del sistema.
DiskLogAddString(1, "Sistema listo, temperatura %f [C]", SysTempRead())

El código anterior creará una entrada similar a la siguiente si la temperatura es de 25.4 °C:


1 03/11/2022 19:45:03 Sistema listo, temperatura 25.4 [C]
2 03/11/2022 19:46:03 Sistema listo, temperatura 25.4 [C]
3 03/11/2022 19:47:03 Sistema listo, temperatura 25.4 [C]


Notar como al comienzo de cada entrada está el número de entrada.

Usar DiskLog con la opción DISKLOG_OPT_FAST_WRITE es más rápido para escribir en memoria que la función DiskWriteLogString() vista anteriormente.

Ejemplo completo:

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



Finalmente, contestando a tu consulta para enviar un valor float como entero por la red, sin usar desplazamientos, es sencillo. Utilizamos un entero como si tuviera un punto fijo y no flotante. Si multiplicamos por 100 antes de enviar, es como mover la coma dos posiciones hacia la derecha.

Por ejemplo:

Código: (Pawn) [Seleccionar]
new Float: Temperatura = 25.59
new Entero
new DataBytes[4]

// Multiplicamos temperatura por 100 para preservar dos decimales y luego convertimos a entero.
Entero = FloatToInt(Temperatura * 100.0)

// Enviamos el valor "Entero" por la red, byte a byte desde el array DataByte[].
DataByte[0] = Entero & 0xFF
DataByte[1] = (Entero >> 8) & 0xFF
DataByte[2] = (Entero >> 16) & 0xFF
DataByte[3] = (Entero >> 24) & 0xFF

Al recibir en Visual Basic armamos el entero (sugerido):

Código: (VB .Net) [Seleccionar]
Dim Entero As Integer
Dim DataByte(3) As Byte  ' Array de 4 bytes

' Opción #1
Entero = (DataByte(0)) Or (DataByte(1) << 8) Or (DataByte(2) << 16) Or (DataByte(3) << 24)

' Opción #2
Entero = BitConverter.ToInt32(DataByte, 0)



Posteriormente, en Visual Basic el valor "Entero" lo convertimos a "float" y dividimos por 100 para obtener los dos decimales, es decir, movemos la coma decimal hacia la izquierda.

7
Cristian nos consulta:

Cita de: Cristian C.
Hola Boris, quiero pedirte si me podes pasar los comandos para poder grabar un LOG con entradas de cadenas de texto en un archivo de la memoria Micro-SD, para que pueda ser utilizado en laboratorio y que nos permita identificar qué rutina es la que se bloquea. Por otro lado pedirte también como hacer para enviar por red la temperatura del PLC como número entero que no recuerdo bien lo que hablamos (te lo pido como entero ya que en vb no tengo la función >>).

Desde ya muchas gracias.

8
Kinco / Quitar Menu Task Bar y emitir sonidos al pulsar pantalla
« : septiembre 30, 2022, 20:51:45 pm »
Desde el menú "View > Attribute" seleccionamos las siguientes pestañas, señaladas en color amarillo en las capturas de pantalla, y tildamos o destildamos las opciones indicadas:

Quitar Menu Task Bar:



Emitir sonidos al pulsar pantalla:




9
Kinco / Re:REMANENCIA Y RTC
« : septiembre 28, 2022, 12:04:59 pm »
Buenos días Angelo,

Estoy con unos problemas que no le estoy pudiendo encontrar solucion, tengo un panel KINCO HMI-PLC HP043-20DT

No trabajamos ese modelo, no le podría indicar. En este foro damos soporte para ayudar a conectar los HMI con los PLC de Slicetex Electronics, operaciones básicas para comenzar a utilizarlos, o también responder dudas para otras marcas si sabemos la repuesta. Para soporte más complejo o profundo, conectar a otras marcas de PLC, debería contactar con el fabricante o revisar el manual.

1) Como pudo hacer para que una un boton (bit state setting o bit state switch usandolo como MARCA) tenga remanencia ? osea si se corta la luz que mantenga el estado en el que estaba

En el manual de usuario de la pantalla Kinco, ver link a continuación:

http://slicetex.com/hmi/kinco/files/Kinco_HMIware_User_Manual_EN_1506.pdf

Bucar capitulo 16, página 461. Allí se detallan los registros internos de la pantalla para uso general y cuales mantienen la información luego de quitar la energía. Para bits son los RB (mantienen si batería está agotada) y FRB (mantienen siempre, pero tienen límites de escritura, ya que es FLASH). Para registros o words, son RW  (batería) y FRW (en memoria FLASH).



Debe tener en cuenta que si solo lee el bit o registro, no se guarda, también debe hacer una operación de escritura.

2) No se como usar el RTC_R y RTC_W para mostrar el horario actual, ya intente varias formas pero no lo logre

No los encuentro en el manual, pero en la página 91, da un ejemplo. Los registros asociados al RTC son LW10000 a LW10006:



Estos registros los puede leer y mostrar en pantalla.

3) Me gustaria hacer un contador de horas de marcha o por ejemplo una alerta de mantenimiento a las 6000 hs de uso, pero no se como !!

Ese contador debería hacerlo en la lógica del PLC, no en la pantalla. Y luego desde la pantalla acceder a los registros del PLC para leer algún bit o flag que se ponga en "1" cuando llegue a las 6000 hs y dar la alerta.

Alternativamente hay formas de hacer scripts (con cierta lógica) en la pantalla para incrementar y comprobar el valor de una variable, le puede servir porque es simplemente un contador, aunque no es igual de versátil que hacerlo desde el PLC.

Hay un en el foro un proyecto donde se utiliza un script en la pantalla, puede mirarlo para orientarse:

foro.slicetex.com/index.php?topic=543.0

Saludos!

10
STX8140 / Re:Node-red
« : septiembre 15, 2022, 16:49:50 pm »
Si la cadena puede tener como maximo 9 digitos y puede contener letras y numeros como por ejemplo A01001001 o 180180180 o X1180

¿Entonces estás trabado en cómo leer la cadena del HMI en el PLC?.

Mirá el siguiente link para entender cómo la envía el HMI y cómo debés procesarla en el PLC:

http://foro.slicetex.com/index.php?topic=256.msg1370#msg1370

Avísame cualquier duda.

11
STX8140 / Re:Node-red
« : septiembre 15, 2022, 11:39:03 am »
Hola Ing. Boris, no, el tema es con el HMI y el PLC, yo necesito pasar un nombre del HMI al PLC para que luego el PLC haga un http get con el nombre que le pase del HMI.

Bien, ¿ya tenés la cadena que le pasás del HMI al PLC? ¿Cuál sería el problema?. Ejemplificar, así logro entender qué necesitás hacer con la cadena.

Gracias.

12
STX8140 / Re:Node-red
« : septiembre 15, 2022, 10:22:34 am »
Hola Ing. Boris logre comunicarme por Http Get que antes no podia con aspx. Ahora el problema que tengo es pasar un string del HMI Kinco al PLC, porque lo pasaba con un array pero luego como lo uno para formar un string. Yo por ejemplo del HMI le paso "estaban10" y luego lo poso por  Http get ese mismo string y capturo la respuesta.

Buenos días Esteban,

¿Esto es con Node-red?.

Si mal no te entiendo, ya tenés dos string en el PLC, por ejemplo, uno es "Hola" y otro es "Mundo", y ¿querés unirlos para que quede "HolaMundo"?.

Saludos!

13
STX8140 / Re:Node-red
« : septiembre 12, 2022, 08:59:46 am »
Hola Ing. Boris, hay posibilidad de ver entradas y cambiar salidas utilizando node-red, yo creo q si pero no sabría como. Saludos. Esteban

Buenos días Esteban,

No he utilizado Node Red, pero por lo que veo puede utilizar protocolo ModBus TCP. En ese caso al PLC lo ponés como esclavo (servidor) y a Node Red como maestro (cliente) y podrías controlar y ver las E/S del PLC. Tal como harías para conectar un HMI Kinco por Ethernet.

Ver siguiente link en Youtube en donde se explica como utilizar ModBus TCP:

https://youtu.be/sjnKFd6m1Sw

Y para el PLC leer la nota AN022.

Saludos!

14
STX8180 / Re:Creación de archivo bin de log con fecha en el nombre
« : agosto 26, 2022, 09:09:19 am »
Buenos días Miguel,

Le paso el proyecto DiskSamplerLog3B.zip actualizado:

http://www.slicetex.com/docs/an/an036/files/examples/DiskSamplerLog3B.zip

El proyecto, ahora, actualiza la lista de links "/web/loglist.htm" a los archivos logs almacenados cuando la fecha cambia mientras está activado el log de datos.

Para ello se creo una nueva función llamada SamplersUpdateLogLinks() en Samplers.p, que se encarga de comprobar si la fecha actual es diferente a la fecha del último log agregado como enlace en el archivo "/web/loglist.htm".

Si la fecha actual ha cambiado desde la última vez que se agregó un link a "/web/loglist.htm", se agrega el link al archivo log.

La función SamplersUpdateLogLinks() es llamada cada "SAMPLERS_UPDATELOGLINK_TIME" segundos desde OnTimeout.p cuando el Timeout2 expira. La constante SAMPLERS_UPDATELOGLINK_TIME se define en Samplers.inc, y tiene un valor por defecto de 30 segundos (se puede cambiar).

Esto quiere decir, que una vez que se produce el cambio de fecha, si el log está funcionando, dentro de SAMPLERS_UPDATELOGLINK_TIME segundos se va a actualizar el archivo de links "/web/loglist.htm". Por lo tanto hay que esperar este tiempo para ver cambios en "/web/loglist.htm".

Leer código del programa y archivo info.txt dentro del proyecto, para comprender funcionamiento.

Saludos!

15
STX8180 / Re:Creación de archivo bin de log con fecha en el nombre
« : agosto 23, 2022, 21:29:20 pm »
creo está operando bien, solo que en la página dinámica no están apareciendo los nuevos archivos al cambio de día.

saludos   Nota:  se están realizando 7 canales , 5 muestras por segundo

Buenas Miguel,

Si, debe ser lo que comentaba en los mensajes anteriores,  no se está llamando a SamplersStart() cuando cambia de día, por lo que el nuevo archivo no se añade a la lista en /web/loglist.htm. Esto es porque no se tuvo en cuenta en el ejemplo.

Analizo el ejemplo DiskSamplerLog3B.zip para ver como modificarlo para que al cambiar de día, también se liste en la página web. Dame unos días, así lo pruebo, y te aviso por acá al subir la nueva versión del ejemplo.

Saludos!



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