Hi,
I'm using some object to develop a little app who read over modbus rtu a few devices.
The app is under linux on a Banana Pi m2+.
Starting from your examples, I'm using the serial port obj, the modbusrtudriver obj and a plctagnumber obj in a datamodule form because I need to have a console application.
All so good, but only if the app is running under an X environement, but I don't have the X on the target machine.
The wrapper I'm using now is to run my app with xvfb-run, but I think should be fine if the non-visual components from PascalScada will be gtk2 non dependant.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm using some object to develop a little app who read over modbus rtu a
few devices.
The app is under linux on a Banana Pi m2+.
Starting from your examples, I'm using the serial port obj, the
modbusrtudriver obj and a plctagnumber obj in a datamodule form because I
need to have a console application.
All so good, but only if the app is running under an X environement, but I
don't have the X on the target machine.
The wrapper I'm using now is to run my app with xvfb-run, but I think
should be fine if the non-visual components from PascalScada will be gtk2
non dependant.
Hi,
I'm using some object to develop a little app who read over modbus rtu a
few devices.
The app is under linux on a Banana Pi m2+.
Starting from your examples, I'm using the serial port obj, the
modbusrtudriver obj and a plctagnumber obj in a datamodule form because I
need to have a console application.
All so good, but only if the app is running under an X environement, but I
don't have the X on the target machine.
The wrapper I'm using now is to run my app with xvfb-run, but I think
should be fine if the non-visual components from PascalScada will be gtk2
non dependant.
Hi,
When I'm running your example in a console UNDER X, yes it works (in ubuntu 64 bits or in ubuntu arm).
But when the app is under a pure console (try in first console, alt+f1), the result is like in the picture .
Hi,
When I'm running your example in a console UNDER X, yes it works (in
ubuntu 64 bits or in ubuntu arm).
But when the app is under a pure console (try in first console, alt+f1),
the result is like in the picture .
Using cross-compile? Compiling it inside of banana pi? What are the
versions of Lazarus and FPC that you are using?
What is the PascalSCADA version that is you using? Have you downloaded it
from OPM?
The example is ok, there is nothing that injects the GUI dependencies.
Hi,
No, no cross-compile. For arm using lazarus 1.2.4 and fpc 2.6.4 with 0.7.3 PascalScada.
For x86_64 using lazarus 2.0.2 and fpc 3.0.4 with 0.7.5 PascalScada.
This infos are in the picture.
Hi,
No, no cross-compile. For arm using lazarus 1.2.4 and fpc 2.6.4 with 0.7.3
PascalScada.
For x86_64 using lazarus 2.0.2 and fpc 3.0.4 with 0.7.5 PascalScada.
This infos are in the picture.
Hi,
On the other hand, I have a questions regardind the "flow" of serial information.
Supose I have 3 tags: 2 PLCBlocks (plc1, plc2) and 1 PLCTagNumber (plc3).
The order I use them is:
plc1.Read;
plc2.WriteDirect;
plc3.Read;
For each ot them "RefreshTime" is set to 200, but usually they respond instant.
My question is: the software wait until it have an aswer from tags after each call (or 200ms), so after plc1.Read, if plc1 is online, I have already the dates received and ready to use? And so one after plc2.WriteDirect and plc3.Read?
Or, the request is send and the dates came (when it comes) on background?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I discovered (again) who is injecting the GUI dependency: the package IDEIntf. But it's related with your Lazarus Version, not with PascalSCADA. So, If I can suggest something to you, update your Lazarus and PascalSCADA versions.
About your last message. There are two parameters involved: Tag AutoRead = true ModbusDriver ReadSomethingAlways = true
If you write a value, Modbus replies with an error or successful messages. So if you are writing value and it's successful write on your device, the tag assumes the new value instantly. But if you are not writing, only reading, the property ModbusDriver.ReadSomethingAlways tells to the ProtocolDriver that, if it has nothing to do (all tags have a recent read, calculated Now-RefreshTime ms), the protocol will read the tag more out-of-date. So, with, your serial line will be busy all the time. Disable this and your serial will be busy only when some tag must be updated.
Tag.AutoRead only enables it on the scan of the protocol driver.
Another point is the procedure that are you using. Tag.Read and Tag.WriteDirect are synchronous. So your tag will be updated immediately. These procedures stop the ModbusDriver Scanner to get priority. The same for write.
Thank you for your answer.
Now, if I want to use my RS485 interface (using a 65176 chip) where should I modify the software to put "SenseBit := true" when the tag is requesting info over the serial line, and where to put "SenseBit := false" to reverse the modbus line?
It's ok in "protocoldriver.pas", in "TProtocolDriver.Write(const tagrec:TTagRec; const Values:TArrayOfDouble)" arround of line "res := DoWrite(tagrec,Values,true);"?
Something like:
SenseBit := true;
res := DoWrite(tagrec,Values,true);
SenseBit := false;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can do it using TProtocolDriver.Write(const tagrec:TTagRec; const
Values:TArrayOfDouble), but it's the same interface that Tag.Write and
Tag.WriteDirect uses to do synchronous writes.
This bit is stored in the holding registers of your Modbus device?
If yes, you can't change a single bit, you will always write 16 bits of the
register (one that you have changed, 15 with the last update from the
device). This is a limitation of Modbus function 06 and 16
If you are changing a coil bit is more simple, since Modbus functions 05
and 15 can write a single bit.
If you are using Modbus functions 03/06/16 to make your senseBit tag, use
entire register only for this function, to avoid write 15 bits with values
from past. Or use this register as WriteOnly: only your supervision system
should write on this register, your Modbus device should only read it.
If I understand correctly, you are writing a recipe or something like that,
and you are informing to your device to ignore it while you are writing the
new recipe on your device, right?
If yes, you need to do extra verification, like this:
implementation
uses Tag, ProtocolTypes;
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
myRecipeValues: TArrayOfDouble;
begin
//Build a block of values containg your recipe
SetLength(myRecipeValues,2);
try
myRecipeValues[0]:=10;
myRecipeValues[1]:=15;
PLCTagNumber1.Write($0001);
if PLCTagNumber1.LastSyncWriteStatus=ioOk then begin //sense bit is
write ok
PLCBlock1.Write(MyRecipeValues, Length(myRecipeValues), 0);
if PLCBlock1.LastSyncWriteStatus<>ioOk then begin
//action if your recipe isn't write into your device
//maybe:
exit;
//letting your sensebit locked with value=1?
//maybe raising an exception?
//note: as exit keyword, raise exception will abort the procedure
//and you senseBit will keep with value 1
raise exception.Create('OOOOppppssss... can''t write the senseBit');
end;
PLCTagNumber1.Write($0000)
end else
raise exception.Create('OOOOppppssss... can''t write the senseBit');
Thank you for your answer.
Now, if I want to use my RS485 interface (using a 65176 chip) where should
I modify the software to put "SenseBit := true" when the tag is requesting
info over the serial line, and where to put "SenseBit := false" to reverse
the modbus line?
It's ok in "protocoldriver.pas", in "TProtocolDriver.Write(const
tagrec:TTagRec; const Values:TArrayOfDouble)" arround of line "res :=
DoWrite(tagrec,Values,true);"?
Something like:
SenseBit := true;
res := DoWrite(tagrec,Values,true);
SenseBit := false;
You can do it using TProtocolDriver.Write(const tagrec:TTagRec; const
Values:TArrayOfDouble), but it's the same interface that Tag.Write and
Tag.WriteDirect uses to do synchronous writes.
This bit is stored in the holding registers of your Modbus device?
If yes, you can't change a single bit, you will always write 16 bits of the
register (one that you have changed, 15 with the last update from the
device). This is a limitation of Modbus function 06 and 16
If you are changing a coil bit is more simple, since Modbus functions 05
and 15 can write a single bit.
If you are using Modbus functions 03/06/16 to make your senseBit tag, use
entire register only for this function, to avoid write 15 bits with values
from past. Or use this register as WriteOnly: only your supervision system
should write on this register, your Modbus device should only read it.
If I understand correctly, you are writing a recipe or something like that,
and you are informing to your device to ignore it while you are writing the
new recipe on your device, right?
If yes, you need to do extra verification, like this:
implementation
uses Tag, ProtocolTypes;
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
myRecipeValues: TArrayOfDouble;
begin
//Build a block of values containg your recipe
SetLength(myRecipeValues,2);
try
myRecipeValues[0]:=10;
myRecipeValues[1]:=15;
PLCTagNumber1.Write($0001);
if PLCTagNumber1.LastSyncWriteStatus=ioOk then begin //sense bit is
write ok
PLCBlock1.Write(MyRecipeValues, Length(myRecipeValues), 0);
if PLCBlock1.LastSyncWriteStatus<>ioOk then begin
//action if your recipe isn't write into your device
//maybe:
exit;
//letting your sensebit locked with value=1?
//maybe raising an exception?
//note: as exit keyword, raise exception will abort the procedure
//and you senseBit will keep with value 1
raise exception.Create('OOOOppppssss... can''t write the senseBit');
end;
PLCTagNumber1.Write($0000)
end else
raise exception.Create('OOOOppppssss... can''t write the senseBit');
finally
SetLength(myRecipeValues,0)
end;
end;
Em qua, 21 de ago de 2019 às 06:39, Popescu Dragos
dragosp@users.sourceforge.net escreveu:
Thank you for your answer.
Now, if I want to use my RS485 interface (using a 65176 chip) where should
I modify the software to put "SenseBit := true" when the tag is requesting
info over the serial line, and where to put "SenseBit := false" to reverse
the modbus line?
It's ok in "protocoldriver.pas", in "TProtocolDriver.Write(const
tagrec:TTagRec; const Values:TArrayOfDouble)" arround of line "res :=
DoWrite(tagrec,Values,true);"?
Something like:
SenseBit := true;
res := DoWrite(tagrec,Values,true);
SenseBit := false;
Hi,
I'm using some object to develop a little app who read over modbus rtu a few devices.
The app is under linux on a Banana Pi m2+.
Starting from your examples, I'm using the serial port obj, the modbusrtudriver obj and a plctagnumber obj in a datamodule form because I need to have a console application.
All so good, but only if the app is running under an X environement, but I don't have the X on the target machine.
The wrapper I'm using now is to run my app with xvfb-run, but I think should be fine if the non-visual components from PascalScada will be gtk2 non dependant.
This is the example laz_console_app running in a pure console terminal.
Em Qua, 31 de jul de 2019 02:53, Popescu Dragos dragosp@users.sourceforge.net escreveu:
What's the example you are looking?
Em qua, 31 de jul de 2019 às 02:53, Popescu Dragos dragosp@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com
Hi,
When I'm running your example in a console UNDER X, yes it works (in ubuntu 64 bits or in ubuntu arm).
But when the app is under a pure console (try in first console, alt+f1), the result is like in the picture .
Can you send to me this example app?
Put it in:
https://mega.nz/megadrop/mHqhfY9fCzo
Em sex, 2 de ago de 2019 às 03:45, Popescu Dragos dragosp@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com
It's the same software from here: https://sourceforge.net/p/pascalscada/code/HEAD/tree/trunk/examples/laz_console_app/
I've just uploaded it.
Strange... How are you building this example?
Using cross-compile? Compiling it inside of banana pi? What are the
versions of Lazarus and FPC that you are using?
What is the PascalSCADA version that is you using? Have you downloaded it
from OPM?
The example is ok, there is nothing that injects the GUI dependencies.
Em sex, 2 de ago de 2019 às 09:40, Popescu Dragos dragosp@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com
Hi,
No, no cross-compile. For arm using lazarus 1.2.4 and fpc 2.6.4 with 0.7.3 PascalScada.
For x86_64 using lazarus 2.0.2 and fpc 3.0.4 with 0.7.5 PascalScada.
This infos are in the picture.
Under Desktop It works under desktop Console?
Is your banana pi is hardfloat? Can I try build this example for you using
the latest version of Lazarus and Pascalscada?
Em Sáb, 3 de ago de 2019 02:26, Popescu Dragos dragosp@users.sourceforge.net escreveu:
Yes, under desktop console it works.
Under pure console doesn't, unless I use the wrapper.
This is the compile message from Lazarus, under arm.
I don't know why gtk2.
Similat is under x86_64 arch.
TSourceEditor.AutoBlockCompleteChar
TBuildManager.CheckIfProjectNeedsCompilation SrcFile outdated Project
TCompiler.Compile WorkingDir="/opt/lazarus/Table/" CompilerFilename="/usr/bin/fpc" CompilerParams=" -MObjFPC -Scghi -O1 -g -gl -vewnhi -Fi/opt/lazarus/Table/lib/arm-linux -Fl/opt/gnome/lib -Fu/opt/LazarusCompo/pascalscada_0.7.3_20160726/lib/arm-linux-gtk2 -Fu/usr/lib/lazarus/1.2.4/components/ideintf/units/arm-linux/gtk2 -Fu/opt/LazarusCompo/SdpoSerial/lib/arm-linux -Fu/usr/lib/lazarus/1.2.4/components/lazcontrols/lib/arm-linux/gtk2 -Fu/usr/lib/lazarus/1.2.4/lcl/units/arm-linux/gtk2 -Fu/usr/lib/lazarus/1.2.4/lcl/units/arm-linux -Fu/usr/lib/lazarus/1.2.4/components/lazutils/lib/arm-linux -Fu/usr/lib/lazarus/1.2.4/packager/units/arm-linux -Fu/opt/lazarus/Table/ -FU/opt/lazarus/Table/lib/arm-linux/ -l -dUseCThreads -dUseCThreads -dLCL -dLCLgtk2 -dUseCThreads Table.lpr"
[TCompiler.Compile] CmdLine="/usr/bin/fpc -MObjFPC -Scghi -O1 -g -gl -vewnhi -Fi/opt/lazarus/Table/lib/arm-linux -Fl/opt/gnome/lib -Fu/opt/LazarusCompo/pascalscada_0.7.3_20160726/lib/arm-linux-gtk2 -Fu/usr/lib/lazarus/1.2.4/components/ideintf/units/arm-linux/gtk2 -Fu/opt/LazarusCompo/SdpoSerial/lib/arm-linux -Fu/usr/lib/lazarus/1.2.4/components/lazcontrols/lib/arm-linux/gtk2 -Fu/usr/lib/lazarus/1.2.4/lcl/units/arm-linux/gtk2 -Fu/usr/lib/lazarus/1.2.4/lcl/units/arm-linux -Fu/usr/lib/lazarus/1.2.4/components/lazutils/lib/arm-linux -Fu/usr/lib/lazarus/1.2.4/packager/units/arm-linux -Fu/opt/lazarus/Table/ -FU/opt/lazarus/Table/lib/arm-linux/ -l -dUseCThreads -dUseCThreads -dLCL -dLCLgtk2 -dUseCThreads Table.lpr"
Hint: Start of reading config file /etc/fpc.cfg
Hint: End of reading config file /etc/fpc.cfg
Free Pascal Compiler version 2.6.4+dfsg-4+rpi1 [2014/10/21] for arm
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for ARMHF
Compiling Table.lpr
I'll try reproduce your environment...
Em qua, 14 de ago de 2019 às 06:23, Popescu Dragos dragosp@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com
Hi,
On the other hand, I have a questions regardind the "flow" of serial information.
Supose I have 3 tags: 2 PLCBlocks (plc1, plc2) and 1 PLCTagNumber (plc3).
The order I use them is:
plc1.Read;
plc2.WriteDirect;
plc3.Read;
For each ot them "RefreshTime" is set to 200, but usually they respond instant.
My question is: the software wait until it have an aswer from tags after each call (or 200ms), so after plc1.Read, if plc1 is online, I have already the dates received and ready to use? And so one after plc2.WriteDirect and plc3.Read?
Or, the request is send and the dates came (when it comes) on background?
Hi!
I discovered (again) who is injecting the GUI dependency: the package IDEIntf. But it's related with your Lazarus Version, not with PascalSCADA. So, If I can suggest something to you, update your Lazarus and PascalSCADA versions.
About your last message. There are two parameters involved:
Tag AutoRead = true
ModbusDriver ReadSomethingAlways = true
If you write a value, Modbus replies with an error or successful messages. So if you are writing value and it's successful write on your device, the tag assumes the new value instantly. But if you are not writing, only reading, the property ModbusDriver.ReadSomethingAlways tells to the ProtocolDriver that, if it has nothing to do (all tags have a recent read, calculated Now-RefreshTime ms), the protocol will read the tag more out-of-date. So, with, your serial line will be busy all the time. Disable this and your serial will be busy only when some tag must be updated.
Tag.AutoRead only enables it on the scan of the protocol driver.
Another point is the procedure that are you using. Tag.Read and Tag.WriteDirect are synchronous. So your tag will be updated immediately. These procedures stop the ModbusDriver Scanner to get priority. The same for write.
Thank you for your answer.
Now, if I want to use my RS485 interface (using a 65176 chip) where should I modify the software to put "SenseBit := true" when the tag is requesting info over the serial line, and where to put "SenseBit := false" to reverse the modbus line?
It's ok in "protocoldriver.pas", in "TProtocolDriver.Write(const tagrec:TTagRec; const Values:TArrayOfDouble)" arround of line "res := DoWrite(tagrec,Values,true);"?
Something like:
You can do it using TProtocolDriver.Write(const tagrec:TTagRec; const
Values:TArrayOfDouble), but it's the same interface that Tag.Write and
Tag.WriteDirect uses to do synchronous writes.
This bit is stored in the holding registers of your Modbus device?
If yes, you can't change a single bit, you will always write 16 bits of the
register (one that you have changed, 15 with the last update from the
device). This is a limitation of Modbus function 06 and 16
If you are changing a coil bit is more simple, since Modbus functions 05
and 15 can write a single bit.
If you are using Modbus functions 03/06/16 to make your senseBit tag, use
entire register only for this function, to avoid write 15 bits with values
from past. Or use this register as WriteOnly: only your supervision system
should write on this register, your Modbus device should only read it.
If I understand correctly, you are writing a recipe or something like that,
and you are informing to your device to ignore it while you are writing the
new recipe on your device, right?
If yes, you need to do extra verification, like this:
implementation
uses Tag, ProtocolTypes;
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
myRecipeValues: TArrayOfDouble;
begin
//Build a block of values containg your recipe
SetLength(myRecipeValues,2);
try
myRecipeValues[0]:=10;
myRecipeValues[1]:=15;
write ok
PLCBlock1.Write(MyRecipeValues, Length(myRecipeValues), 0);
if PLCBlock1.LastSyncWriteStatus<>ioOk then begin
//action if your recipe isn't write into your device
//maybe:
exit;
//letting your sensebit locked with value=1?
//maybe raising an exception?
//note: as exit keyword, raise exception will abort the procedure
//and you senseBit will keep with value 1
raise exception.Create('OOOOppppssss... can''t write the senseBit');
end;
finally
SetLength(myRecipeValues,0)
end;
end;
Em qua, 21 de ago de 2019 às 06:39, Popescu Dragos dragosp@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com
If you have a Telegram account, plese join to PascalSCADA group.
https://t.me/pascalscada
Em seg, 26 de ago de 2019 às 10:00, Fabio Luis Girardi papelhigienico@users.sourceforge.net escreveu:
--
The best regards,
Fabio Luis Girardi
PascalSCADA Project
http://sourceforge.net/projects/pascalscada
http://www.pascalscada.com