Es posible guardar 12 caracteres en una variable de un solo registro
algo como
new OT[1]
MbServGetRegisters(40009, 1, Ort, 0)
¿Obtener los caracteres escritos por el HMI en el PLC?
Bien, primero debes entender que 12 caracteres para poder almacenarse como cadena en el PLC, necesitan una variable o array de 12 elementos en el PLC, más un elemento de finalización con el valor cero que marca el "fin" de la cadena.
Entonces, necesitarías declarar una variable de 13 elementos asi:
new StringOT[12+1] // Le agregué el texto "String" para que sepamos que contienen una cadena y puse una suma para ser explicito.
Por lo tanto, si queres almacenar la cadena "
HOLA MUNDO!!" de 12 caracteres, podrías hacerlo de la siguiente forma:
StringOT[0]='H'
StringOT[1]='o'
StringOT[2]='l'
StringOT[3]='a'
StringOT[4]=' '
StringOT[5]='M'
StringOT[6]='u'
StringOT[7]='n'
StringOT[8]='d'
StringOT[9]='o'
StringOT[10]='!'
StringOT[11]='!'
StringOT[12]=0 // Valor cero de finalización.
Otro método alternativo (no utilizado acá), que solo sirve al inicializar el array es:
new StringOT[]="Hola Mundo!!" // Aqui el tamaño y el cero al final se asignan automáticamente.
Con esto en mente, si en el HMI cargamos la cadena "
Hola Mundo!!" a partir de la dirección
40009, nos quedaría:
40009 = "Ho"
40010 = "la"
40011 = " M"
40012 = "un"
40013 = "do"
40014 = "!!"Desde el PLC podríamos obtenerla de la siguiente forma, leyendo 6 registros a partir de la dirección
40009:
new Buffer[12]
MbServGetRegisters(40009, 6, Buffer, 0)
Pero esto nos deja en "
Buffer[]" los 6 elementos, y cada elemento con dos caracteres, ya que el HMI guarda dos por registro.
Buffer[0] = "Ho"
Buffer[1] = "la"
Buffer[2] = " M"
Buffer[3] = "un"
Buffer[4] = "do"
Buffer[5] = "!!"Entonces tenemos que desempaquetarlo, para pasarlo a un modo "normal".
Como en
Buffer[0] tenemos los caracteres "
Ho", cada uno en un byte diferente, entonces, tenemos que separarlos.
Esto lo podemos hacer asi:
new Text[12+1]
// Toma Buffer[0] y hace cero todo, excepto el byte inferior (obtengo primer caracter "H").
Text[0] = Buffer[0] & 0xFF
// Toma Buffer[0], desplaza 8 bits a la derecha para mover el byte superior al byte inferior,
// y luego hace cero todo, excepto el byte desplazado (obtengo segundo caracter "o").
Text[1] = (Buffer[0] >> 8) & 0xFF
Y nos queda:
Text[0] = "H"
Text[1] = "o"
Todo esto se puede automatizar con una función "genérica" auxiliar:
GetHmiString(): Obtiene una cadena guardada por el HMI a partir de un registro ModBus.
ARGUMENTOS:- Address = Dirección ModBus donde esta la cadena (ej: 40009)
- Qty = Cantidad Maxima de registros ModBus a leer (ej: valor 6, implica 12 caracteres)
- Text[] = Array o cadena resultante en PLC, debe ser de una longitud minima Qty*2+1.
GetHmiString(Address, Qty, Text[])
{
new Buf[40]
MbServGetRegisters(Address, Qty, Buf, 0)
for(new i=0; i<Qty; i++)
{
Text[i*2] = Buf[i] & 0xFF
Text[i*2+1] = (Buf[i] >> 8) & 0xFF
}
// Fin de cadena, ultima posicion.
Text[Qty*2]=0
}
Volviendo al ejemplo que propones y usando la función
GetHmiString() que te escribo, te quedaría para leer 12 caracteres:
new OT[12+1]
GetHmiString(40009, 6, OT)
Listo, ya tenes la cadena en
OT[ ].
Te adjunto tu programa modificado con esta función, donde imprimo como cadena en
Virtual-HMI (192.168.1.81) lo que recibo del Objeto ASCII en registro 40017 (para verificar el método).
Lo importante es que entiendas como se guarda todo en memoria, puede costar entenderlo, pero es simple si encapsulas todo en funciones y así se evitan errores.
Saludos