Hi!
I just improved the support for expressions in the properties of PascalSCADA tags. At first moment, this feature was only available for the TPLCBlockElement.Index and TPLCStructItem.Index tags/properties. From today, is possible to use expressions on the following tag classes:
- TPLCTagNumber
- TPLCStruct
- TPLCBlock
- TPLCString
On these tags, is possible use and include in the expression the following properties:
- PLCRack
- PLCSlot
- PLCStation
- MemFile_DB
- MemAddress
- MemSubElement
- MemReadFunction
- MemWriteFunction
- Tag (you can only use this property on expressions in the properties mentioned above)
Below is a video that helps you understand the new feature:
Suggestions for improvements are always welcome!
Good day!
This components works with OPC DA?
Not yet. I started the implementation some time ago, but I stopped to put the efforts on others parts of the project.
Hi, Bro,
Whats different of PLCTagNumber.Value and PLCTagNumber.ValueRaw ?
Thanks
If you assign a scale processor in TPLCTagNumber.ScaleProcessor, the property TPLCTagNumber.Value will show the scaled value (engineering value) instead TPLCTagNumber.ValueRaw still showing the original value, read from your device.
Hi Fabio,
How will we use ScaleProcessor instead of ValueRaw to get Value
Thank You
Insert a TLinearScaleProcessor on your application
Configure it
On your tags that will use the same scale, set the property ScalProcessor of your tags to the TLinearScaleProcessor created on the first step
Note that a single Scale processor component (TLinearScaleProcessor, TUserScale) can be shared across multiples tags.
Hi Fabio,
Great……Job
Hi Fabio,
What are different for any write method on:
TPLCTagnumber, TPLCBlock, TPLCBloctElement since of all them use same parameters….
procedure Write(Values:TArrayOfDouble; Count, Offset:Cardinal); override;
Should we write from TPLCBlock or from Element ?
Thank you
Depends of what you want to do. But in summary, all synchronous writes will be redirected to the
procedure Write(Values:TArrayOfDouble; Count, Offset:Cardinal); override;
And the parameters will depend of your tag class and size (and offset or index, if you are doing that from a TPLCStructElement or a TPLCBlockElement).
This way allows you to map only the first element of a big block using a TPLCTagNumber, to use it to write a big data block using the procedure write mentioned above.
But as I wrote, depends of what you want to do…
Hi Fabio,
Thank you for your explanation.
From your explanation, we able to write block of memories address just using TPLCTagNumber.Write, but also using TPLCBlock.Write with same parameters.
For Offset parameter, please kindly explain clearly since we have already TArrayOfDouble and count.
Thank you
Hi Fabio,
We have block of memories in Arduino (15 location, 4 byte: addr from 0 – 14), Slave ID of Arduino is 1.
if we want write 1 location addr 2 only, should we configure:
PLCStation : 1
MemAddress : 2
Size : 1
TPLCTagNumber.Write(Value,1,offset);
Is it correct except “offset – still not clear” ?
Thank you
Hi Fabio,
We continue with block of memories in Arduino (15 location, 4 byte: addr from 0 – 14), Slave ID of Arduino is 1.
if we want write 3 location addr from 10 – 12, should we configure:
PLCStation : 1
MemAddress : 10
Size : 3
We should use TPLCBlock.Write(Value-array,3,offset), instead of TPLCTagNumber…….
Is it correct except “offset – still not clear” ?
For moment time we have able to read and write from Autoread/AutoWrite set to true.
Thank you
Hi!
The offset depends of:
** Protocol type
** Tag Class
** Tag.TagType property
Can you explain more about your configuration?
Hi Fabio,
Our Configuration:
SerialPortDriverMB: TSerialPortDriver;
BaudRate : br9600
COMPort: COM5
DataBits:db8
Noparity
Stopbits:sb2
ModBusRTUDriverArdu: TModBusRTUDriver;
CommunicationPort:SerialPortDriverMB
ArduRlBlockOpr: TPLCBlock;
ProtocolDriver:ModBusRTUDriverArdu
PLCStation:1 (same as Arduino)
MemAddress:2
Size:2
MemReadFuntion:3
MemWriteFuntion:16
In the Arduino side:
Slave Addr:1
Block of memories in Arduino (15 location, 4 byte: addr from 0 – 14)
And we used following code that doesn’t work:
procedure TfrmDiag.BtnSendModbusClick(Sender: TObject);
var
val: TArrayOfDouble;
begin
SetLength(val, 2);
val[1] := dataToArdu.STATE;
val[2] := dataToArdu.RESET;
bankTag.ArduRlBlockOpr.Write(val,2,0);
BtnSendModbus.Enabled:=false;
end;
But working as well if we configure AutoRead/AutoWrite to true
Thank you
Hi Fabio,
Our TagType : pttDefault
Thank you
Hi Fabio,
We continue with our own experiment with “Write” method.
The following code look doesn’t work.
procedure TfrmDiag.BtnSendModbusClick(Sender: TObject);
var
val: TArrayOfDouble;
begin
SetLength(val, 2);
val[1] := dataToArdu.STATE;
val[2] := dataToArdu.RESET;
bankTag.ArduRlBlockOpr.Write(val,2,0);
BtnSendModbus.Enabled:=false;
end;
Any Idea for it ?
Thank you
Thanks by your feedback.
Now that I know your config, is more easy to you explain how offset works.
On Modbus (RTU/TCP) the TagType pttDefault have 16 bits of length on functions 3 and 16, and no type conversion are made when receiving or sending values.
So, if the MemAddress of your tag (with TagType=pttDefault or tagType=pttSmallInt or TagType=pttWord, using modbus) is equal to 0, the offset=2 will simple start the write on modbus register 2 instead of 0, with Count registers of lenght.
But assuming that you are using 32 bits of length tags (TagType=pttLongInt, TagType=pttDWord or TagType=pttFloat) the offset will calculated:
RealMemAddress:=(SizeOfTag/SizeOfTargetArea)*Offset;
Writing on modbus holding registers (MemWriteFunction=16):
pttLongInt size = 32 bits;
MemWriteFunction=16 on Modbus Size: 16 bits
Offset = 2
RealMemAddress := (32 / 16) * 2;
So, the write of one LongInt tag will start at holding register 4;
The size of datablock that will be written is:
RealSize :=(SizeOfTag/SizeOfTargetArea)*Count;
Writing the same example above, with Count=5, will result:
RealSize :=(32/16)*5;
So doing:
MyTagLongInt.Write(ArrayWith5LongIntValues,5,2);
Will write 10 words, at the holding register MyTagLongInt.MemAddress + 4.
To help you, enable the log of the data exchanged between PascalSCADA and your Arduino by doing:
SerialPortDriverMB.LogFile := ‘c:\some path\some log file name.txt’
SerialPortDriverMB.LogIOActions := true;
Ahhh, Do you have activated your SerialPort? To activate it do?
SerialPortDriverMB.Active := true;
on your Form.OnFormCreate event
Hi Fabio,
Thank you for your kind time for help me.
Since it is midnight in Indonesia, let me try tomorrow.
Regards
Slamet
Hi Fabio,
We have tested and work as well…
TPLCTagNumber -> OK
TPLCBlock -> OK
Thank you
Another thing:
You should use a TPLCBlock instead of TPLCTagNumber, because the Write of TPLCTagNumber, the count and offset are hardcoded to 1 and 0, respectively.
Hi Fabio,
How do we resolve “Error reading SerialPortDriver” when application (PasccalScada) if Modbus-RTU devices are not connected to Host (Master) ?
Thank You.
Is simple. First of all, leave the property SerialPort.COMPort empty at design time. On your Form Create event put the following code:
try
SerialPort.COMPort := ‘COM5’;
SerialPort.Active := true;
except
//show some message telling about the missing serial port…
end;
Hi Fabio,
Thank….
Yes, also we did through RTTI -> Propertygrid…
Hi Fabio,
How can I write a 32bit analog register.
I know I must write two 16bit. But how can I config this in a tag?
Example please.
Id 1 address 2 register 2
Thanks
Hi!
Assuming that the area being read is 16 bits sized, set the property:
TagType = pttLongInt (for signed values)
TagType = pttDWord/pttLongWord (dont remember the property value for unsigned values)
and use
SwapBytes, SwapWords and SwapQWords to change de registers positions. You can set it in runtime to see what’s best fits to your needs.
Hi, thanks for answer. On modbus slave I have 32bit analog holding reg.
What swap type is the right?
Tagtyp pttlongint?
Hi!
Is your register?
a) a 32 bit signed int
b) a 32 bit unsigned int
c) a 32 bit floating-point
Depending on your response, Should you set the following value in TagType:
a) pttLongInt
b) pttDword
c) pttFloat
With the correct TagType, you should set the properties SwapBytes, SwapWords to match the Endian of your controller. You will have to make trial and error to find out the correct setup of SwapBytes/SwapWords properties. I can’t help you in this with more accurate information. The good is that, with the correct MemAddress and TagType set, you have only four combinations to test:
+———–+———–+
| SwapBytes | SwapWords |
+———–+———–+
| false | false |
+———–+———–+
| true | false |
+———–+———–+
| false | true |
+———–+———–+
| true | true |
+———–+———–+
One of these combinations should let you able to read the correct value from your controller.
The best regards,
Fabio
Hi, Fabio !
I work with PascalSCADA 0.7.5.0 from OPM.
Access with the TTCP_UDPPort, TISOTCPDriver and TPLCTagNumber works for Flags/MK (german: ‘Merker’) works without a problem. (Memreadfunc, Memwritefunc = 3, MemAdress = FlagAdress, PLCRack = 0, PLCSlot = 2, TagType = pttWord).
If i want to access DB 200:DBW2 it doesnt work and return and io??? Error ( I have no PLC actual for tests)
(Memreadfunc, Memwritefunc = 4, MemAdress = 2,Mem_FileDB=200, PLCRack = 0, PLCSlot = 2, TagType = pttWord).
With the Snap7 demoserver the access works, but not on a real S7-300 device. Have i forgotten/misconfigured something ? Or is PLCTagNumber not ok for DBs ?
BTW: I have no access to such a device, so i cant test directly.
Hi Andreas!
Your settings are right. I’ll hint you about symbolic addressing, but isn’t your case, since you are using s7-300. What’s the lastasyncreadstatus?
Hi Fabio,
it looks we have found the issue. We had a short timeslot for tests.
1st) We have a missunderstanding between PLC-programmer and us 🙂 The infos about DB-Nr and Byte-Nr were exchanged. So it was an access to an non existing DB.
2nd) The data in the DB are the last and we have accessed one byte to much. So it was an illegal access.
Now we can work with it, with DBs too. THX for the help.
Your PascalSCADA is a brillant and excellent work !!!
Hi!
Sorry for taking too much time to reply. Can you send an example that reproduces that?
Hi Fabio,
how is the config in pascalscada for input Register:
I will read input register 0x04 Adress: 1 Registers: 1 uint16t
Adress:100 Registers: 4 uint64t
Adress:200 Registers: 2 float
can you help me, whats for a tag i must use and the config of the tag?
thanks
I’m supposing that you are using Modbus. If yes, do you have seen that:
http://www.pascalscada.com/pb/modbus-rtu-and-tcp/
??
Hi Fabio I’m a newbie in Pascal and modbus. I have see it but I don’t understand it right.