STEP7 UDTs and initial values.

JesperMP

Lifetime Supporting Member + Moderator
Join Date
Feb 2003
Location
ᚴᚬᛒᛅᚾᚼᚬᚠᚾ
Posts
16,338
Hi,

I am experimenting with using UDTs for organizing my program data, and I find that I get the same functionality as if I had used FBs + instance DBs.
The problem is that there will be differences between the final values (that are found to be good at commisioning) and the initial values (that were based on my best guess at time of design).
If I download a new program the actual values will be overwritten with the initial values. The initial values comes from the declarations in the UDTs.
If I upload the actual values from the CPU to the offline project, then the DBs are out of sync.

I think now that I have to use shared DBs with 'regular' data declarations (i.e. no UDTs).
The negative aspect with this is that it takes a lot more editing work to get the same thing done.

How are you guys doing in this respect ?
How to structurize the data AND be able to keep the actual values ?

NB. Pardon me if this thread is similar to a previous one I posted. The difference is that I thought that FCs + Shared DBs + UDTs would be better than FBs + instance DBs.
 
HERE it is, Roy :)

But I didnt get any conclusion in that thread about what other people do in that situation.
But it MUST be something that is universally relevant.
Nif mentioned that with S5 you could copy the DB back to the PC. This is what I did with S5 and what I do with S7, but STEP7 is much more picky and likes to flash a "timestamp conflict" every now and then.
Generally you can not use instance DBs, or shared DBs with data declared with UDTs when you want to upload the 'good' data.
 
Hello Jesper!

What I'm doing (this is not a fix it's just a workaround) is that after the program is finished I copy the online program to a new s7 program inside the project.
If I have to download after a crash or memory reset then I just download the online copy first then my program (without the DB's).
This way I know that I'll at least have the data from the last backup.

The bad part about this is that I have to remember to do a upload after doing some changes to the DB's.

BTW. Is there a way of not loosing all the data in a DB if you have to change it?

Cheers
Borte
 
Thanks Jesper, that was interesting, I hadn't been really clear of what the "PLC > Copy RAM to ROM" command actually did.

For some reason, probably related to how my peculiar brain works :rolleyes: , I prefer to organise my data in DBs rather than in Merker and this problem with the retention of the initial value has been a pain in the neck, to put it mildly! The all or nothing nature of the command is not a problem for me (at the moment?).

Great forum this, I learn something new or useful every week!

Cheers

Roy
 
My experience with initial values is they only come into play when the data block is created or is modified with a new element. After that Step7 uses the stored data values. Now if you have never done an upload and save of the DB the saved data and the initial values WILL be the same and you will download the initial values when you download the DB.


I am assuming you can online monitor the DB without getting the timestamp conflict message. If so you can save from the online monoitor and the offline DB will be populated with the latest online values.


If you actually did modify the DB offline and you have a timestamp conflict you are sunk as far as I know. In those cases I open up an online and offline copy of the same DB and make sure the offline data matches the online data. If not I manually update the offline copy, save it and download it to the processor. But then again, mu biggest DB is about 300 bytes long with alot of floats so it doesn't take me too long to do this.


I have to agree that Step7 is too restrictive in this regard. A warning that there is a conflict is a good thing. However, Step7 should allow you to upload the online data and keep the offline structure. As responsible individuals it should be up to us to make sure this is what we want.
My only guess is that the extra layer of data mapping with symbolic programming might get screwwed up if addresses really did change.


I'm a little confused with your question, though. To the best of my knowledge UDTs are a programming tool. They lay a template over the top of a data block to add organization and make data referencing more intuitive. But in the end you still just have a DB. It should act just like any other DB when sending/viewing data to/from the plc.
The only exception to this is probably when you modify the base UDT. This will force data to move and Step7 may not babysit this move very well. Instead of moving pre-existing data to make room for the new stuff Step7 might just re-initialize the UDT elements already created. I'm not sure on this.

Keith
 
Borte,
your method is OK. But you have to be onsite to do that. I want to have the latest actual values stored as initial values on the memory card. In that way my customer can exchange the CPU, move the memory card to the new CPU and startup with the actual values from the time that I did the last save.

Roy,
be a little careful with that 'Copy RAM to ROM' feature. As I am only using S7-400, I am not 100% certain what it REALLY does. Maybe you can check it out.

Kamenges,
I believe that the initial values also comes into play when the CPU goes through a 'cold startup' *.
when I use shared DBs with data declared via UDTs, STEP7 gets very picky. It 'feels' the same as working with instance DBs. Every now and then you will be forced to syncronize everything. And when that happens, the actual values are overwritten with the initial values.

*: I am going to test that tomorrow. Just to be sure what I am talking about.

For now, I work with shared DBs with 'regular' data declarations. This is least problematic approach for me. But it means that editing takes that bit longer, as there is no smart structuring of the data.
 
Jesper,

I have had to come up with methods of retaining data on blocks that I want to download, and have used different approaches for what I need to do.

For one thing, I rarely include initial values in my DBs. There's nothing really wrong with it if that is how you want to do it, but I find it too restrictive. Instead, I leave all variables at "0" and initialize them programatically on start-up with SET/CLR, L/T, etc. That way I can change an initial value on only one variable without downloading the whole block (and screwing up the time stamp and actual values). It also works great during development, because on start-up I just clear the DB completely and reload the initial values without needing to download the DB (this is especially useful during integration, because the plant technicians can reset the program to defaults in an emergency without my help simply by switching the plc to Stop/Run).

As for retaining live values in the event that you want to download the DB (which obviously overwrites the live values), what I do is create a scratch block in memory that mirrors the actual block I am concerned about. At the end of each scan, I just do a block copy to the scratch block (or, if you are only concerned about a few values, you can just copy them one-by-one). Now that the values are in the scratch block, I can download the new block and then copy them back with any method I choose. For instance, I could have a button on the GUI called "COPY DB", or I could do it automatically on start-up. Most of the time I just retain stuff like machine configuration values that the operator might have changed over time, but I suppose you could save the whole block as well. I usually use this method when I want to download the whole program after a fresh compile, and I don't want to lose the actual values.

As for being able to retain the live values during a CPU exchange, I'm not sure if there is a dependable way of doing it at the PLC level. I use only S7-400s with RAM cards, so there is no way I can pull them anyway, but maybe you can find a way with the RAM/ROM copying. In my case, I always copy the critical values somewhere else (usually a file on the HMI PC), and copy them back if necessary. Or, I could even copy them to another PLC for safekeeping. But ultimately, I've found that my time was better spent on finding ways for the machine to self-learn after a fresh download. That way, I always know the machine starts with good, safe values, especially since I don't know why the machine died in the first place, or what they did to it while it was down. The only reason (outside of development and commissioning) I download a new program anyway is after a catastrophic failure, so I'm depending on it not happening very often :). On the other hand, I'm not familiar with your machines.

