Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read values from PLC memory #3

Closed
drunsinn opened this issue Jan 20, 2021 · 7 comments · Fixed by #4
Closed

Read values from PLC memory #3

drunsinn opened this issue Jan 20, 2021 · 7 comments · Fixed by #4
Assignees
Labels
enhancement New feature or request

Comments

@drunsinn
Copy link
Owner

Hey Max,

I want to read the PLC-memory to wait until a value changes using a WORD, MARKER or DWORD statement.

I sent a command that waits until the program state changes.

I've used the TNCcmd to send this statement and inspected it with Wireshark. I've found that it first makes a login with LOGIN_PLCDEBUG and then sends a command with R_MB (from PC to TNC) and get a response with S_MB (from TNC to PC)

I saw in the .client that the R_MB command was found via bruteforce test, purpose unknown but I didn't see the S_MB command.

Do you know a way how we can implement this reading of the PLC-memory in the code ?

Wouter

Originally posted by @WouterElfrink in #1 (comment)

@drunsinn
Copy link
Owner Author

Hello Wouter

to get the list in the code I checked every combination from R_AA to R_ZZ. For most I got an error message for an unknown command but some return errors like wrong parameters or problems with the Login-rights. I added them as comments to the code for documentation and to make sure I would not miss something in the future. My test probably never sent the correct data to get the response S_MB which is why I haven't documented it yet.

I have only very limited experience in working with PLC memory so it will take some time to work out how the payload is arranged.
Which command did you use in TNCcmd? GETVALUE? This command tries to log in with DATA and I get the response "wrong password".
By using my code directly I can login with PLCDEBUG and send R_MB just fine. If I send at least 4 bytes of payload I get the error message "bad memory address", anything less and I get "telegram not supported".
Can you provide the Wireshark capture and what you typed into TNCcmd?
I can only test on my programing station at the moment so my results might be different from a real machine. As soon as I have time at work I will check repeat the tests on real hardware!

Are you familiar with git? I have created a new branch for working on this topic, it is called "plc-read"

@drunsinn drunsinn self-assigned this Jan 20, 2021
@drunsinn drunsinn added the enhancement New feature or request label Jan 20, 2021
@drunsinn
Copy link
Owner Author

@WouterElfrink I think I have some good news!
I found a service manual for the iTNC 530 on some Russian site, it contains steps on how to view and change the content of the PLC memory on the control. In addition to that I found a tool by inventcom that also can read the plc memory. I have not tried I yet but I think it should be easy to replicate it's functionality.

My first assumption that it is enough to send four bytes seems to be wrong. I Sent out all combinations from 0x00 to 0xFFFFFFFF. This only gave me results for 0x40, 0x1D500, 0x1D8E8, 0x1DCD0, 0x27910, 0x27CF8, 0x280E0, 0x28170, 0x28558, each time only one byte. I have not jet found the pattern, I hope the tool will give me an idea what is going on.

@WouterElfrink
Copy link

Hey Max,

Via the TNCcmd I sent the command WAIT UNTIL a marker changed value, I dont know what marker precisely anymore but I think it had something to do with the change of the machine state.

I've used the Inventcom tool to read the plc memory using MARKERS, WORD and DWORD. I've used Wireshark to capture the data but at that time didn't understand much of it.

I'll try some more today to see if I can make something of it. And I'm curious what results you get.

And to answer this question

Are you familiar with git?

No it's all new to me, I used it to search for things etc. but never worked with it like we do now.

@drunsinn drunsinn linked a pull request Jan 22, 2021 that will close this issue
@drunsinn
Copy link
Owner Author

Good news! I think I got it working :-)

plc marker read

With the tip to use WAIT UNTIL I was able to discern that it actually needs five bytes of data to get a result. There dosen't seem to be any special logic for waiting, it just repeatedly polls the value form the control.
By reading the service manual I was then able to set the actual values manually to see what happens. This also helped with reading byte, word and double word values. The trick here is that they are actually read from the same memory area, just in different chunks.

The last pice of the puzzle was the tool by Inventcom. By checking with different programming stations I was able to see that they each had different magic numbers. After looking at the complete data stream I understood that the values can be read from the control, they are contained in the system parameters! I never knew what these values meant but now I know. Last but not least, the fifth byte is the number of values to read in one request, this can be up to 254 values (except for strings).

So, long story short, I have uploaded some code that can read values from the control by using the address and value type.

I have not tested this on any real machine, only on programming stations for TNC640, iTNC530 and CNCPILOT640. All seem to behave the same so I am very confident that it works as intended. The tool by Inventcom has the option to swap the byte oder for the numerical values but I have no idea in which situation this might be helpful.

The code to read marker M4321 looks like this:
lsv2.read_plc_memory(address=4321, mem_type=pyLSV2.LSV2. PLC_MEM_TYPE_MARKER)

In the scripts folder I added a new demo program that has some more examples on how to use the new function.

The code is currently not merged into the master branch, that means it is not yet part of the main code that can be installed via pip. Before I merge my changes I want to run some tests with a real machine.
You can see my changes by looking at pull request #4

@WouterElfrink
Copy link

Hey Max,
Good to hear that you got it working! I´m happy that you can help me with this.

I´m currently just looping through my code to check every 3 seconds if the program_state changes, and based the program state I run some statements.

My goal is to read the PLC-memory with the wait function so that it just waits until the state changes and then run the statements.

I look forward to try and test to see if its works!

Wouter

@drunsinn
Copy link
Owner Author

I did my tests with a TNC640 and everything seems to work fine. I have integrated the code into the master branch.
Please test and check if it works for you.

To wait for a change something like this should do:

while lsv2.read_plc_memory(address=4321, mem_type=lsv2.PLC_MEM_TYPE_MARKER)[0] is False:
time.sleep(3)

@drunsinn drunsinn reopened this Jan 25, 2021
@drunsinn
Copy link
Owner Author

Hello @WouterElfrink

FYI: I have just published version 0.6.2 which includes the plc read and I will close this issue since my tests have worked. Feel free to reopen it or create a new one if you have any problems!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants