plcpeople / nodeS7

Node.JS library for communication to Siemens S7 PLCs
MIT License
356 stars 120 forks source link

Need help for tags / address associations G120C drive #121

Closed aurelien49 closed 2 years ago

aurelien49 commented 3 years ago

Hello, In the README.md file it is stated that nodeS7 has the ability to read / write variables with G120C drives.

Is it possible to have an example of the tags / address association for a G120 drive ?

For a PLC it's working very well with something like : var variables = { TEST4: 'DB1,REAL0.20', // Array of 20 values in DB1 };

But, how I can do for read a variable from a drive? For exemple, I would like read the parameter "p2000".

I think I need add something in the nodeS7 file but I don't know what. // Default theItem.readTransportCode = 0x04;

switch (theItem.addrtype) {
    case "DB":
    case "DI":
        theItem.areaS7Code = 0x84;

......

Thanks a lot for your help.

aurelien49 commented 3 years ago

Nobody has a solution ?

ceremcem commented 3 years ago

This project is abandoned by the owner, AFAIR. It's working, but expect no support.

aurelien49 commented 3 years ago

Ok, I continu on myself to find out a solution. Thank you.

plcpeople commented 3 years ago

Sorry folks I know it seems like this project is abandoned but it isn't, we still use it, but the demand for free work and support on software is never-ending and there are only so many hours in a day. Questions on paying projects already take up far too many of those hours.

Note this requires firmware 4.7 or higher in the drive to work.

For initial connection to the drive, use the IP address of the drive and rack 0, slot 0. All examples use slot 1 or 2 but this time use 0.

Siemens has a document on accessing parameters in some G120 drives on their website. It's here. I am not sure if a G120C supports this same method but if it does, it likely follows this same pattern. https://support.industry.siemens.com/cs/document/109481157

And then we have a parameter list manual https://support.industry.siemens.com/cs/document/109782304

Step 1: Look up the parameter you want to read/write in the manual. Say you want to display r24 output frequency. It says it's a floatingpoint32 so that is real. It's not an array. So use data block 24.

Use INT and DINT for integer types.

For p2000 it's also floating point so use data block 2000.

Step 2: From this, to change to the format used by nodeS7, you would use the following addressing: OUTFREQ : 'DB24,REAL0'; REFFREQ : 'DB2000,REAL0';

Please let us know how this works to help everyone who finds this. If it works I will close the issue. I don't have one of these drives to test.

aurelien49 commented 3 years ago

Thank you very much for you reply, your advice and documentations.

Everything is working now. Below, I show some configurations that I tested. My problem with the drive was the slot number, I changed 1 to 0. And I tried to used directely 'p2000' instead of 'DB2000,REAL0'. Yes, even if it's for a drive, with the nodeS7 driver we can use 'DB...'

Thanks a lot. `


PLC settings: const PLCparams = { port: 102, host: '192.168.1.200', rack: 0, slot: 1 };

PLC READING: First case: Use symbolic names var variables = { DB5DBW2:'DB5,INT2.1' }; conn.setTranslationCB(function (tag) { return variables[tag]; });

conn.addItems('DB5DBW2'); conn.readAllItems(valuesReady);

Second case: Use direct address //var variables = { // DB5DBW2:'DB5,INT2.1' //}; //conn.setTranslationCB(function (tag) { // return variables[tag]; // }); conn.addItems('DB5,INT2.1'); conn.readAllItems(valuesReady);

PLC WRITING: First case: Use symbolic names var variables = { DB5DBW2:'DB5,INT2.1' }; conn.setTranslationCB(function (tag) { return variables[tag]; }); conn.writeItems('DB5DBW2', [ 789 ], valuesWritten); //conn.readAllItems(valuesReady);

Second case: Use direct address //var variables = { // DB5DBW2:'DB5,INT2.1' //}; //conn.setTranslationCB(function (tag) { // return variables[tag]; // }); conn.writeItems('DB5,INT2.1', [ 567 ], valuesWritten); //conn.readAllItems(valuesReady);


G120C DRIVE settings: const PLCparams = { port: 102, host: '192.168.1.201', rack: 0, slot: 0 };

G120C DRIVE READING: First case: Use symbolic names var variables = { P2000 : 'DB2000,REAL0', }; conn.setTranslationCB(function (tag) { return variables[tag]; }); conn.addItems('P2000'); conn.readAllItems(valuesReady);

Second case: Use direct address //conn.setTranslationCB(function (tag) { // return variables[tag]; // }); conn.addItems('DB2000,REAL0'); conn.readAllItems(valuesReady);

G120C DRIVE WRITING: First case: Use symbolic names var variables = { P2000 : 'DB2000,REAL0', }; conn.setTranslationCB(function (tag) { return variables[tag]; }); conn.writeItems('P2000', [ 4369.23 ], valuesWritten); // conn.readAllItems(valuesReady);

Second case: Use direct address //conn.setTranslationCB(function (tag) { // return variables[tag]; // }); conn.writeItems('DB2000,REAL0', [ 556.112 ], valuesWritten); //conn.readAllItems(valuesReady);


`

aurelien49 commented 3 years ago

Hello, I tried to mix transfer between my application and the 2 different devices, a SIEMENS PLC and a G120C inverter. One by one transfer, with 10 seconds between each transfer. I start the transfer manually. But nodeS7 stop working.

Exemple of situation: 1) I sent data from my application to the G120C inverter and it worked. The data are all in the G120C inverter. 2) I sent data from my application to the SIEMENS PLC and it worked. The data are all in the Siemens PLC. 3) I tried to send data again from my application to the G120C driver, and the connection/application stop.