As I've mentioned in other posts, I really like the FB/UDT approach without using the instance DBs. It has sped up program development exponentially, and the scan times are faster than ever. I usually end up with only one or two huge shared DBs, and I can see what the machine is doing just by monitoring these blocks instead of creating a bunch of VAT tables.
 
I really like the FB/UDT approach without using the instance DBs

S7Guy, can you expand on this a bit, do you just create the instance DBs and then ignore them, or is there a way to use FBs without having to create the instance DBs?

I seem to have intuitively arrived at a similar way of working, I collect all my common data in one fairly large DB. I did this partly out of organisational grounds and partly on the (unfounded?) assumption that it would be quicker opening (and leaving open) one large DB than opening and closing multiple smaller ones.

Is there a point at which one runs into a law of diminishing returns with really big DBs where it might actually be better to change to two smaller ones?

Is the benefit of using UDTs purely organisational, or does it have other advantages as well. I'm thinking of my current situation whereby after each monthly meeting it's a 90% probability that the customer wants some new facility or has changed his mind about the way he wants something to work. This results in me having to modify the structure of my general DB (occasionally quite substantially). Then I find that once in a while ProTool Pro gets confused when it tries to reorganise the symbols. It doesn't happen very often (thank goodness!) but when it does it's a real pain in the neck, because in some screens all 21 modules are shown, so every screwed up symbol has to be reentered 21 times - not funny! banghead

If reorganising my DBs to include large chunks of (relatively) stable data into UDTs would effectively protect this data better, then it might be worth my while to do it.

Cheers

Roy
 
Last edited:
I'm puzzled about two things: the UDTs; and the continual reference to FBs without instance DBs.

