PDA

View Full Version : Need a function to shift Floating point


Foty
November 22nd, 2005, 08:56 AM
I'm using a siemens plc, I was wondering is there a function that I could use to transfer Floating point (REAL) to a every 1/2 hrs to a different memory area.

Basically I'm getting the current from my drive and I would like to shift it so that I could take the new current every 1/2 hrs so like that I could monitor the current consumption, because I'm conducting a test.

Kidblue
November 22nd, 2005, 09:59 AM
You can simply use the 'MOVE' command in Siemens to move data into memory, but you will need to do a little more to obtain 'consumption'. Search the site for 'Totaliser' - this has been covered several times.....You then need to bung the data into the necessary formula to obtain whatever it is your trying to find (eg P=√3 VI Cos phi)


Hope this helps! :yeah:

Foty
November 22nd, 2005, 10:24 AM
That's what I'm doing for know, I add to a word and I have a few compares, which at every 1/2 hrs I then move the current to a different Real data.



I want to eliminate all that with a function like a shift but the only one that I fund was a shift word or double word.

SimonGoldsworthy
November 22nd, 2005, 10:24 AM
Here's my code snippet from OB35. I have set up OB35 to be called every 1000ms (using the h/w config editor), hence the need to count 1800 calls to OB35 before storing data. The data to be stored is assumed to be in MD106. I have not included to logic to reset the index back to zero or catered for running off the end of the DB...


L MW 100 //seconds counter
+ 1
T MW 100
L 1800
>=I
= #b30MinuteFlag

