Help with Indirect addressing

M4ndarr

Member
Join Date
Dec 2014
Location
Brno
Posts
9
Hello PLC gurus,
i would like to ask you for your help.
I have a little problem with indirect addressing, also with ST language.
My problem.
I have two DBs, where i have to take pointer from these and add this pointer to function like input.
and in next step i have to jump to another row in DB and add to input again after all rows in DB will be done.



L DW#16#A // NUMBER of DB
T #NUMBER_DB1 // z ACC1 do #NUMBER_DB1

L DW#16#2 // ACC110tka se presune do čísla
T #NUMBER_DB2

L 0
T #INDEX


CALL "TEST_DB"
DB_NUMBER :=#NUMBER_DB1
RET_VAL :=#Ret_Value
DB_LENGTH :=#LENGHT //lenght of DB #NUMBER_DB1 in word
WRITE_PROT:=#WRITE_PROT



OPN "IDB CM DD Valves" // i think can be OPN DB[#NUMBER_DB1]
LAR1
TAR1 #BaseAdrPointer_DB1


OPN "MT"
LAR1
TAR1 #BaseAdrPointer_DB2

Next: L #INDEX
INC 1
T #INDEX


//DB1
L #INDEX
L 20 //how many bites are for on row in DB
*I
SLD 3
LAR1 #BaseAdrPointer_DB1
+AR1
// TO temp_pointer_DB1 I dont know how can i transfer AR1 to Temp_pointer_DB1 (ANY) this was first idea
L D [AR1,P#0.0]
T LD 0
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8


//DB2
L #INDEX
L 30
*I
SLD 3
LAR1 #BaseAdrPointer_DB2
+AR1
//TO Temp_pointer_DB2
L D [AR1,P#0.0]
T LD 10
L D [AR1,P#4.0]
T LD 14
L W [AR1,P#8.0]
T LW 18



CALL "CM DD MT"
CM :=#Temp_pointer_DB1 //input is type ANY
NHT_MT:=2.000000e+003
CM_MT :=#Temp_pointer_DB2 //input is type ANY


L #INDEX
L 20
*I
L #LENGHT
==I
JC Next

Thank you for your help
 
Last edited:
Dear M4ndarr,
What do you mean for "i have to take pointer from these and add this pointer to function like input" can you be more clear?
There's too much confusion.. Can you post your project or fc here?
Thanks.
 
I could try to write information more specific.
Ok

1.step, I have two DBs
first DB 10 is filled of valves. every row is one valve and this row has 20bytes.
second DB 2, has array of UDTs, enought for all valves.

L DW#16#A
T #NUMBER_DB1 //Dword

L DW#16#2
T #NUMBER_DB2

These lines are for these DBs

2.
I dont know, how many rows are in DB 10
CALL "TEST_DB"
DB_NUMBER :=#NUMBER_DB1
RET_VAL :=#Ret_Value
DB_LENGTH :=#LENGHT
WRITE_PROT:=#WRITE_PROT

this function returm me a LENGHT of DB in bytes. And i know, one row is 20bytes.

3.
i have to open these DBs and transfer pointer 0.0 to baseAdrPointer and in next step i will count with this baseadrpointer.Like BaseAdrPointer+rownumber(INDEX)*20 = the row which i need
OPN "IDB CM DD Valves" //THIS Is DB10
LAR1
TAR1 #BaseAdrPointer_DB1


OPN "MT" /this is DB 2
LAR1
TAR1 #BaseAdrPointer_DB2

4.
I will take index of row, and shift it, because i need bytes not bits.
And plus with AR1. after that, i think i have pointer of adress which i need
In next step i transfer this pointer to Temp_pointer_DB1 which is in data type ANY.
//DB1
L #INDEX
L 20
*I
SLD 3
LAR1 #BaseAdrPointer_DB1
+AR1
// TO temp_pointer_DB1
L D [AR1,P#0.0]
T LD 0
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8

5. call my function
CALL "CM DD MT"
CM :=#Temp_pointer_DB1
NHT_MT:=2.000000e+003
CM_MT :=#Temp_pointer_DB2

6.
all again for all rows


FC3 - <offline>
"Call MT"

IN 0.0
OUT 0.0
IN_OUT 0.0
TEMP 0.0
Temp_pointer_DB1 Any0.0
Temp_pointer_DB2 Any10.0
NUMBER_DB1 Word20.0
NUMBER_DB2 Word22.0
ADDRESS_BYTE_DB1 Int24.0
ADDRESS_BYTE_DB2 Int26.0
LENGHT Word28.0
Ret_Value Int30.0
WRITE_PROT Bool32.0
BaseAdrPointer_DB1 DWord34.0
BaseAdrPointer_DB2 DWord38.0
INDEX Int42.0
RETURN 0.0
RET_VAL 0.0
Block: FC3
Network: 1
L DW#16#A// ACC110tka se presune do čísla
T #NUMBER_DB1// z ACC1 do #NUMBER_DB1#NUMBER_DB1
L DW#16#2// ACC110tka se presune do čísla
T #NUMBER_DB2#NUMBER_DB2
L 0

T #INDEX#INDEX
CALL "TEST_DB"SFC24 -- Test
Data Block
DB_NUMBER :=#NUMBER_DB1#NUMBER_DB1
RET_VAL :=#Ret_Value#Ret_Value
DB_LENGTH :=#LENGHT//delka DB #NUMBER_DB1 ve WO
RDU#LENGHT
WRITE_PROT:=#WRITE_PROT#WRITE_PROT
OPN "IDB CM DD Valves"DB10
LAR1
TAR1 #BaseAdrPointer_DB1#BaseAdrPointer_DB1
OPN "MT"DB2
LAR1
Next: TAR1 #BaseAdrPointer_DB2#BaseAdrPointer_DB2
L #INDEX#INDEX
INC 1
T #INDEX#INDEX
//DB1
L #INDEX#INDEX
L 20
*I
SLD 3
LAR1 #BaseAdrPointer_DB1#BaseAdrPointer_DB1
+AR1
// TO temp_pointer_DB1
L D [AR1,P#0.0]
T LD 0
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8
//DB2
L #INDEX#INDEX
L 30
*I
SLD 3
LAR1 #BaseAdrPointer_DB2#BaseAdrPointer_DB2
+AR1
//TO Temp_pointer_DB2
L D [AR1,P#0.0]
T LD 10
L D [AR1,P#4.0]
T LD 14
L W [AR1,P#8.0]//Hodnota pointeru z AR1 + 8 a presunu LongWord na adres
u 18 kde je nachází T_pointerCM_MT
T LW 18
CALL "CM DD MT"FC13
CM :=#Temp_pointer_DB1#Temp_pointer_DB1
NHT_MT:=2.000000e+003
CM_MT :=#Temp_pointer_DB2#Temp_pointer_DB2
L #INDEX#INDEX
L 20
*I
L #LENGHT#LENGHT
==I
JC Next

FC13
"CM DD MT"
IN 0.0
CM Any0.0
NHT_MT Real10.0HODNOTA NHT pro údržbu
OUT 0.0
IN_OUT 0.0
CM_MT Any14.0
TEMP 0.0
T_pointerCM Any0.0
T_pointerCM_MT Any10.0
T_ret_value Int20.0
Temp_CM UDT CM DD22.0
Temp_CM_MT UDT CM DD MT42.0
rozdil_DATE Bool72.0
rozdil_NHT Real74.0
RETURN 0.0
RET_VAL 0.0
Block: FC13
Network: 1
Nahrání bloků
L P##CM//nacteni bloku s motore/ventilem
LAR1
L D [AR1,P#0.0]
T LD 0
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8
CALL "BLKMOV"//Nacteni UDT Podle adress d
o Temp_CMSFC20 -- Copy
Variables
SRCBLK :=#T_pointerCM#T_pointerCM
RET_VAL:=#T_ret_value#T_ret_value
DSTBLK :=#Temp_CM#Temp_CM
L P##CM_MT//nacteni bloku s udrzbou
LAR1
L D [AR1,P#0.0]
T LD 10
L D [AR1,P#4.0]
T LD 14
L W [AR1,P#8.0]//Hodnota pointeru z AR1 + 8 a presunu LongWord na adresu
18 kde je nachází T_pointerCM_MT
T LW 18
CALL "BLKMOV"//Nacteni UDT Podle adress d
o Temp_CM_MTSFC20 -- Copy
Variables
SRCBLK :=#T_pointerCM_MT#T_pointerCM_MT
RET_VAL:=#T_ret_value#T_ret_value
DSTBLK :=#Temp_CM_MT#Temp_CM_MT


SOME logic in FBD

Network: 11 Save
CALL "BLKMOV"//UloženíSFC20 -- Copy
Variables
SRCBLK :=#Temp_CM_MT#Temp_CM_MT
RET_VAL:=#T_ret_value#T_ret_value
DSTBLK :=#T_pointerCM_MT#T_pointerCM_MT


I you need something more specifict, i will write it.
I will be so glad for all advice.

If is my idea of program wrong, just tell me. This is one part of my BACHELOR´S THESIS and actually i don't know anything about indirect addressing, just from some guides.
 
Last edited:
You have write a lot of code ,it's not so easy to understand what you want to do , but If I understand it, correct me if I'm wrong, you would like to copy the data from DB10 to DB2 offset by offset (row by row)?
 
I could try to write information more specific.
Ok

1.step, I have two DBs
first DB 10 is filled of valves. every row is one valve and this row has 20bytes.
second DB 2, has array of UDTs, enought for all valves.

L DW#16#A
T #NUMBER_DB1 //Dword

L DW#16#2
T #NUMBER_DB2

My code:
Code:
      OPN   DB 10
      L     DBNO
      T     #NUMBER_DB1
      L     DBLG
      T     #NUMBER_DB1_LENGTH

      OPN  DB 2
      L     DBNO
      T     #NUMBER_DB2
      L     DBLG
      T     #NUMBER_DB2_LENGTH


These lines are for these DBs

2.
I dont know, how many rows are in DB 10
CALL "TEST_DB"
DB_NUMBER :=#NUMBER_DB1
RET_VAL :=#Ret_Value
DB_LENGTH :=#LENGHT
WRITE_PROT:=#WRITE_PROT

this function returm me a LENGHT of DB in bytes. And i know, one row is 20bytes.

Code:
We have all information about length and db number!

3.
i have to open these DBs and transfer pointer 0.0 to baseAdrPointer and in next step i will count with this baseadrpointer.Like BaseAdrPointer+rownumber(INDEX)*20 = the row which i need
OPN "IDB CM DD Valves" //THIS Is DB10
LAR1
TAR1 #BaseAdrPointer_DB1


OPN "MT" /this is DB 2
LAR1
TAR1 #BaseAdrPointer_DB2

Code:
This to me is incomprehensible.

4.
I will take index of row, and shift it, because i need bytes not bits.
And plus with AR1. after that, i think i have pointer of adress which i need
In next step i transfer this pointer to Temp_pointer_DB1 which is in data type ANY.
//DB1
L #INDEX
L 20
*I
SLD 3
LAR1 #BaseAdrPointer_DB1
+AR1
// TO temp_pointer_DB1
L D [AR1,P#0.0]
T LD 0
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8

Code:
With this instruction you send in stop mode the cpu.
Index, which is the value?

5. call my function
CALL "CM DD MT"
CM :=#Temp_pointer_DB1
NHT_MT:=2.000000e+003
CM_MT :=#Temp_pointer_DB2

6.
all again for all rows







I you need something more specifict, i will write it.
I will be so glad for all advice.

If is my idea of program wrong, just tell me. This is one part of my BACHELOR´S THESIS and actually i don't know anything about indirect addressing, just from some guides.

See my code!
 
Sorry i wasnt here yesterday.
I have seen your code.
I have a question. Do i have to open DB to get their lenght?? I know, i have to open DB to use DBLG and DBNO. But when i use the function TEST_DB i cant i think.
Like OPN DB10 for example.

I could try to explain my problem much more specifict.

For example:
I can call function CM DD MT like this:
Code:
       CALL  "CM DD MT"
       CM    :="IDB CM DD Valves".Dummy      P#DB10.DBX0.0
       NHT_MT:=2.000000e+003
       CM_MT :="MT".Dummy                        P#DB2.DBX0.0

      CALL  "CM DD MT"
       CM    :="IDB CM DD Valves".C121XV01     P#DB10.DBX20.0
       NHT_MT:=2.000000e+003
       CM_MT :="MT".Spare[1]                        P#DB2.DBX30.0


      CALL  "CM DD MT"
       CM    :="IDB CM DD Valves".C141XV01     P#DB10.DBX40.0
       NHT_MT:=2.000000e+003
       CM_MT :="MT".Spare[2]                         P#DB2.DBX60.0
But in future i dont know how many valves will be in DB10. And direct addressing is unproductive.

in simple, i have to get basepointer of DB10 and DB2.. Pointer DB10.DBX0.0 and pointer DB2.DBX0.0.. save these pointers.

Call function CM DD MT with these pointers and in next cycle with pointers DB10.DBX20.0 and DB2.DBX30.0 ... in next cycle DB10.DBX40.0 and DB2.DBX60.0 to end of DB10.

Can you understand to my problem much more?

In my program i have #INDEX which mean.. where iam in rows.
For example #INDEX 0 is row 1 for DB10.DBX0.0 and pointer DB2.DBX0.0 ... #INDEX 1 for DB10.DBX20.0 and DB2.DBX30.0

Code:
[CODE]
I need to get some information from DB10 and DB2 , do some logic in function CM DD MT with these information and save on same row in DB2.
and do it for all row or struction. i downt know can i call it.
You have write a lot of code ,it's not so easy to understand what you want to do , but If I understand it, correct me if I'm wrong, you would like to copy the data from DB10 to DB2 offset by offset (row by row)?
[/CODE]

C9TQ.png
 
Last edited:

Similar Topics

I’m working with indirect addressing and trying to make an HMI where each Rectangle Object has a tag of “A[0-127]” with a correlating Push Button...
Replies
15
Views
4,142
Hi guys, New to indirect addressing is anyone able to help me with the attached file. I have tried the pen and paper method and first I put the...
Replies
11
Views
2,468
🙃 I have been scratching my head for a couple of days on this issue. I am in the process of converting a program from rs500 to Studio 5000...
Replies
7
Views
5,595
Some of you guys may remember I was getting some help on a roller door project a few months.. Lets say learning the ropes of what can be done...
Replies
2
Views
4,262
I have an oven that can contain a rack. I have two racks, "1" and "2", each of which can hold up to 6 parts. I load one rack via a robot that...
Replies
0
Views
1,246
Back
Top Bottom