Here the message: "[4168,434372200 192.168.1.201 S0] We Caught a connect error ECONNREFUSED We have an error. Maybe the PLC is not reachable. Error: connect ECONNREFUSED 192.168.1.201:102"

Is it possible to mix the transfer like I want to do with the nodeS7 or it's impossible.

I saw in the documentation the function "dropConnection()" and I tried this function to manage the end of connection after each complet transfer. But the nodeS7 driver tried to establish the connection itself, so I cannot stop the connection properly.

Do you have an exemple of how to manage different connections, please ?

In my case, the parameters are like this: For the Siemens PLC: const PLCparams = { port: 102, host: '192.168.1.200', rack: 0, slot: 1 };

and for the G120C inverter: const PLCparams = { port: 102, host: '192.168.1.201', rack: 0, slot: 0 };

If you can help, I thank you a lot.

aurelien49 commented 3 years ago

Hello again, After some tests, I can confirm that:

I can download several times from nodejs application to the G120C driver, it works. AFTER I can download several times from nodejs application to the Siemens PLC, it works. BUT I cannot download again from nodejs application to G120C driver. Download to the PLC works again.

Obviously, something block the G120C driver. What is wrong is a transfer inside the plc and AFTER inside the driver. It block the communication of the driver. A ping command works.

I tried to connect my laptop to the G120C driver with Siemens software but the connection never works.

For the moment, to solve the problem, I need to switch off/on the power supply of the G120C driver and AFTER, I can download again inside the driver.

On the digital screen of the driver, there is no message, no red light blinking.

If someone can help me. I'm a student and this application is my school project.

Thank you.

plcpeople commented 3 years ago

It sounds like you are creating many new connections to the drive and it can only accept so many before you reach the maximum connections the drive will allow - this might be why the Siemens software won't even connect. The PLC probably allows many more simultaneous connections than the drive which is why the problem is seen on the drive first. You have a few options depending on your application flow.

conn2 = new nodes7;

Then you would connect to the PLC with conn and the drive with conn2 and work with them separately.

aurelien49 commented 3 years ago

Thanks a lot for your solutions. Now I use your first solution, with 2 instances, and it's working.

I encountered another problem to read data, when the parameter is an array, like r8931, the actual IP address, Unsigned8. How is the right syntax to read a complete array parameter ? With the Siemens Software, I can see the values of the array: r8931[0] => 192 r8931[1] => 168 r8931[2] => 1 r8931[3] => 201

I tried to send this for the tag translation with the conn.setTranslationCB() function:

var variables3 = {
                r8931_0: 'DB8931,INT0',
                r8931_1: 'DB8931,INT1',
                r8932_0: 'DB8932,INT0',
                r8933_0: 'DB8933,INT0.2',
            };

// After exchange from nodejs application to the drive, I can log this:
{
  r8931_0: 'BAD 255',
  r8931_1: 'BAD 255',
  r8932_0: 192,
  r8933_0: [ 0, 255 ]
}

What I understand is, I can only read one sub parameter for a parameter by exchange with the driver.

With r8932_0, the result is correct because I ask only one value from the array.

Thanks you.

plcpeople commented 3 years ago

I think this is being broken by the optimizations that work well with "real" data blocks but not this mapped version in the drive.

Please try to change line around 64 in nodes7.js that reads self.doNotOptimize = false; to self.doNotOptimize = true;, or after you have done your conn = new nodes7 then add conn.doNotOptimize = true; and see if that helps. If it does I will update the docs and add to connection parameters.

aurelien49 commented 3 years ago

Hello,

I did the second modification, because I manage 2 different connections.

Just after the call, conn2 in my case is for the G120C drive:

let conn2 = new nodes7(true); conn2.initiateConnection(Driveparameters); conn2.doNotOptimize = true;

And the result is ok for me:

{ r8931_0: 192, r8931_1: 168, r8932_0: 192, r8933_0: [ 0, 255 ] }

And I tested a complete reading of the ip address:

var variables1 = { r8931_0: 'DB8931,INT0', r8931_1: 'DB8931,INT1', r8931_2: 'DB8931,INT2', r8931_3: 'DB8931,INT3', r8932_0: 'DB8932,INT0', r8932_1: 'DB8932,INT1', r8932_2: 'DB8932,INT2', r8932_3: 'DB8932,INT3', r8933_0: 'DB8933,INT0', r8933_1: 'DB8933,INT1', r8933_2: 'DB8933,INT2', r8933_3: 'DB8933,INT3', };

// And the results are good:

{ r8931_0: 192, r8931_1: 168, r8931_2: 1, r8931_3: 201, r8932_0: 192, r8932_1: 168, rp8932_2: 1, r8932_3: 201, r8933_0: 255, r8933_1: 255, r8933_2: 255, r8933_3: 0 }

Thousand thank you again.

plcpeople commented 2 years ago

doNotOptimize has been added as a connection option and documentation has been improved so I will close this issue.