A #b30MinuteFlag
JCN nofg
L 0
T MW 100
OPN DB 1 //open data DB
LAR1 P#DBX 0.0 //ar1 points to start of DB
L MW 102 //get current index
SLD 5 //convert to real pointer
+AR1 //update
L MD 106 //get data
T DBD [AR1,P#0.0]
L MW 102 //update index
+ 1 //ready for next call
T MW 102

nofg: NOP 0

Foty
November 22nd, 2005, 10:47 AM
I will try it and adjust your function to fit it to my application. Thank you guys for the replies

10baseT
November 22nd, 2005, 12:28 PM
This one works nicely , you can modify to suit :-
It is surprising accurate , and you can set a threshold if required . There is the facility for current batch and last batch.


NW1
A #ENABLE_TOTALIZER
AN #RESET_TOTAL
= L 1.0
A L 1.0
A(
L #SCALED_FLOW
L #THRESHOLD
>R
)
A "SYS_0.2SEC_PULSE"
= L 1.1
A L 1.1
JNB _001
L #SCALED_FLOW
T #WORKING_FLOW_KGH
_001: NOP 0
A L 1.1
JNB _002
L #WORKING_FLOW_KGH
L 1.800000e+004
/R
T #WORKING_FLOW_KGS
_002: NOP 0
A L 1.1
JNB _003
L #WORKING_FLOW_KGS
L #WORKING_FLOW_ACC
+R
T #WORKING_FLOW_ACC
_003: NOP 0
A L 1.0
JNB _004
L #WORKING_FLOW_ACC
T #ACC_FLOW_BATCH
_004: NOP 0

NW2
A #RESET_TOTAL
JNB _005
L #WORKING_FLOW_ACC
T #LAST_BATCH
_00

NW3
A #RESET_TOTAL
FN #STAT0
JNB _006
L 0.000000e+000
T #WORKING_FLOW_ACC
_006: NOP 0

Foty
November 22nd, 2005, 02:15 PM
Hi 10baseT,



What I need I think is different from what you sent me. What I'm trying to do is to take a REAL (current floating point) and transfer it to a database using a pointer so that I keep a history. What I have done is I add 1 to word which gives me a pointer, then I compare that value; what I get is the first one equals to 1,I move the REAL to Database 1. In the next 1/2 hrs I add 1 again and it equals to 2, I compare the word to 2, I move the REAL to Database 2.


Is there a better way to do what I want?
:o:

10baseT
November 23rd, 2005, 10:03 AM
I have got quite a nice shift real if that would help - you can make the DB as big as you want .
nw1
L 0
>I
JC Nxt1
L 1
JU Err
//------------------------------------------------------------------------------
Nxt1: L #Stack_DB // Test for DB existence & get length
T #Test_DB_No
CALL "TEST_DB"
DB_NUMBER :=#Test_DB_No
RET_VAL :=#Test_DB_Ret_Val
DB_LENGTH :=#Test_DB_Length
WRITE_PROT:=#Test_DB_Write_Protected
//------------------------------------------------------------------------------
L #Test_DB_Ret_Val // Test for DB existence
L 0
==I
JC Tst2
L 1
JU Err
Tst2: AN #Test_DB_Write_Protected // Test for DB write protected
JC Tst3
L 2
JU Err
//------------------------------------------------------------------------------
Tst3: L #No_Of_Stack_Locations // Test for no. of stack locations
L 0 // less than or equal to zero.
>I
JC Tst4
L 3
JU Err
//------------------------------------------------------------------------------
Tst4: L #Stack_DB_Start_Offset // Test for stack start offset >=0
L 0
>=I
JC Tst5
L 4
JU Err
//------------------------------------------------------------------------------
Tst5: L #No_Of_Stack_Locations // Test stack fits into length of
ITD // specified DB
L L#1
+D
L L#4
*D
L #Stack_DB_Start_Offset
ITD
+D
L #Test_DB_Length
<=D
JC Tst6
L 5
JU Err
//------------------------------------------------------------------------------
Tst6: L #Stack_Out_Location // Test for stack output location >=0
L 0
>=I
JC Tst7
L 6
JU Err
//------------------------------------------------------------------------------
Tst7: L #Stack_Out_Location // Test for stack output location less
L #No_Of_Stack_Locations // than or equal to number of locations
<=I // in stack.
JC Cont
L 7
//------------------------------------------------------------------------------
Err: T #Error // On error load error code & exit
BEU
//------------------------------------------------------------------------------
Cont: L 0 // Continue execution if no error found
T #Error
nw2
L #Stack_DB // Load the DB number holding the stack
T #Stack_Temp_DB // Transfer it to a temporary variable
OPN DB [#Stack_Temp_DB] // Open the DB holding the stack
//------------------------------------------------------------------------------
AN #Pulse // If trigger pulse not set
AN #Clear_Stack // or not Clear_Stack then skip
JC Out // data movement & jump to load output
//------------------------------------------------------------------------------
// Calculate start address of top of stack
//------------------------------------------------------------------------------
L #No_Of_Stack_Locations // Load number of locations in stack
ITD // Convert to a double integer
L L#4 // Multiply by 4
*D
L #Stack_DB_Start_Offset // Load the stack start address offset
ITD // Convert to a double integer
+D // Add. Result is offset to destination
T #Data_destination // for first source value moved.
//------------------------------------------------------------------------------
// Move all data values in stack one location towards top of stack
//------------------------------------------------------------------------------
Loop: NOP 0
L #Data_destination // Derive the source value offset by
L 4 // subtracting 4 from the destination
-I // offset.
T #Data_source // Source 4 bytes below the destination.
L #Data_destination // Derive indirect pointer for Destination
SLD 3
T #Destination_Indirect
L #Data_source // Derive Indirect Pointer for the source
SLD 3
T #Source_Indirect
L 0.000000e+000 // Load Zero
A #Clear_Stack // If Clear selected then jump over the
JC Clr // load of source data, so that 0 is passed to the destination.
L DBD [#Source_Indirect] // Transfer source to destination
Clr: NOP 0
SAVE
T DBD [#Destination_Indirect] // Transfer either zero or source data to destination
L #Data_destination // Remove 4 bytes from the destination
L 4 // for the next scan
-I
T #Data_destination
L #Data_destination // Check to see if the destination is
L #Stack_DB_Start_Offset // below or equal to start address. This checks that
>I // all of the stack has been addressed. If not then
JC Loop // execute the stack move again.
//------------------------------------------------------------------------------
L #Stack_DB_Start_Offset // Derive indirect pointer for transfer
SLD 3 // of new data to bottom of stack.
T #Destination_Indirect
L #New_Data_In // Transfer new data to bottom of stack.
T DBD [#Destination_Indirect]
//------------------------------------------------------------------------------
// Fetch element from stack to be read and load into stack output location
//------------------------------------------------------------------------------
Out: NOP 0
L #Stack_Out_Location // Load element number to be read
ITD // Convert to a double integer.
L L#4 // Multiply by 4 to get element byte
*D // offset from bottom of stack.
L #Stack_DB_Start_Offset // Load stack DB start offset.
ITD // Convert to double integer.
+D // Add to element byte offset to get
T #Data_source // absolute source address for data.
L #Data_source // Derive indiract pointer for read data
SLD 3
T #Source_Indirect
L DBD [#Source_Indirect] // Load data and output it from the block
T #Stack_Data_Out
// -----------------------------------------------------

Foty
November 23rd, 2005, 11:50 AM
Well that looks interesting, it looks a bit long. But I will try it when I get a chance. What I was thinking was someting much simpler then that, but I still have not fund a way to use a pointer to move my Real to a data base.

aloudermilk
November 23rd, 2005, 01:15 PM
I believe the ATT and the FIFO functions from the standard Library would do what you want. You would have to initialise a data block but that is no big deal. Check them out.

krk
November 23rd, 2005, 01:28 PM
...but I still have not fund a way to use a pointer to move my Real to a data base


Foty,

The code Simon G posted in #4 above does exactly that...

10baseT
November 23rd, 2005, 02:14 PM
If you copy and paste the submitted code , you will find that it can be called as a nice function block that does as you wish ( assuming I understand your requirements ). You can make the DB as big as S7 will allow and shift real values through FIFO , it even gives you the chance to extract those at any location you wish , you can use a number of the same blocks adddressing the same DB and extract multiple locations - if change this block to do the same thing .This block does things that you don't want like check for write access to the block , and the validity of the addresses

Problem I see is that you need to decide what YOU want !

Foty
November 23rd, 2005, 03:28 PM
Good call 10baseT, I did not get a chance to test what you posted, I just look between meetings, and I should be able to test it later today.



Sorry for creating any doubts on WHAT I wanted, but I really appreciated the time you took to help me.

I will try it out and I will let you know what happens.



Thank you,


;)