• Skip to primary navigation
  • Skip to main content

ProgramaciónSiemens

Cursos online de automatización industrial con PLC Siemens

  • Cursos
  • Mi cuenta
    • Mi cuenta
    • Blog
    • Foros
    • Curso HMI con Python y Qt-Designer
    • Curso de AWL
    • Curso de iniciación a la Industria 4.0
    • Curso Express de TIA Portal
    • Curso de WinCC Flexible 2008
    • Crear HMI con OPC y VB.NET
    • Crear HMI con Snap7 y VB.NET
    • Curso ViSnap7
    • Curso de TIA Portal para CPU 1200
    • Curso de Step 7 V5.x
    • Curso de comunicaciones IE y Profinet
  • Contacto & Faq

Cómo copiar datos de forma dinámica en Step 7

Cómo copiar datos de forma dinámica en Step 7

por Iñigo Gútiez · 15 Comments

Vamos a ver cómo copiar datos de forma dinámica en Step 7 para que si tienes diferentes bloques de información homogéneos en su estructura (pero no en sus datos) y los quieres copiar  a un boque final en función de un parámetro cualquiera.

Por ejemplo, tenemos diferentes DB con información de ciertos productos que en función del producto, lo tenemos que copiar a un DB.

Podrías decir, bueno, en función del producto, hago una copia del DB del producto al DB final y ya está…

Hombre, pues sí, pero digamos, que es mucho trabajo y poco elegante. Porque si en vez de ser 10, ¿son 100?

Cómo copiar datos de forma dinámica en Step 7

Pues resulta que la solución es realmente fácil usando direccionamiento indirecto en Step 7.

Imaginemos que los DB donde tenemos la información son del estilo DB100 + Número de producto, es decir:

  • DB101 para el producto 1
  • DB102 para el producto 2
  • DB103 para el producto 3 …

Y así con todos.

Imaginemos, a su vez, que el DB destino es el DB1 (por poner un ejemplo) y que queremos copiar 50 bytes.

Bien.. ¿cómo copiar datos de forma dinámica? Pues realmente de una forma muy sencilla.

Lo primero que debemos tener en cuenta que para realizar este tipo de ejercicios podemos usar la apertura de los db de dos formas:

  • AUF DB
  • AUD DI

Sí, porque de esta manera, la solución es realmente sencilla.

Una vez sepamos el número de producto a copiar, tan solo deberemos usar la función SFC20 (Block Move)  para solucionar nuestro problema.

L #NumeroProducto //Leemos nuestro número de producto que indica el DB que almacena la información

L 100

+ I

T #NumeroDB // Sumamos el número de producto 100 unidades para obtener el número de DB a usar

