plcpeople / nodepccc

Library for node.js to communicate with some Allen-Bradley programmable controllers (PLCs)
MIT License
81 stars 24 forks source link

writeItems callback always receives false #26

Closed srebling closed 5 years ago

srebling commented 5 years ago

Any idea why the writeItems callback is always passed a false parameter? This is after a connection is established and read/writes are successful. When controller is disconnected, writes continue to return complete with quality OK. After reconnect, reads begin working again but writes do not.

conn.writeItems(['STR0', 'INT0', 'STR1', 'STR2', 'INT3', 'INT4'], ['Setup Number', 2, 'Customer Name', 'Order Number', 211200, 500500 ], valuesWritten);

valuesWritten is always passed false, no matter what. ???

plcpeople commented 5 years ago

The parameter passed by valueswritten is intended to be false if everything was successful with the write, and true if there was an error with any of the items. Is there an issue with writes not working at all after a disconnect/reconnect? What is the best way to duplicate this?

srebling commented 5 years ago

The writes do not work at all after disconnect/reconnect. Here is some test code that duplicates the issue.

var nodepccc = require('nodepccc'); var async = require('async'); var conn = new nodepccc; var doneReading = false; var doneWriting = false; var writeInProgress = false; var setup_number = 'Setup Number 123';

conn.initiateConnection({port: 44818, host: '10.0.0.101', /routing: [0x01,0x02,0x01,0x00]/}, connected); // Either uncomment the routing or uncomment this next line for ControlLogix/CompactLogix or if otherwise using routing // First 0x01, 0x00 = 1 word in the path, second 0x01, 0x00 = Port 0x01 (backplane port of Ethernet module), 0x00 = PLC is in slot 0 in chassis.

function connected(err) { if (typeof(err) !== "undefined") { // We have an error. Maybe the PLC is not reachable. console.log(err); process.exit(); } conn.setTranslationCB(tagLookup);

conn.addItems('TEST8');

    async.forever(
        function(next) {
            //conn.readAllItems(valuesReady);

            conn.readAllItems(function (err, values) {
                if (err) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
                console.log(values.TEST8);
                doneReading = true;
                setTimeout(function () {
                  next();
                }, 1000);

// if (doneWriting) { process.exit(); } });

        },
        function(err) {
            console.log('READ LOOP ERROR: ' + err);
        }
    );

    async.forever(
        function(next) {

          if(!writeInProgress){
            conn.writeItems(['STR0', 'INT0', 'STR1', 'STR2', 'INT3', 'INT4'],
                            [setup_number, 2, 'Customer Name', 'Order Number', 211200, 500500 ], valuesWritten);
            writeInProgress = true;
            setTimeout(function () {
              next();
            }, 2000);

        }

        },
        function(err) {
            console.log('WRITE LOOP ERROR: ' + err);
        }
    );

}

function valuesWritten(anythingBad) { if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); } console.log("Done writing."); doneWriting = true; writeInProgress = false; }

// This is a very simple "tag lookup" callback function that would eventually be replaced with either a database findOne(), or a large array in memory. // Note that the return value is a controller absolute address and datatype specifier. // If you want to use absolute addresses only, you can do that too. function tagLookup(tag) { switch (tag) { case 'TEST1': return 'Test_Int'; // Integer case 'TEST2': return 'B3:0/0'; // Bit case 'TEST3': return 'B3/17'; // Same as B3:1/1 case 'TEST4': return 'F8:0,20'; // Yes this is an array... 20 real numbers. case 'TEST5': return 'F8:1'; // Single real. case 'TEST6': return 'F8:2'; // Another single real. case 'TEST7': return 'N7:1,2'; // A couple of integers in an array case 'TEST8': return 'NST9:2,4'; // Direct output case 'TEST9': return 'NST9:10'; // Direct output case 'STR0': return 'NST9:10'; // setup number case 'STR1': return 'NST9:11'; // customer name case 'STR2': return 'NST9:12'; // order number case 'STR3': return 'NST9:13'; // next operation case 'STR4': return 'NST9:14'; // generic comment case 'INT0': return 'L7:1'; // discharge direction (flags?) case 'INT1': return 'L7:2'; // sheet width case 'INT2': return 'L7:3'; // sheet length case 'INT3': return 'L7:0'; // sheets in discharge case 'INT4': return 'L7:1'; // sheets in discharge case 'INT5': return 'L7:6'; // stacks to batch default: return undefined; } }

plcpeople commented 5 years ago

Well I am able to duplicate the issue on my test setup but have to leave it for now. I will investigate more as soon as I can.