Answers in the forums created
-
AuthorPost
-
StefanoParticipant
To power the measurement bridge of a load cell it is possible to take the 5V from the USB of one slimline (if present) or from the expansion bus?
StefanoParticipantI also notice one thing, provided I'm interpreting the data correctly:
10:48:04.730514|ModbusMaster:Tx|04 03 00 00 00 05 85 9C 10:48:05.553558|ModbusMaster:Rx|04 03 0A 82 3F 00 00 00 00 08 78 08 91 DF 75 10:48:06.054401|ModbusMaster:Tx|03 03 00 00 00 05 84 2B 10:48:07.183762|ModbusMaster:Rx|03 03 0A 82 3F 00 00 00 00 E8 B8 00 00 25 A2
Between the first sending and receiving, 800ms pass,
1100ms passes between the second sending and the reception.The devices are extremely slow to respond and this seems strange to me.
Are you sure the ModbusMaster is running often enough?
StefanoParticipantIf the communication is in RS485, have you tried to increase the "Delay" value in the ModbusMaster_V2 block?
Some devices take some time to free the RS485 bus after they finish transmitting. From experience, as long as only one device is interrogated there are no major problems, when more are interrogated it is better to ensure a suitable pause (10ms? depends on the devices) between the request to one node and to another.
StefanoParticipantI can also think of a C method that perhaps is more convenient for you:
- Page with all controls resting on locations on the panel. Then a curtain, or a numeric value, which indicates which set of PLC variables to read.
- A macro that runs every X seconds when the page is active that:
With a case pointing to the selection value it performs a GetData for all the PLC variables you need and places the data in local variables to the macro.
After the case do various SetData from the macro's local variables to the locations on which the controls are placed.
If the controls all have the same data type you can optimize a little: the controls lean on all sequential locations (for example three controls respectively on LW-0, LW-1, LW-2). In the macro you create an array of 3 elements. Three GetData, within the various houses, each write to an index of the array. Finally you do a single SetData with the array as the data to write, pointing to LW-0 and with data count equal to 3.
StefanoParticipantI've never used Siemens devices but I doubt that the logic to use in your case is:
GetData(read_data, device_name, device_type, address_offset, 1)
Then get the absolute address of the TAG (driver type "Absolute Addressing"), create a device_type/address array, use various "GetData" with the fixed device_type and choose which one to use with a case. Then put the address in a variable set to address_offset. If the variable is not allowed (I've never used this method before) then use the same case logic but using index registers.
The most "Weintekionian" method to do something similar to what you need I think is one of the two that I write to you below:
Method A:
In a page put all the controls supported by local variables. For each control/tag put a page data transfer. So if "Lamp A" refers to 10 possible tags there will be 10 data transfers to the address to which the control is supported. In the various data transfers use Security -> Enable/Disable from registry and with a macro go to Enable/Disable at runtime the data transfers you are interested in.
Method B without macros:
Create a page that has all controls leaning on local variables.
You create a transparent page for each set of tags you are interested in viewing. In the page settings, set the page with the controls as "page below" (it doesn't matter if it is placed in the field above, center or below). On the transparent page, put a page data transfer for each object related to the tag you want to view.
When the page is then changed, the controls displayed are always the same, but the data transfer objects that copy the values from the PLC to the local variable of the object change.
StefanoParticipantThis is my temperature capture code:
PROGRAM MyProgram VAR ALR_SENS_HEATER : BOOL; (* Sensor alarm *) AN_TEMP_HEATER : REAL; (* Temperature (°C) *) ANA_IN_2 : SysGetAnInp; (* Analog inout acquisition *) AV_IN_2 : Average; (* Temperature average *) END_VAR ANA_IN_2(Address:=3, Channel:=1, Mode:=AD_PT100_DIFFER); IF ANA_IN_2.Fault THEN ALR_SENS_HEATER:=TRUE; //Sensor alarm ELSIF ANA_IN_2.Done THEN AV_IN_2(Value:=ANA_IN_2.Value,Coefficient:=125.0); AN_TEMP_HEATER:=AV_IN_2.Average; //Temperature (°C) END_IF; // [End of file]
There was an electrical problem on the PT100 today. Probably the analog acquisition block returned some disproportionately high values. However, the error activated the Fault output, the thing is managed so the operator was informed of the problem. Maintenance fixed the electrical problem without restarting the system. The error signal had disappeared, therefore the operator did not see any failures, but after more than an hour the indicated temperature was 180°C, with a decreasing trend, against the real temperature of the probe around 22°C. This makes me think that the Average block was just "dirty".
My idea would be to support "Coefficient" to a variable that is set to zero when the SysGetAnInp block is in "Fault" and returned to the correct value at the end of the executed code when the block signals "Done". So I make sure that the Average block is "cleared" on the first read.
In a similar situation, therefore restoring the probe from a fault, might a sort of reset of the SysGetAnInp block also be necessary? Or maybe a physical PCB126C110 hardware reset?
October 26, 2022 at 3: 31 pm in response to: Error "eGetBYTE => Unknown function" in compilation #68383StefanoParticipantAlso solved the problem of pointers, now I am left with this, I have defined the variable
CNVDatetime: LDATETIMESTRUCT;
Used as an example "LogicLab (Ptp116, ST_DateTimeOperators)":
CNVDatetime: = TO_LDATE_AND_TIME (SysDateGetNs ());
The compilation shows:
ST_SerialDataReceive (192) - warning G0065: CNVDatetime => The destination type may be too small to hold the result
ST_SerialDataReceive (192) - error G0043: Module: armcodegen.cpp, line: 6299 => INTERNAL CODE GENERATOR ERROR
October 26, 2022 at 2: 59 pm in response to: Error "eGetBYTE => Unknown function" in compilation #68378StefanoParticipantI ran the command “Project -> Update current system” and the library was added automatically eLLabCommonlib.
Now I no longer have that error, but pointer assignments no longer work (eg: @Ptr: = Ch;) The test program is a slightly modified version of “LogicLab (Ptp116, ST_SerialDataReceive) Simple serial protocol ”, modified just enough to parse the string with a different logic.
Access operations with pointers are exactly the same as untouched.
StefanoParticipantAny news on this?
StefanoParticipantThe same thing happens to me with 2 Mt8073iE, they read data on RS485 (modbus RTU) and publish them in MQTT with internal broker.
After about 2 months of operation they stop communicating with the PLC.
To remedy, I restart them once a week.I have other same panels and have not encountered the problem, only on those where I use the MQTT protocol.
StefanoParticipantCould you have an example of SysVarsscanf with the format '% {% d%}' shown in the manual?
I made a test program with the string '123 456' and the format as above but SysVarsscanf always returns FALSE.
StefanoParticipantTo debug the application it would be useful to have a web page that shows the log of the strings arrived via serial. Exactly what the system web page that shows logs does. Is there a standard way to replicate it leaning against a different text file?
StefanoParticipantAfter countless tests I have come to the solution.
The fundamental problem is that the registers are not unsigned long (32 bit) but rather unsigned long-long (64 bit). Furthermore, one must be careful to always read a multiple number of registers of 2 starting from even addresses, otherwise the instrument goes into error.To read the two offending registers I relied on a macro that reads the registers, converts them into a 32-bit float and copies the value into a register on the panel.
It would not be the best because there will come a time when the value shown will be approximated, but for now that's enough for me. Below is the Macro:
macro_command main() unsigned int uiData[2] = {0,0} float energy = 0 GetData(uiData[0], "DMG110", 5x, 1b21, 2)// read 4 words active energy energy = uiData[0] energy = (energy + uiData[1] * 65536) / 100 SetData(energy, "Local HMI", LW, 30, 1) GetData(uiData[0], "DMG110", 5x, 1b29, 2)// read 4 words reactive energy energy = uiData[0] energy = (energy + uiData[1] * 65536) / 100 SetData(energy, "Local HMI", LW, 32, 1) end macro_command
March 12, 2022 at 1: 39 pm in response to: Modbus communication with Lovato DMG110 multimeter #64396StefanoParticipantWith EasyDiagnoser I found the error. A "2" error on a request was given by an address that does not exist on the device.
The other was error number 12 given by 2 successive requests:
[5x] 2031616/2
[5x] 2097152/2Corresponding to these indications from the device manufacturer:
1B20H 4 Total Active Imported Energy Total imp. Active Energy kWh / 100 Unsigned long-long
1B28H 4 Total imported reactive energy Total imp. Reactive Energy kvarh / 100 Unsigned long-longthe 4 that you see after the address is the number of words to read, they are 64-bit values. Obviously the device generates an error if all 4 words are not read consecutively. I believe the only way is with a macro.
PS all these values were published via MQTT. If an object has an incorrect address the object is simply not displayed. If the invalid address is among the MQTT data, the “PLC no response” message appears.
StefanoParticipantOk found: I have the version downloaded from the Weintek site and it is under the heading "Multiline" which is the only one I had not checked.
-
AuthorPost