With UDTs Ithought the whole point was that a user could define a unique datatype composed of simpler datatypes and use that in their own application. Once you had created this datatype called Valve or Pump or whatever, you just used it in type declarations in DBs, or FC and FB parameters exactly as a standard pre-defined datatype. How does the use of a UDT differ so much from the use of an INT or BOOL etc?

How on earth do you call FBs without instance DBs? I understand about multiple-instance DBs where a 'parent' FB can have 'children' FBs declared within it as STATs, and these children do not have explicit IDBs. But eventually, when you call the parent, surely you do have to assign an IDB and it wraps up all the data requirements of the parent and children in the one DB? So other than reducing the actual number of DBs involved you've saved no memory. Anyway, if you could call an FB with no instance DB wouldn't that be exactly the same as an FC? I thought the whole difference between FCs and FBs is that an FC has no inherent memory of ever having been called before (previous executions have no effect on the current execution) whereas the STAT capability of an FB gives it a history of previous results. If you don't need or want the instance DB, don't use an FB?

Still puzzled (even after writing it all out),

Ken
 
No,
it is FBs + instance DBs
OR it is FCs (with data declared as UDT types) + shared DBs (with data declared as UDT types).

You can pass a complete DB (or part of a DB) to a single INOUT pin of an FC, when the data is declared as UDT types.

My experience is that it is the same as if you use FBs + instance DBs.
If you change the UDT, you will have to update the FC, and the shared DB as well.
And the problem with the initial values is the same as with instance DBs, only it is the initial value of the UDT.
Before I started to experiment with this I did think that it would give me some advantages, but now I am not so sure.
 
Still puzzled (even after writing it all out),

Ken, you're not the only one, it's got me thoroughly confused. Guess we'll just have to wait till S7Guy gets back on air later on!


Roy,
be a little careful with that 'Copy RAM to ROM' feature. As I am only using S7-400, I am not 100% certain what it REALLY does. Maybe you can check it out.

Hi Jesper,

I thought I'd take a look at this, but I hadn't actually planned on being at it for more than half a day! In the process I laid the 317 low again and in the course of juggling MMCs around I then managed to screw the 314 up as well.

It looks as if you screw the formatting of the MMC if you try and load more into it than it can hold. After swapping the MMCs back and forth I managed to get the 314 into the condition where it was demanding a reformat of the card - which I did. Thereafter, I could load some programs, but not all (although all these other programs had previously worked OK). It chucked out all sorts of weird error messages (like complaining about perihery access fault when there was no attempt no access periphery!). I suspect I need to reformat the MMCs offline in the Prommer - but that's another problem - and in about five minutes, another Thread!!!

DB Remanance (is that how you write it in English?) in S7 300 CPU's.

I finally found the story here - "HB_CPU31xC_und_CPU31x_d.pdf", that's the German version, but I assume the English version is the same with an "e" instead of a "d" at the end.

Basically the DBs on a 300 CPU are allways remanent - in fact the whole of the working memory(?), Arbeitsspeicher, (it's a weird feeling being a native English speaker and through having worked with something only in German, having no idea what the English terminoloy is :oops: )is always remanent. There are basically two qualifications:

1) 317 CPUs - only 256kB of the memory is available for remanent DBs, so if you've got more DBs than that - tough!

2) There is a difference between CPUs with Firmware V1.0 and those with Firmware >= V2.1

With Firmware <V2.1 all memory is remanent (apart from above 317 exception)

With Firmware >=V2.1 you have the choice of whether the DBs (and only the DBs) are remanent or not. You define this on Side 2 of the General Properties. (Only possible with Step7 >= V5.2, or by using SFC82)

As luck would have it, although both the 317 and 314 were bought about the same time in the middle of last year, the 317 has V2.1 and the 314 has V1.0, so I played around to see what happened.

To cut a long story short, the 317 behaved as one would expect, the 314, however, initalises the DBs to "0" regardless of what you enter as an initial value! Once you change the value, however, it is then remanent.

I didn't get round to playing with the SFCs 82 - 84, because of the MMC problems. I think it's probably not really relevant unless you're running out of memory and only want to load certain DBs when they are actually needed by the program.

Anyway, now we all know what happens to DBs in a 300 CPU, I'm off to my next thread to see if I can dig up the S/W for the prommer so I can rescue my MMCs - I'm down to my last one now!

Cheers

Roy
 
