Comments (13)
Oh, that seems to be a bug that was introduced with #40. I will look into it and get back to you.
from pylsv2.
Can you please check if there are any warnings or errors in the log?
from pylsv2.
I'm not getting any warnings or errors.
The output for addresses 356, 364, 368 and 360 doesn't change, it's always [4210752250] when reading via read_plc_memory()
function.
from pylsv2.
Ok, this seems to be more of a problem with the documentation than with th e code.
To get the same results with read_plc_memory
and read_data_path
you have to adjust for the actual size of the data type in memory. The current implementation of read_plc_memory
is taking care of that but the data path doesn't since it is decoded on the control. A double word (DWORD) is four bytes long, therefore the address has to be multiplied by four.
Example:
for mem_address in [0, 1, 2, 4, 8, 12, 68, 69, 151, 300, 368]:
v1 = lsv2.read_plc_memory(mem_address, pyLSV2.MemoryType.DWORD, 1)[0]
v2 = lsv2.read_data_path("/PLC/memory/D/%d" % (mem_address * 4))
assert v1 == v2
from pylsv2.
WHEN im trying this print("## double word: {}".format(con.read_plc_memory(8016, MemoryType.DWORD, 50))), return only 0 values i dont know why,this is the value in the cnc +66977274
from pylsv2.
I am seeing this same problem just with WORD as well, both calls worked and returned the same non-zero value in 0.7.7 but the latest versions are hitting this.
>>> con.read_plc_memory(39416, mem_type=MemoryType.WORD)
DEBUG:LSV2 Client:system parameters already in memory, return previous values
DEBUG:LSV2 TCP:telegram to transmit: command CMD.A_LG payload length 9 bytes data: bytearray(b'\x00\x00\x00\tA_LGPLCDEBUG\x00')
DEBUG:LSV2 TCP:received block of data with length 8
DEBUG:LSV2 Client:expected response received: RSP.T_OK
DEBUG:LSV2 Client:login executed successfully for login PLCDEBUG
DEBUG:root:memory type allows 126 elements per telegram, split request into 1 group(s)
DEBUG:root:current transfer group 0 has 1 elements
DEBUG:LSV2 TCP:telegram to transmit: command CMD.R_MB payload length 5 bytes data: bytearray(b'\x00\x00\x00\x05R_MB\x00\x0140\x02')
DEBUG:LSV2 TCP:received block of data with length 10
DEBUG:LSV2 Client:expected response received: RSP.S_MB
DEBUG:root:read 1 value(s) from address 39416
DEBUG:root:read a total of 1 value(s)
[0]
>>> con.read_data_path("/PLC/memory/W/39416")
DEBUG:LSV2 TCP:telegram to transmit: command CMD.A_LG payload length 5 bytes data: bytearray(b'\x00\x00\x00\x05A_LGDATA\x00')
DEBUG:LSV2 TCP:received block of data with length 8
DEBUG:LSV2 Client:expected response received: RSP.T_OK
DEBUG:LSV2 Client:login executed successfully for login DATA
DEBUG:LSV2 TCP:telegram to transmit: command CMD.R_DP payload length 24 bytes data: bytearray(b'\x00\x00\x00\x18R_DP\x00\x00\x00\x00\\PLC\\memory\\W\\39416\x00')
DEBUG:LSV2 TCP:received block of data with length 14
DEBUG:LSV2 Client:expected response received: RSP.S_DP
INFO:LSV2 Client:successfully read data path: \PLC\memory\W\39416 and got value '21'
21
from pylsv2.
@npalmerDNX
as mentioned in an earlier comment, the addressing works different between the data_path and plc_memory. In the case of a WORD, the factor is two.
In earlier versions of pyLSV2 the calculation of the correct memory address of the read_plc_memory function was wrong which lead to an offset. This meant that bigger chunks of memory returned broken values.
For read_data_path the calculation of the offset has to be done by the application.
from pylsv2.
I am including 2 screenshots of behavior that I am seeing and trying to validate against. I used the Inventcom testing tool for PLC data and noticed that my W20 shows 0 and W40 show 8.
I ran some test code using the pyLSV2 library to see if I could map those properly, but I noticed that the PLC call in the library returns an 8 not a 0 where as the datapath W20 instance (without changing the memory address like you show above) results in 0. If I apply the address adjustment like you mentioned it would get getting datapath W40 which is 8. I believe that the memory addressing used for the read_plc_memory is double the value that it should be.
def scan_plc(con, start=10000, end=19999):
results = []
for wnum in range(start, end, 1):
count = con.read_plc_memory(first_element=wnum, mem_type=MemoryType.WORD)
print(f"PLC W{wnum} = {count}")
results.append((wnum,count))
return results
def scan_datapath(con, start=10000, end=19999):
results = []
for wnum in range(start, end, 1):
if (wnum % 2) != 0:
continue
count = con.read_data_path(f"/PLC/memory/W/{wnum}")
print(f"Datapath W{wnum} = {count}")
results.append((wnum,count))
return results
res = scan_datapath(conObj, 10, 42)
Datapath W10 = 0
Datapath W12 = 30776
Datapath W14 = 25901
Datapath W16 = 0
Datapath W18 = 0
Datapath W20 = 0
Datapath W22 = 0
Datapath W24 = 0
Datapath W26 = 0
Datapath W28 = 0
Datapath W30 = 0
Datapath W32 = 2
Datapath W34 = 0
Datapath W36 = 0
Datapath W38 = 8
Datapath W40 = 8
res = scan_plc(conObj, 10, 42)
PLC W10 = [0]
PLC W11 = [0]
PLC W12 = [0]
PLC W13 = [0]
PLC W14 = [0]
PLC W15 = [0]
PLC W16 = [2]
PLC W17 = [0]
PLC W18 = [0]
PLC W19 = [8]
PLC W20 = [8]
PLC W21 = [0]
PLC W22 = [0]
PLC W23 = [32767]
PLC W24 = [0]
PLC W25 = [0]
PLC W26 = [0]
PLC W27 = [0]
PLC W28 = [0]
PLC W29 = [0]
PLC W30 = [0]
PLC W31 = [0]
PLC W32 = [0]
PLC W33 = [0]
PLC W34 = [0]
PLC W35 = [0]
PLC W36 = [0]
PLC W37 = [0]
PLC W38 = [0]
PLC W39 = [0]
PLC W40 = [0]
PLC W41 = [0]
from pylsv2.
This is very strange. If you look at
Line 112 in dc06e43
range(0, 500)
for all three tests still does not fail.
I think you also have a bit of a problem in your code. The modulo comparison basically skips every second element which results in an offset. Take a look at this and its output:
import pyLSV2
lsv2 = pyLSV2.LSV2("192.168.56.102", port=19000, timeout=5, safe_mode=False)
lsv2.connect()
for wnum in range(0, 42, 1):
v1 = lsv2.read_plc_memory(first_element=wnum, mem_type=pyLSV2.MemoryType.WORD)[0]
if (wnum % 2) == 0:
v2 = lsv2.read_data_path(f"/PLC/memory/W/{wnum}")
else:
v2 = "skipp"
v3 = lsv2.read_data_path(f"/PLC/memory/W/{wnum*2}")
print(f"Address {wnum:>5}: PLC {v1:>7} - DP*1 {v2:>7} - DP*2 {v3:>7}")
Address 0: PLC 0 - DP*1 0 - DP*2 0
Address 1: PLC 0 - DP*1 skipp - DP*2 0
Address 2: PLC 256 - DP*1 0 - DP*2 256
Address 3: PLC 770 - DP*1 skipp - DP*2 770
Address 4: PLC 255 - DP*1 256 - DP*2 255
Address 5: PLC 0 - DP*1 skipp - DP*2 0
Address 6: PLC 150 - DP*1 770 - DP*2 150
Address 7: PLC 0 - DP*1 skipp - DP*2 0
Address 8: PLC 0 - DP*1 255 - DP*2 0
Address 9: PLC 0 - DP*1 skipp - DP*2 0
Address 10: PLC 0 - DP*1 0 - DP*2 0
Address 11: PLC 0 - DP*1 skipp - DP*2 0
Address 12: PLC 0 - DP*1 150 - DP*2 0
Address 13: PLC 0 - DP*1 skipp - DP*2 0
Address 14: PLC 0 - DP*1 0 - DP*2 0
Address 15: PLC 0 - DP*1 skipp - DP*2 0
Address 16: PLC 0 - DP*1 0 - DP*2 0
Address 17: PLC 0 - DP*1 skipp - DP*2 0
Address 18: PLC 0 - DP*1 0 - DP*2 0
Address 19: PLC 0 - DP*1 skipp - DP*2 0
Address 20: PLC 0 - DP*1 0 - DP*2 0
Address 21: PLC 0 - DP*1 skipp - DP*2 0
Address 22: PLC 10080 - DP*1 0 - DP*2 10080
Address 23: PLC 0 - DP*1 skipp - DP*2 0
Address 24: PLC 0 - DP*1 0 - DP*2 0
Address 25: PLC 0 - DP*1 skipp - DP*2 0
Address 26: PLC 0 - DP*1 0 - DP*2 0
Address 27: PLC 0 - DP*1 skipp - DP*2 0
Address 28: PLC 0 - DP*1 0 - DP*2 0
Address 29: PLC 0 - DP*1 skipp - DP*2 0
Address 30: PLC 0 - DP*1 0 - DP*2 0
Address 31: PLC 0 - DP*1 skipp - DP*2 0
Address 32: PLC 0 - DP*1 0 - DP*2 0
Address 33: PLC 0 - DP*1 skipp - DP*2 0
Address 34: PLC 0 - DP*1 0 - DP*2 0
Address 35: PLC 0 - DP*1 skipp - DP*2 0
Address 36: PLC 0 - DP*1 0 - DP*2 0
Address 37: PLC 0 - DP*1 skipp - DP*2 0
Address 38: PLC 0 - DP*1 0 - DP*2 0
Address 39: PLC 0 - DP*1 skipp - DP*2 0
Address 40: PLC 0 - DP*1 0 - DP*2 0
Address 41: PLC 0 - DP*1 skipp - DP*2 0
As I see it, by multiplying the address for the data path with two I get the same result as with 'read_plc_memory'. The approach of skipping every other address gives an offset.
from pylsv2.
I ran your test script and I see that the values of PLC and DP2 are the same, but they are not the representation of what the W# is.
I have included the screenshot run at the same time to show that the PLC tool is showing a value that equals DP1 for W20 while the values shown from the test script PLC and DP2 are equal to DP1 of W40
You can see this pattern hold true for W6 PLC, DP2 vs W12 DP1 and W7 PLC,DP2 vs W14 DP1
Address 0: PLC 0 - DP*1 0 - DP*2 0
Address 1: PLC 0 - DP*1 skipp - DP*2 0
Address 2: PLC 0 - DP*1 0 - DP*2 0
Address 3: PLC 0 - DP*1 skipp - DP*2 0
Address 4: PLC 0 - DP*1 0 - DP*2 0
Address 5: PLC 0 - DP*1 skipp - DP*2 0
Address 6: PLC -21487 - DP*1 0 - DP*2 -21487
Address 7: PLC 25901 - DP*1 skipp - DP*2 25901
Address 8: PLC 0 - DP*1 0 - DP*2 0
Address 9: PLC 0 - DP*1 skipp - DP*2 0
Address 10: PLC 0 - DP*1 0 - DP*2 0
Address 11: PLC 0 - DP*1 skipp - DP*2 0
Address 12: PLC 0 - DP*1 -21487 - DP*2 0
Address 13: PLC 0 - DP*1 skipp - DP*2 0
Address 14: PLC 0 - DP*1 25901 - DP*2 0
Address 15: PLC 0 - DP*1 skipp - DP*2 0
Address 16: PLC 2 - DP*1 0 - DP*2 2
Address 17: PLC 0 - DP*1 skipp - DP*2 0
Address 18: PLC 0 - DP*1 0 - DP*2 0
Address 19: PLC 10 - DP*1 skipp - DP*2 10
Address 20: PLC 10 - DP*1 0 - DP*2 10
Address 21: PLC 0 - DP*1 skipp - DP*2 0
Address 22: PLC 0 - DP*1 0 - DP*2 0
Address 23: PLC 32767 - DP*1 skipp - DP*2 32767
Address 24: PLC 0 - DP*1 0 - DP*2 0
Address 25: PLC 0 - DP*1 skipp - DP*2 0
Address 26: PLC 0 - DP*1 0 - DP*2 0
Address 27: PLC 0 - DP*1 skipp - DP*2 0
Address 28: PLC 0 - DP*1 0 - DP*2 0
Address 29: PLC 0 - DP*1 skipp - DP*2 0
Address 30: PLC 0 - DP*1 0 - DP*2 0
Address 31: PLC 0 - DP*1 skipp - DP*2 0
Address 32: PLC 0 - DP*1 2 - DP*2 0
Address 33: PLC 0 - DP*1 skipp - DP*2 0
Address 34: PLC 0 - DP*1 0 - DP*2 0
Address 35: PLC 0 - DP*1 skipp - DP*2 0
Address 36: PLC 0 - DP*1 0 - DP*2 0
Address 37: PLC 0 - DP*1 skipp - DP*2 0
Address 38: PLC 0 - DP*1 10 - DP*2 0
Address 39: PLC 0 - DP*1 skipp - DP*2 0
Address 40: PLC 0 - DP*1 10 - DP*2 0
Address 41: PLC 0 - DP*1 skipp - DP*2 0
from pylsv2.
I still quite follow your reasoning. According to the memory tables on the control the address values are correct. If you check the screenshot I posted here, word 11 is the same as via the library as on the control.
If you are not happy with the current state you are more than welcome to create pull request for a new function that use another addressing scheme. Please note that since the current implementation works as far as I can see, and some other application might already use it the way it is now, I don't want to break compatibility.
from pylsv2.
I ran your test against my 530 simulator and I am still seeing the same results where the Address of IDX 20 returns 0 based on the PLC call but IDX10 shows the correct part count value. This also led me to review your screenshot a bit more to see where I was going wrong when I noticed that you were requesting W11 but the screenshot shows that the value is stored in W22 (second line Word 20 Column +2)
from pylsv2.
I interpreted the blue column numbers a bit differently. Since I have no manual I assume that these numbers count the number of bytes from the start of memory. The increments change when switching between byte, word and double from 1 to 2 to 4 but the line numbers only change when switching from byte to word or double. This lead me to believe that they count the number of bytes instead of the address of the memory value.
Again, if you prefer a function that uses the numbering scheme that counts bytes instead of the memory values I have no problem integrating a pull request. The current behavior is not broken, it works for all intents and purposes. Changing the existing behaviour is not a direction I want to take.
from pylsv2.
Related Issues (20)
- LSV2 transfer protocol HOT 3
- Few question HOT 11
- Cann't connect to the Haidenhain system (version TNC640) HOT 2
- Can we get the symbol name through the PLC address? HOT 9
- Integrated Oscilloscope in iTNC530 HOT 39
- Exception: AttributeError: module 'pyLSV2' has no attribute 'xxyyzzxxyyzz' HOT 2
- signals at long & short intervals together HOT 3
- Integrated Oscilloscope in TNC640 HOT 8
- i cannot read all the plc variables HOT 1
- System Parameters: Incorrect variable used for default initialization HOT 1
- iTNC 530 get_error_messages inconsistent? HOT 5
- memory loss and feedback HOT 4
- an error occurred while querying system information HOT 2
- File not Found Error
- How to locate Q parameters values HOT 3
- unexpected response 'RSP.T_BD' HOT 8
- table_reader ERROR:NCTable parser:File has invalid utf-8 encoding HOT 2
- Announcement of the discontinuation of the LSV2 protocol HOT 1
- pyLSV2.err.LSV2InputException: highest address is 15000 but address of last requested element is 26733 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pylsv2.