I am forced to really learn how to program a S7

For some reasons you have ditched SCL during your 'journey' into S7-land. I think that it would be a lot easier to write in SCL, since you are manipulating various DBs + indexing etc.

I could be persuaded to port what you have got until now into SCL, if you are interested.

Actually JesperMP and L D [AR2,p#0.0] know much more that what find in the books. [...] There are techniques shown that I haven't found in the books. However, I still am not convinced that they know the S7 inside out, forwards and backwards but they know how to use the S7 well
That is flattering - thank you. Personally, I have long since left the narrow STL-path, and wissed off via the SCL-highway. I dont know everything about STL, and am definitely not an ANY pointer wizard. LD seems to have chosen another path. People are different.
 
Peter, you can use

Code:
L P##RECV_BUFFER
LAR2

Idd but, if i'm not wrong otherwise just correct me.

If peter is using a FB the he can't use it in the position he does it know, scince i think the amount of loops is also in de declaration of the FB and Loaded after he has changed AR2. So there is a good possibility that the code is pointing somewhere wrong scince AR2 is pointing to the instance of a FB.
That is why i asked if it was a FB.
Correct me if i'm wrong.
 
For some reasons you have ditched SCL during your 'journey' into S7-land. I think that it would be a lot easier to write in SCL, since you are manipulating various DBs + indexing etc.
I am not writing this for myself and not everybody has SCL. This is an example program so that people can use FB500 RMC__UDP_READ and FB501 RMC_UDP_WRITE. to read and write anywhere any length.

I could be persuaded to port what you have got until now into SCL, if you are interested.
Actually, if I don't get an answer to my question I was going to write a SCL program that accesses an array in a structure like I want to do in STL. I would then look at the code SCL generates but it wouldn't do me any good if it just loads a constant offset into AR2.

That is flattering - thank you. Personally, I have long since left the narrow STL-path, and wissed off via the SCL-highway. I dont know everything about STL, and am definitely not an ANY pointer wizard. LD seems to have chosen another path. People are different.
I have found that if I create an error I can get the compiler to show me the true code that is generated. Only when the true code is examined and understood will one truly understand what is going on. Siemens hides too much and there are too many arbitrary restrictions.

Turbo, I will try
L P##RECV_BUFFER
but then I still must add the offset to the DATA. That is hard coded.

DI is already loaded with 500. DB500 is the IDB for FB500. On entry AR2 is 0 which makes sense.

I see the Loop: label is in the wrong spot. I haven't got to the point to actually run code because I can't load the offset of RECV_BUFFER.DATA into AR2. This should be easy. On a 80186 I would simply
MOV DI,OFFSET RECV_BUFFER.DATA
That would load the DI register with the offset I need. I could do that in the late 1970's and with ease. The the S7 is an example of 30 years of going backwards.

So there is a good possibility that the code is pointing somewhere wrong scince AR2 is pointing to the instance of a FB.
So far I have seen that AR2 is set to 0 on entry to a FB. The DI register points to the IDB. However, Siemens must play some more unseen tricks because DI has the IDB number not the true address of the IDB in memory. This means the Siemens must be using the DI register as an index register into a DB_ARRAY that holds the true IDB address. This makes sense if you think about it because as I down load different DB500 the S7 only needs to change the address in this hidden DB_ARRAY for the program to work. If the S7 didn't have this indirect DB array then the actual addresses of the DB500 would need to change everywhere in the program where DB500 is accessed. This is one of the few things I would do the same as Siemens does. When accessing variables in the DB from within the DB, the S7 should only need to use the DI register to lookup the true IDB address in memory and then add the offset of the variable in the IDB and load it. I am not sure why AR2 is needed. Looking at the FB500 code in STL shows that AR2 is not used anywhere until I try to use it.
 
I am not writing this for myself and not everybody has SCL. This is an example program so that people can use FB500 RMC__UDP_READ and FB501 RMC_UDP_WRITE. to read and write anywhere any length.
But why not make an FB that has an IDB plus parameters going in and out. In that case people do not have to access the SCL source code.
Actually, if I don't get an answer to my question I was going to write a SCL program that accesses an array in a structure like I want to do in STL. I would then look at the code SCL generates but it wouldn't do me any good if it just loads a constant offset into AR2.
If the code is an FB block, and external access to data is via INPUT and OUTPUS (f.ex. I guess DST is an OUTPUT that contains an ARRAY of DINTs), then the generated STL code manipulates its own IDB only. As it knows the position of all the STATs, including the INPUTs and the OUTPUTs, it loads AR1 with constants based on the position in the declaration table.
 
I don't know if i understand you sentense correct do you mean you don't know what AR2 is doing in a FB or do you mean something else ?
I mean that AR2 is set to 0 on entry and I see no instructions like L D [AR2,P#0.0] that require AR2 to do addressing. I see nothing that changes AR2 within FB500.

My program is mostly written in LAD but some is in STL. I go to the tab which says VIEW->STL and I can see all the code in STL. AR2 is not being used.

I am going back through this thread. I believe there are some examples are AR2 is used and perhaps L D [AR2,P#0.0] or someone else had an example but most were for FCs and they don't have STAT areas. It is still early here. I need to get to work where the S7 is.

BTW, after changing the interface on a FB I save it but DON't download it. I then go back to OB1 and update the FB and the DB. That works well. I then do the consistency check and recompile all and download. I still forget to download DB500. When I do the S7 stops. However, if I remember to download DB500 all works well and the change is relatively easy. There are still more steps and things to remember than what I think is necessary but changing code is going well. I think the trick is to NOT DOWNLOAD the modified FB until everything else is ready to work together. The should be a download modified objects options that will download ALL the modified FBs OBs and DBs that have been updated so that none are forgotten and cause the CPU to stop. At least I know what is causing this now and I know it isn't a programming problem but rather a downloading problem. It is obvious that Siemens doesn't know what I make file is. Actually, even make files are becoming obsolete now.
 
I am not sure why AR2 is needed. Looking at the FB500 code in STL shows that AR2 is not used anywhere until I try to use it.


AR2 is used in FBs in the background to access the IDB variables, and is set to 0 by the OS. By definition, an IDB is a stand-alone entity (you can't have an array of instance data blocks, for instance), and this is the only reason it is automatically set to zero, but is also why you can manually modify AR2 and make it point to anywhere you want, as I've decribed in other code samples.
To see that the IDB is just a container for symbols, you could try something like this (although you will see the effect in this example):

Code:
      L     5
      T     #Test1
      OPN   DI     1
      L     DID [AR2,P#0.0]
      L     DIW [AR2,P#0.0]
In the above snippet, #Test1 is an INT and is the first item in DI 5 (this code is in an FB that used IDB 5). I load a '5' into #Test1, but then I change the instance data block to a global data block (DB1), which is just an array of INTs. Note that what I posted is still in the editor and I haven't saved it yet.

Now, I save my changes, and what do I see?

Code:
      L     5
      T     #Test1
      OPN   DI     1
      L     DID [AR2,P#0.0]
      L     #Test1

The compiler automatically tries to match the symbol of the instance data block to any indirectly addressed variables, and because DB1.DBW0 and DB5.DBW0 both happened to be INTs, it mapped #Test1 to DB1.DBW0 even though the symbol in my DB1 is 'ThisIsATest[0]' (I just made an array of INTs). But, DB1.DBD0 doesn't match the data type, so it couldn't be converted and stayed as DID[AR2,P#0.0]. And, the 'L #Test1' won't return '5'; it will return whatever DB1.DBW0 is.

So, within the compiled code, the FBs just have instructions like L DIW[AR2,P#0.0], A DIX[AR2,P#16.4], etc. Simatic Manager does the translation.

And, this is why a lot of people don't even bother using instance data blocks anymore once they understand this. For one thing, IDBs are a pita (I think you realize this by now), and second, being able to do the same thing with any data I want at any location is much more valuable to me.

I know what you are trying to do. I just did the same thing recently (I had to code a PLC that sent UDP messages over ten different ports, with the length being set at runtime). The resulting code was actually very simple and very fast. If I had a customer that demanded it in ladder, I would just can it and give him a function call with input parameters.
 
Now i'm home so have access to S7 again since i change from job a week ago i don't haave the software anymore at the job wahtever here is a pic

Like you can see in the pic your offset of the sturct is in AR2 i didn't saved it and restore the AR2,

Otherthing you need to adjust in your code is
Code:
L DID[AR2,P#0.0]
 
Becomes 
 
L D[AR2,P#0.0]  // the Adressregister allready points to the instance see pictur DI4.0

I think with this and the perfect explanation of S7guy will help you forward. Don't forgot to save and restore the Area out of AR2

struct.jpg
 
Almost, there. Just two more problems..

I pass 64 to a VAR_IN COUNT. It is the number of REALs to transfer. When I load it is 0. I can look at the DB500 on-line and in the blue actual column it says it is 64. WTF?

You can see I load a 1 after the count just to make one cycle through the loop but the program stops because I am accessing memory I shouldn't be.
I get the Area length error when reading and
STOP caused by programming error (OB not load or.... this is a mystery to me because I can't scroll the message ). I know that all the objects are downloaded. Why can't the the diagnostic say which object it is looking for?
The stack doesn't tell me the rung but if I open the block I go to the T_DISC network just after the network I am trying to debug. The makes me believe that I something I am doing to the registers in rung I am trying to debug is messing up the code in the next rung.

Do I need to restore AR2 back to 0 before leaving the network? It seems to me that as long as I leave a 500 in DI I should be OK. Since Siemens hide the real code I can't see what is required by the next rung.

http://www.plctalk.net/qanda/attachment.php?attachmentid=11382&stc=1&d=1252524366

Picture 2.png
 
When it says OB not loaded, it means that you have not loaded OB to cpu that handles given error and prevents cpu from going stop mode when that error happens. Help gives listing on all OBs and what error they handle. Also diag buffer gives more info when correspondig OB is loaded, but cpu does not go to stop. That is why they should not be loaded if not programmed (in most cases).

You need to restore AR2 after using it before accessing any variable wich uses AR2 to know where it is.
 
That is interesting. Now I know why I don't need the DID and DIW. Back in the late 90s everything was hard coded so I have old examples with lots of DIW and DBD instructions.

Actually, everything I do still uses DIW and DBD. I just use the raw address without the data type, since I use the address for other things. Six in one and half dozen in the other.
 
When it says OB not loaded, it means that you have not loaded OB to cpu that handles given error and prevents cpu from going stop mode when that error happens.
The point is that the error is false, yet again.

You need to restore AR2 after using it before accessing any variable wich uses AR2 to know where it is.
OK, S7Guy made the point that when we see L #temp it is really doing L DIW[AR2,P#.0]. You see, this is what has been ****ing me off from the beginning. This has been hidden from me. It also explains why the AR2 must be reset back to the way it was at the beginning of the FB execution.
You see it didn't look like AR2 was being used anywhere until I used it.
When the S7 executed L #temp I though it was loading the address of the IDB from the IDB table using the 500 as an index and then adding the offset of #temp to it and AR2 wasn't required!

So now. If #temp has an offset of 0 and #temp2 has an offset of two. What does the compiler do? Does it add 2 to AR2? I doubt it. It must do this L DIW [AR2,P#2.0].

Hopefully I can save AR2 in VAR_TEMP variable and restore it from there. It is obvious that I will not be able to access stat. That explains why COUNT is loading 0 too. The point is that AR2 is ALWAYS being used to access IDB variables it is just hidden most of the time.
 

Similar Topics

is it possible to external read the Forced_value list from a PLC using UnityPRO? I need to get this data. It could be via modbus, ops... or even...
Replies
5
Views
2,450
So View SE 10 was the last to support HMI alarm tags. View SE 11 says you must migrate them to Alarm and Events. The View SE alarm summary will...
Replies
0
Views
1,901
I'm using an L33 PLC with an Ethernet I/P Point IO 1734-VHSC24 high speed counter to read in from an encoder, then calculating the counts per...
Replies
5
Views
1,769
So I have a dryer project that connects to the PLC and says "equal". When I connect it shows there are forced bits, but when I double-click on the...
Replies
3
Views
2,195
Hello All, I am using Allen Bradley Control Logix system, from the machine supplier I got the controller program developed in RS Logix 5000...
Replies
2
Views
2,041
Back
Top Bottom