S7Guy, can you expand on this a bit, do you just create the instance DBs and then ignore them, or is there a way to use FBs without having to create the instance DBs?

I don't create the instance DBs, nor do I use FBs as a STAT variable. I just use a shared DB just as I would with any other function, and declare a UDT as a STAT variable.

How on earth do you call FBs without instance DBs?....But eventually, when you call the parent, surely you do have to assign an IDB and it wraps up all the data requirements of the parent and children in the one DB?

Nope. I haven't used instance DBs for a few years, but 90% of my code is still in FBs. I will post a sample project later. When you look at it, you will see that you would be able to change the length and structure of any UDT (and consequently, the DB) and not have to update any code or block calls. And, you will be able to monitor everything from one block.

Anyway, if you could call an FB with no instance DB wouldn't that be exactly the same as an FC?

Not quite. Functionally, it would look the same, but when you assign a UDT as an FC Input/Output variable, the scan time increases considerably, because the operating system spends a bunch of time passing each individual item into the function. But because the UDT in an FB is assigned to the STAT, it doesn't have to pass anything in. As a result, it runs as fast as though you were directly addressing the variables.

Is the benefit of using UDTs purely organisational, or does it have other advantages as well. I'm thinking of my current situation whereby after each monthly meeting it's a 90% probability that the customer wants some new facility or has changed his mind about the way he wants something to work. This results in me having to modify the structure of my general DB (occasionally quite substantially).

I know exactly what you mean, which is why I do it the way I do. All I do is add the new variables, recompile, and download. If you are using an HMI, then the addresses have to be updated as they usually are. I don't use Siemens TPs, so in my case it's just a matter of generating a new SQL file, but in your case you might have to be a little more creative (I worked with ProTool only a few times, and it leaves a lot to be desired). I thought there was a way to import tags into a protool project, but maybe I'm wrong.

Like I say, I'll post something later.
 
OR it is FCs (with data declared as UDT types) + shared DBs (with data declared as UDT types)

Do you mean that you can define a global DB to be the instance DB for a variety of different FBs? If so, how do you do it in practice?

Cheers

Roy
 
1. To RMA:
OR it is FC s (with data declared as UDT types) + shared DBs (with data declared as UDT types)
First declare some UDT to suit your data (example UDT MyUDT).

Then create an FC (MyFC) and declare an INOUT (or IN and OUT if that suits you better) in the FC by means of the UDT (example INOUT name MyUDTinout type MyUDT).

Then create a shared DB (MyDB) and declare data in the DB by means of the UDT (example name MyData_1 type MyUDT, name MyData_2 type MyUDT, etc).

Then, when you call MyFC, you will be prompted for the INOUT pin, (example MyDB.MyData_1).
In that way you can forward a lot of data to the FC in a structured way.

By the way, Arbeitsspeicher = Work Memory. Just translate 'straight' over from german to english. Thats what the germans do anyway.

2. After a little experimentation I have found the following:
After a cold start (like startup after battery removal), S7-400 takes the actual values from the memory card (before I was worried that it would take the initial values, but that does not happen).

So, the trick is to:
a. When commisioning is finished, upload the DBs that are important to the offline project (go online, highlight the relevant DB(s) and select PLC ... Upload to PG).
b. Select PLC ... Download user program to memory card.
c. Archive the project.
d. Save the project under a new version number.

The only thing that can go wrong, is if you accidently use the 'Initialize datablock' function.

3. I will be very interested in that sample project that shows how to use UDTs + FBs and where you can change the structures without having to update block calls.
 
Last edited:

Similar Topics

This is the first time I am working with Simatic Manager Step7 as I started my siemens journey with TIA which is pretty easy and do a lot of stuff...
Replies
3
Views
150
When you download a DB, the values get overwritten by what is in the "actual" column in offline DB. Does this happen at the start of the PLC...
Replies
6
Views
147
Hello Inside a FB, I´m trying to transfer a string from a DB to a IN_OUT var that was define as a UDT. The problem is that i can´t determine the...
Replies
4
Views
141
Hi all, I am trying to convert RSLogix 5000 program to Step7. I need to bit shift left my array of double integers for tracking the product on...
Replies
2
Views
527
I have a word in some DB which I want to load to AR1 and use as a pointer. In order to do this I need to write L DBxy.DBW xy SLD 3 LAR1 I...
Replies
3
Views
544
Back
Top Bottom