AUF DI[#NumeroDB] //Abrimos el DB

CALL «BLKMOV»
SRCBLK :=P#DIX 0.0 BYTE 50
RET_VAL:=MW0
DSTBLK :=P#DB1.DBX 0.0 BYTE 50

¡Y ya está!

Como ves, en la solución, manejamos 2 conceptos:

  • Apertura de los bloques con AUF DI para abrir el bloque origen, y luego el puntero lo hacemos relativo a esa apertura simplemente leyendo 50 bytes del bloque abierto con AUF DI
  • Puntero absoluto de 50 bytes al DB1 destino

¿El destino podría ser dinámico a su vez?

Claaaaro. Si en vez de haber usado, el DB1, quisieramos usar un #DBDestino, podríamos hacer análogamente:

L #NumeroProducto //Leemos nuestro número de producto que indica el DB que almacena la información

L 100

+ I

T #NumeroDB // Sumamos el número de producto 100 unidades para obtener el número de DB a usar

AUF DI[#NumeroDB] //Abrimos el DB origen

AUF DB[#DBDestino] // Abrimos el DB destino

CALL «BLKMOV»
SRCBLK :=P#DIX 0.0 BYTE 50
RET_VAL:=MW0
DSTBLK :=P#DBX 0.0 BYTE 50

Como ves, esto de cómo copiar datos de forma dinámica en Step 7 es muy útil si quieres pasar información entre bloques.

¿Qué te ha parecido? ¿Te parece útil?

 

Iñigo Gútiez
Iñigo Gútiez

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.

Filed Under: blog

Reader Interactions

    Deja un comentario Cancelar

    Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

    15 Comentarios

  1. David says

    19 abril, 2016 at 23:06

    Supongo que el SFC20 tendrá sus limitaciones en el ancho de memoria que va a mover!

    Responder
    • Iñigo Gútiez says

      20 abril, 2016 at 20:01

      Pues a decir verdad, la ayuda de Siemens no dice la longitud máxima. Yo lo he usado y he copiado bloques muy grandes sin problemas.

      Responder
  2. Juan says

    20 abril, 2016 at 19:48

    Funcionará con DBs optimizados? No me adapto a estos nuevos DBs!

    Responder
    • Iñigo Gútiez says

      20 abril, 2016 at 20:15

      A ver, es AWL, y los 300/400 no admiten bloques optimizados. El 1500 sí, y la ayuda de Siemens dice esto:
      Descripción

      La instrucción «Copiar área» permite copiar los contenidos de un área de memoria (área de origen) en un área de memoria diferente (área de destino). La operación de copia se realiza por orden ascendente de direcciones. Las áreas de origen y destino se definen mediante VARIANT.

      Nota
      Las variables de la instrucción solo se pueden usar en los bloques de datos en los que no está ajustado el atributo «Acceso optimizado al bloque». Si la variable se ha declarado con el ajuste de remanencia «Ajustar en IDB», la variable también se puede usar «con acceso optimizado».

      Responder
  3. José says

    8 junio, 2018 at 12:15

    Buenos días, ¿cómo podría copiar dato a dato y pasarlo a una misma mw. Pasar todos los datos enteros de un db, por ej. 100 datos, a una misma mw, para luego pasarla a través de un dp dp a otra máquina. O sea que haga un barrido en bucle dl db y pase los datos uno a uno y los vaya pisando. Gracias.

    Responder
    • Iñigo Gútiez says

      10 junio, 2018 at 19:37

      Hola José. Tendrías que hacer un bucle que vaya leyendo el DB, y vaya recorriendo este paso a paso con un disparador. Leyera la posición X y la mandara a la salida Y (que sería la marca).
      Saludos

      Responder
  4. Nautilus says

    16 febrero, 2019 at 8:47

    Eso funciona para S7-300, pero en S7- 1500, me dice que el dato está incompleto, es decir, que aun cuando abro antes el bloque, me pide poner el prefijo DB, esto es: P#DB101. DBX 0.0 BYTE 50 y así ya no me sirve porque necesito que el Bloque de datos sea variable.
    Sal U2

    Responder
    • Iñigo Gútiez says

      16 febrero, 2019 at 11:49

      Efectivamente, el ejemplo es para S7 tradicional, y la serie 300 y 400.
      Las series 1200 y 1500, son en muchos aspectos diferentes, entre ello, los bloques de datos.
      ¿Los bloques los has configurado como no optimizados? Si no los configuras así, no funciona el sFC20 correctamente.
      Otra opción que tienes, seguramente más práctica, es usar SCL para realizarlo en TIA Portal.
      Saludos

      Responder
  5. Carlos says

    7 julio, 2019 at 21:58

    El largo del db es posible hacer que varie??

    Responder
    • Iñigo Gútiez says

      7 julio, 2019 at 23:24

      Si, jugando con los punteros puedes hacer el ancho sea dinámico también.
      Tendrás que jugar con la definición del puntero para que el ancho sea una variable de entrada.

      Responder
  6. eric nolasco says

    13 agosto, 2019 at 16:14

    Hola Gútiez

    Una pregunta. Tomando en cuenta la estructura «P#0.0 BYTE 50» hay alguna manera para que ese «0.0» y «50» sea variable? es decir poder cambiar el tamaño de la estructura y el puntero inical?

    Responder
    • Iñigo Gútiez says

      13 agosto, 2019 at 16:29

      Sí, tienes que configurar el puntero como tu quieras. Mira esta entrada: https://programacionsiemens.com/domina-los-punteros-con-formato-any/

      Responder
      • Eric nolasco says

        13 agosto, 2019 at 19:19

        Muchas gracias por tu pronta respuesta!!
        Para configurar el puntero ANY al inicio de tu código dice
        LAR1 P##Source

        Según tu definición de variables
        Source = type ANY

        Pero siempre se pone rojo mi código. No me deja colocar ese código inicial
        Ya cambié “Source” a tipo INT, DInt, Pointer, ANY me da error

        Responder
        • Eric says

          13 agosto, 2019 at 19:23

          Y quedó
          Perdón =)

          Responder
        • Iñigo Gútiez says

          13 agosto, 2019 at 19:53

          El código del ejemplo es un source de AWL. La idea es que cojas ese código y lo estudies para que veas como se hace, no que lo pegues tal cual, porque no te va a funcionar seguramente.
          Tienes que crear un FC, e ir implementando poco a poco el código, entendiendo cada parte de lo que se explica en el texto.
          Para empezar, por ejemplo, asegúrate que la variable SOURCE, que es de tipo ANY, la llamas SOURCE, y no #SOURCE, y la declaras en la sección de temporales.
          Esto debe funcionar sí o sí, porque no tiene más en un PLC S7-300 programado con S7 clásico.

          Responder
  • Aviso Legal y Política de Privacidad
  • Condiciones de Venta
  • Política de cookies
  • Contacto & Faq
  • Blog

Copyright © 2023 · Programación Siemens · Todos los derechos reservados

· ¿Quién soy? · Misión, Visión y valores