Los DB en Step 7 son unas herramientas muy potentes para el almacenamiento y tratamiento de datos, de ahí que tengas que aprender una serie de conceptos que te serán útiles a la hora de realizar tus proyectos.
Los DB (Data Block) pueden ser:
- Globales
- De instancia
El acceso a los DB globales está pensado para que puedan ser usados desde cualquier parte del programa (desde un OB, FC o FB).
En cambio, los DB de instancia están asociados a los Bloques de función FB y almacenan los valores de las variables estáticas usadas en estos FB.[divider]
Tipos de datos de los DB en Step 7
Los tipos de datos que nos podemos encontrar y definir en los DB en STEP son de dos tipos:
- Simples
- Compuestos
Los datos simples son los siguientes (con un ejemplo en su formato):
- Bool: True/False
- Byte: B#16#A
- Word: W#16#432
- DWord: DW#16#12300
- INT: 124
- DINT: L#130000
- REAL: 0.45e+1
- S5TIME: S5T#2s
- TIME: T#1D5H
- DATE: D#2012-12-24
- TIME_OF_DAY:TOD#11:34:15
- CHAR: ‘B’
Hay que decir que la asignación de memoria se hace por palabras. Esto implica que si definimos 3 bools se ocuparan 2 bytes. Si usamos un byte se ocuparan igualmente 2 bytes. Por tanto, si se van a definir bools es conveniente definir hasta completar la palabra dejando los que no vayamos a usar como libres para futuros posibles usos.
Los datos compuestos son:
- DATE_AND_TIME: DT#12-12-24-11:34:1.0
- STRING: ‘Hola mundo’
- ARRAY: Array[1..20]
- STRUCT
- UDT: UDT1
El uso de los datos simples es inmediato, pero en el caso de los compuestos, hay que hacer alguna consideración:
- En el caso de los Strings habrá que definir su longitud de tal forma que la memoria reservada será mayor o menor según definamos cómo queremos que sea de largo.
- Los arrays se usarán definiendo a posteriori de decir la longitud qué tipo de datos albergarán. Pueden ser datos simples o compuestos como por ejemplo otras estructuras.
- Las estructuras no son un tipo propiamente ya que no almacenan información. Simplemente se indica la forma en la que se van a almacenar. Por ejemplo podremos crear un array de 10 posiciones de STRUCT y dentro de esta, almacenar un entero y un String[18] por poner un ejemplo de forma que cada posición del array tenga un número y un string.
- Se pueden insertar UDT ya definidos con las precauciones que ya hemos comentado arriba. En la parte de definición al introducir un UDT sólo veremos que en el DB se reserva la memoria que ocupa el UDT. Si queremos ver las variables deberemos ponernos en modo visualizar datos.
DB en Step 7 usando UDT
Los archivos UDT (User-defined Data Type) son unas plantillas que usaremos en los DB con los tipos de datos que vamos a usar. Y me explico:
Imagina que tienes que realizar un proyecto en el cual vas a tener varias recetas cuyos datos los vas a almacenar en DB. La solución que se te puede estar pasando por la cabeza es… bueno, hago el primero, lo copio y pego tantas veces como sea necesario o los genero a mano uno a uno (trabajo de chinos).
Sería una solución aceptable si estás muy convencido de que esos datos van tener el mismo nombre dentro del DB. Imagina que has dejado algo de espacio con variables libres para futuros usos. Tendrías que ir cambiando a cada DB el nombre de la variable que acabas de modificar.
Como ves no parece una solución fácil de mantener ni especialmente elegante. Para solventar este inconveniente existen los UDT.
En los archivos UDT definiremos la estructura que queremos que tenga el DB. Luego, a la hora de añadir un DB, dentro de la pestaña de tipo, tendremos Globales, Instancia… y de tipo. Elegiremos el UDT que acabamos de crear.
Igualmente podremos insertar dentro de un FB como parte de sus variables estáticas (y por tanto parte de su DB asociado) un UDT predefinido.
A la hora de mantener los DB con el mismo UDT sólo tendremos que cambiar el UDT.
Pero ojo, has de tener claro lo siguiente ya que conlleva un inconveniente grave:
- El cambio de nombre en las variables de un UDT no afectará al funcionamiento de los DB creados. Asumiran los nuevos nombres y listo.
- El cambio de la estructura (Una variable definida como Word pasarla a INT) sí afecta a los DB creados.
Al cambiar la estructura, la estructura de los DB creados con los UDT no sólamente no se actualizan sino que además se pierde el valor simbólico de cada variable. Para solucionarlo has de destruir cada DB global y volverlo a generar. En el caso de los FB habrá que actualizar los accesos.
Este grave problema hace que se deba saber muy bien de antemano cuál va a ser la estructura del DB. La forma de mitigar los efectos tan nocivos que puede acarrear el cambio de estructura es la siguiente:
- En el UDT dejar variables que creas que pueden ser útiles en el futuro como libres de reserva. Esto implica que el DB va a ser más grande de lo necesario de forma artificial para posibles problemas en el futuro. A decir verdad, no suele ser un gran problema por dejar espacio sobrante de cara al futuro.
- Incrustar el UDT dentro del DB. Es decir, en vez de declarar el DB de tipo, lo usas de forma global y dentro de el declaras una variable de tipo UDT1 (suponiendo que tu UDT sea el UDT1). De esa forma, el DB reserva el espacio al UDT y al cambiar la estructura del UDT, el DB no se ve afectado.
Abrir y hacer llamadas a los DB en Step 7
Dentro de cualquiera de los bloques que usemos podemos realizar llamadas al contenido de los DB. Así podemos cargar cualquier valor haciendo una llamada absoluta del tipo:
- U DB100.dbx0.0 para cargar el valor del bit 0.0 del DB100
- L DB100.dbb0 para cargar el byte 0 del DB100
- L DB100.dbw0 para cargar la palabra 0 del DB100
- L db100.dbd0 para cargar la doble palabra 0 del db100
Hay otra foma de hacer las lecturas que es mediante la apertura del DB y luego hacer las llamadas, así podríamos hacer como en el caso anterior:
- AUF DB100
- U dbx0.0 para leer el bit 0.0 del DB abierto.
Esto nos será muy útil para cuando veamos el direccionamiento indirecto.
Hay una segunda forma de abrir un DB que es, haciendo la analogía:
- AUF DI100
- U dix0.0 para leer el bit 0.0 del DB abierto.
- L DIB0 para cargar el byte 0 del DB abierto
- L DIW0 para cargar la palabra 0 del DB abierto
- L DID0 para cargar la doble palabra 0 del DB abierto
Se pueden combinar las llamadas de la apertura DB y DI de tal forma que podemos tener 2 DB abiertos.
Pero ojo, debes tener en cuenta una cosa. Si abres un DB y luego haces una llamada de forma absoluta a otro DB, el que queda abierto ya no es el DB que inicialmente habías abierto con el AUF sino el último del que has hecho una llamada absoluta. Me explico: imaginate que tienes dos DB, el DB1 y el DB2. El primero contiene un entero con valor 5 y el DB9 un entero de valor 9. Si haces esto:
- AUF DB1
- L DBW0
- T MW 0
- L DB2.DBW0
- TMW2
El valor de la MW0 será 5 y el valor de MW2 será 9. Ahora bien, si haces esto:
- AUF DB1
- L DB2.DBW0
- T MW2
- L DBW0
- T MW 0
Ahora, tanto MW0 como MW2 valdrán 9 ya que cuando haces la llamada L DBW0 último DB abierto no es el DB1, sino el DB2. Ojo con esto.
Igualmente puedes tener problemas si haces un AUF y antes de tomar y asignar valores, se hace una llamada a un FC el cual hace una consulta a otro DB. Por tanto, entre las aperturas mediante AUF y su consulta no debe haber ninguna llamada a un DB.
Lo que sí podrás hacer, siguiendo con el ejemplo anterior será algo de este estilo:
- AUF DB1
- AUF DI2
- L DIW0
- T MW2
- L DBW0
- T MW 0
Ahora sí MW0 = 5 y MW2 = 9 ya que estás abriendo un DB mediante AUF DB y AUF DI respectivamente y por tanto no se mezclarán entre sí.[divider]
En próximas entradas veremos cómo usar los DB mediante el direccionamiento indirecto y los punteros. Con ello podremos realizar acciones muy potentes dentro de lo que son los tratamientos de datos y DB en Step 7.
Finalmente he realizado un video (un poco largo, así que con paciencia) donde repaso todos estos conceptos.
Recordarte finalmente que si estás interesado en formarte en Step 7, puede que te interese adquirir el libro «Cómo programar en Step 7 y no morir en el intento» donde puedes encontrar no sólamente el curso completo gratuito, sino muchas más entradas del blog que como sabes se irán actualizando para los que lo adquieran de forma gratuita. Si estás interesado, puedes echarle un vistazo a este enlace donde se explica qué es lo que contiene el libro, el precio y los métodos de pago.
Referencias:
Enseño a programar PLC de Siemens a través de mis cursos.
Más información sobre mi aquí
Puedes seguirme en cualquiera de las siguientes redes sociales.
11 Comentarios
Enhorabuena por el fantástico trabajo que estás haciendo y al que estoy enganchado.
Respecto a los DB, suelo utilizar un truco que me permite modificar/añadir/borrar elementos en un DB o UDT sin que el programa quede inservible y sin tener que borrar y volver a crear los DB.
En «SIMATIC Manager», en el árbol de la izquierda, pinchar con el botón derecho del ratón en «Bloques» y pinchar sobre «Propiedades del objeto…. En la nueva ventana emergente elegimos la pestaña «Operandos preferentes» y situamos la selección en la casilla de abajo a la derecha («En todos los accesos»).
Ahora podemos modificar los DB, UDT aunque una vez modificados hay que hacer una cosa más.
Cerramos todas las ventanas excepto el «SIMATIC Manager». En el menú vamos a «Edición – Comprobar coherencia de bloques…» y volvemos a compilar el programa («icono «Compilar» o «compilar todo»). Y ya está solucionado.
Personalmente prefiero trabajar con símbolos como operandos preferentes, pero quien no esté acostumbrado, quizá debería volver al primer paso y dejar la selección el la posición original (el cuadro de arriba a la izquierda).
Un saludo a todos los automatistas.
Buen truco Carlos… y gracias por los ánimos!!
Muy agradecido por tus explicaciones. Me están ayudando mucho en mi formación.
Tengo una pregunta sobre DBs
El tema es el siguiente:
Mediante SFC 22 voy creando DBs según me son necesarios en el programa. Se crea un bloque de BYTEs (en mi caso 244 BYTEs).
Por otro lado tengo un UDT1 con la estructura: Medidas Array[0..59] de tipo Dint y con Media de tipo Real. Total 244 BYTEs.
Lo que quiero hacer es poder asignar al DB creado de forma dinámica la estructura del UDT1 para asi poder acceder o visualizar los datos de forma correcta.
Para el acceso a los datos no tengo problema al estar trabajando con punteros a los datos Dint y al Real.
Si creo el DB de forma manual no hay problema al usar una variable de tipo UDT1. El problema es que no se como hacerlo de forma dinámica.
Agradeciendote de nuevo el magnífico trabajo que haces me despido es espera de una posible solución.
Francisco
Muy agradecido por tu explicación. No la había visto antes y con esto me doy cuenta que debo revisarme mejor tu sitio para buscar la información antes de preguntar
Ya se algo nuevo y como solucionar mi problema.
Sigue así que te lo agradeceremos TUS alumnos.
Francisco
Hola tengo una duda con las DB,
Puedo guardar informacion en ellas y leerlas despues?
Por ejemplo tengo dos variables de velocidad maxima que solo una vez les escribire pero luego permaneceran como constantes, puedo hacer esto con una DB, o en que forma lo puedo hacer?
Gracias
Alejandro.
Hola Alejandro,
No tendrías que tener ningún problema en almacenar datos en los DB. Eso sí, puede ser escrito encima, así que cuidado.
Pero es común usar los DB como parámetros máquina, así que sin problemas en principio.
Un saludo
Hola tengo un problema con los DB,S necesito estar copiando de un db de edicion a otro DB estoy usando la funcion SFC84 para escribirle los valores de uno a otro , el problema esta en que cuando lo inicio los valores no los reescribe. Podrias ayudarme con este problema.
Los problemas por favor en el foro.
Buenas tardes Ingeniero:
Soy un novato aficionado a la automatización , he realizado algunos ejemplos muy básicos tomados de la red en diferentes tutoriales he visto con gran satisfacción los de su blog ,gracias por ayudar a formar el mundo que no tiene acceso a una universidad !!!
Solamente quisiera saber porque con wincc 2008 flexible no se puede utilizar los bloques de datos programados para simulación con plcsim step75.5 solamente lo he conseguido con marcas y con entradad y salidas.
La comunicación esta bien configurada entre wincc y step7 pues me reconoce las instrucciones con marcas .Es problema de versión de wincc o de configuración del mismo , como lo advierto soy un novato aficionado de , Muchas gracias por su atención .
QUE DIOS LE BENDIGA!!!!!
Una duda, estoy creando avisos, según la información que he encontrado tengo que crear un DB donde enliste todos los avisos, luego hacer referencia absoluta en la lista de variables de HMI. En caso de que sean más de 8 variables ¿Cómo hago la referencia absoluta? Ya que a esta se hace referencia tomado el offset, pero este va de 8 bits, y al hacer referencia tengo que escribir el número del bloque y el offset %DB29.DBW0 por ejemplo, pero al llegar a la variable 9 ¿Es válido escribir %DB29.DBW8? ¿O como se haría la referencia?
hola Iñigo muy buenas tardes tengo una pregunta espero me puedas orientar.
puedo mandar a leer un DB completo en un hmi mp277 y desplegarlo todo en una pagina del hmi?
saludos