Posted 8 Dec 2021 hi david ott, i still don't understand what exactly is the problem? or why the SLMP communication should be changed to BINARY? Are you now concerned about the connection PLC to PC (nodejs) or the connection between robot/HMI to PLC? You wrote: "With such a setup in ascii format, the robot and HMI cannot communicate with PLC, but only PC can. So system needs to be changed to binary format." I don't understand how the change from ASCII to BINARY should change anything here, or why this should be necessary. If no other devices than the PC can connect to the PLC, you should check if you have configured enough connections in the network settings. If necessary you have to add more connections here. (Parameter|FXCPU|Module Parameter|Ethernet Port|External Device Configuration) If you still want to use the BINARY variant (although I doubt this is necessary) you have to modify the nodejs program accordingly of course. Share this post Link to post Share on other sites
Posted 9 Dec 2021 @AndreasW I got screenshot of the ethernet configuration. The port 1025 where PC should connect. If PLC is set to binary, the log shows that PC connected to PLC, but PC does not receive string started with 8100, but 3 symbols (no more data). Do you know where is the problem? Thank you for your help. Share this post Link to post Share on other sites
Posted 9 Dec 2021 hi david ott, i think the problem is that you send the wrong request. If you set the data code to BINARY, you have to change the nodejs and the Request you send to the plc. The request has to be send as Bytre-Array and not as a string. Also the response data from the plc can't be interpreted as string all you recieve are bytes. The response is no longer the string "8100" (4 bytes) but only 2 bytes with the value 81h and 00h, and if you use console.log to visualize/show these two bytes are interpreted as utf-8 characters and console.log will show the corresponding symbols to see the received bytes you can use an Buffer object, so in your nodejs program change the client.on function to show the received bytes. ///// nodejs (OLD) works for ASCII //////////////////////////////////// client.on('data', function(data) { console.log('Received: ' + data); <--- received data are ASCII coded so console.log can show them as STRING client.end(); }); ///// nodejs (NEW) //////////////////////////////////// client.on('data', function(data) { let buff= Buffer.from(data); console.log(buff); <--- Buffer object hold the received Bytes, console.log show the received Bytes client.end(); }); 1 person likes this Share this post Link to post Share on other sites
Posted 10 Dec 2021 (edited) @AndreasW I put the received data into Buffer. I got numbers: 176,91,16.This is frame message in binary code, not the stored data I guess. This is my request string: 01FF000A522000004E200900. I attached photo of the PLC settings what it should read and you can see what the received data was when PLC was set to ASCII. Now with binary I got above 3 numbers. Do you know how I can convert the numbers to get the numbers in PLC's current values column? Thank you Edited 10 Dec 2021 by DavidOtt Share this post Link to post Share on other sites
Posted 10 Dec 2021 (edited) hi David Ott, the response 91,16 (5Bh, 10h) is an error code, i think this is because the request you send to plc is wrong; -> could you show me the Request you send to PLC (for binary)? for your request string "01FF000A522000004E200900" (in ASCII) this should be something like: let sndBuff= new Buffer([1,255,0,10,0,0,78,32,82,32,9,0]); client.write(sndBuffer, ()=>{ timeout= setTimeout(()=> { console.debug('error: timeout occured, no data received for last ReadRequest'); EndConnection(); }, 1500); be aware that the position of the device code and the head device are switched in the binary version, see page 124 in the SLMP manual https://dl.mitsubishielectric.com/dl/fa/document/manual/plcf/jy997d56001/jy997d56001j.pdf Edited 10 Dec 2021 by AndreasW Share this post Link to post Share on other sites
Posted 13 Dec 2021 (edited) Hi @AndreasW If I use your lines above (sndBuff, I changed at client.write(sndBuffer) to sndBuff) the app receives data from PLC => Buffer.from(data) = 129,86. These 2 numbers are received. Do you know how I can convert to the original data as in PLC? Thank you Edited 13 Dec 2021 by DavidOtt Share this post Link to post Share on other sites
Posted 13 Dec 2021 hi david ott, if you receive 192, 86 (81h, 5Bh) this is the error code, because the send request is wrong, i forgot that the send buffer also need the data in high order, to receive R20000 and following register use the following send buffer: let sndBuff= new Buffer([0x01, 0xFF, 0x0A,0x00, 0x20,0x4E,0x00,0x00, 0x20,0x52, 0x09,0x00]); 0x01 ... command: batch read word units 0xFF ... pc-no 0x0A, 0x00 .... timeout (000Ah) 0x20, 0x4E, 0x00, 0x00 .... start adress (00004E20h .... = 20000) 0x20, 0x52 .... register type (5220h = R-Register) 0x09 .... number of register to read 0x00 ... endcode inside the receive function you have to convert/combine the received bytes to an 16 bit value (signed/unsigned, depending on the data type used in the plc) Therefore you can use an Int16 Array or an UInt16 Array. client.on('data', function(data) { let buff= Buffer.from(data); console.log('Received: '); console.log(buff); const int16array = new Int16Array( buff.buffer, buff.byteOffset, buff.length / Int16Array.BYTES_PER_ELEMENT); console.log(int16array); const uint16array = new Uint16Array( buff.buffer, buff.byteOffset, buff.length / Uint16Array.BYTES_PER_ELEMENT); console.log(uint16array); let value1= (buff[3] << 8 ) | buff[2]; let value2= (buff[5] << 8 ) | buff[4]; console.log('value1=' + value1); console.log('value2=' + value2); client.end(); }); Share this post Link to post Share on other sites
Posted 15 Dec 2021 Hi @AndreasW It's working. Thank you very much. I'm trying the same way wirting to PLC. So far this is what I have: I need to write 2-2-2 digits numbers to R19990~R19992, numbers are between 0-99 in decimal. ```var writeBuffer = new Buffer.from([0x03, 0xFF, 0x0A, 0x00, 0x16, 0x4E, 0x00, 0x00, 0x20, 0x52, 0x03, 0x00, input1format, input2format, input3format]);``` Where input1format (2,3 too) are string: '0x0'+input if input length is 1 and if input length is 2: '0x'+input. Input is the hexadecimal conversion of the 2-2-2 digits. I also need to write to R19999(writeMachineBuffer), I don't know if I can do that together with R19990~R19992 writing. So I would have 2 client.write. One with writeBuffer and another one with writeMachineBuffer. Can I do that or I should write once from R19990~R19999 and having 0x00 for R19993~R19998. Thank you for all your help. Share this post Link to post Share on other sites
Posted 16 Dec 2021 Hello David Ott, if there are only 10 registers you can of course simply write zero to the other registers (R19993-R19998) if these registers are not used in the PLC. If you do this, you should mark the registers as used/written in the device comments of the PLC, so that they are not accidentally used later. Alternatively you can use the function Test(Wrandom Write) to write only the selected registers, see page 133 in the SLMP manualhttps://dl.mitsubishielectric.com/dl/fa/document/manual/plcf/jy997d56001/jy997d56001j.pdf In both cases the values written are 16 Bit, that mean you have to write two bytes for each value (high byte and low byte, in the order LOW, HIGH). i.e. if the value to write is <= 255 (decimal) => High-Byte= 0x00, "var writeBuffer = new Buffer.from([0x03, 0xFF, 0x0A, 0x00, 0x16, 0x4E, 0x00, 0x00, 0x20, 0x52, 0x03, 0x00, input1format, 0x00, input2format, 0x,00, input3format, 0x00]);" if the value is > 255 the corresponding high byte must be written e.g. 16.589 (dec) = 40CD(hex) => 0xCD, 0x40 1 person likes this Share this post Link to post Share on other sites
Posted 16 Dec 2021 Hi @AndreasW Thank you for your advice. You wrote if value > 255 it should be in hexa. The buffer starts with 0x01, 0xFF, 0x0A, 0x00. Why 10 is written in hexa as 0x0A? It's less then 255. Also the R19999 register: 0x1F, 0x4E, 0x00, 0x00, 0x20, 0x52, where the R is 5220 which is larger than 255, but it was just split up and swapped. For 19999, hexa is used. I realized that I have to use Test(Wrandom Write) as you recommended too. I need to use registers R19990~R19999, but I cannot overwrite data in register with 0x00, I should leave data in register if there is data. I need to create 3 different writings: 1. machine 1 is used write to R19990~R19992 and R19999 or 2. machine 2 is used write to R19993~R19995 and R19999 or 3. 1 and 2 machines are used together write to R19996~R19999. If R19990~R19992 and R19999 is written, app should not overwrite data in R19993~R19998 I.e if input1 = 22, input2 = 40, input3 = 04 and machineUsed = 1 I cannot do this: new Buffer.from([0x03, 0xFF, 0x0A, 0x00, 0x16, 0x4E, 0x00, 0x00, 0x20, 0x52, 0x10, 0x00, 0x22 (input1), 0x40 (input2), 0x04 (input3), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 (machineUsed)]); On page 133 in FX5 documentation it is not clear for me if R19990~R19992 and R19999 is written: Number of devices for this example would be (R19990~R19992 and R19999) 2(?) or (R19990 and R19991 and R19992 and R19999) 4(?) My Test(Wrandom Write) would be as on page 133 and as I thought: new Buffer.from([0x05(subheader), 0xFF(PC No.), 0x0A, 0x00 (monitoring time in 2 parts), 0x04(number of devices?), 0x00 (fixed value),0x16, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 part), 0x00, 0x22 (input1 in 2 parts), 0x17, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x40 (input2 in 2 parts), 0x18, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x04(input3 in 2 parts),0x1F, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x01(machineUsed in 2 parts),]); Share this post Link to post Share on other sites
Posted 16 Dec 2021 hi david ott, you wrote: My Test(Wrandom Write) would be as on page 133 and as I thought: new Buffer.from([0x05(subheader), 0xFF(PC No.), 0x0A, 0x00 (monitoring time in 2 parts), 0x04(number of devices?), 0x00 (fixed value),0x16, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 part), 0x00, 0x22 (input1 in 2 parts), 0x17, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x40 (input2 in 2 parts), 0x18, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x04(input3 in 2 parts),0x1F, 0x4E, 0x00, 0x00 (head dev.# in 4 parts), 0x20, 0x52 (device name in 2 parts), 0x00, 0x01(machineUsed in 2 parts),]); this should be Ok except for the data values, but should write R19990- R19992 and R19999. i think for the inputvalues you have to switch the order of the High and the Low Byte: e.g. input1 = 22 (dec) = 16 (hex) --> 0x16, 0x00 (input1 in 2 parts) input2 = 40 (dec) = 28 (hex) --> 0x28, 0x00 (input2 in 2 parts) input3 = 04 (dec) = 04 (hex) --> 0x04, 0x00 (input3 in 2 parts) ... new Buffer.from([0x05, 0xFF, 0x0A, 0x00, 0x04, 0x00 ,0x16, 0x4E, 0x00, 0x00 , 0x20, 0x52 , 0x16, 0x00 , 0x17, 0x4E, 0x00, 0x00, 0x20, 0x52, 0x28, 0x00, 0x18, 0x4E, 0x00, 0x00 , .... If your input is a decimal number and if you don't want to convert it to a hex number you also can use the decimal number as input for the buffer, then just leave out the "0x" at the beginning. input1 = 22 (dec) = 22, 0 (input1 in 2 parts) input2 = 40 (dec) = 40, 0 (input2 in 2 parts) input3 = 04 (dec) = 4, 0 (input3 in 2 parts) new Buffer.from([0x05, 0xFF, 0x0A, 0x00, 0x04, 0x00 ,0x16, 0x4E, 0x00, 0x00 , 0x20, 0x52 , 22, 0 , 0x17, 0x4E, 0x00, 0x00, 0x20, 0x52, 40, 0, 0x18, 0x4E, 0x00, 0x00 , .... regarding the value 255: that was only a hint, which is about the High Byte. If the value is in the range 0-255 (dec) the high byte is 0 and the low byte is equal to the value, therefore it can be written in the buffer as [VALUE, 0] as above. For values > 255 (dez) it is easier to represent the number hexadecimal, because you can directly see the high/low byte. e.g. 16589 (dec) = 40CD(hex) => Low-Byte= 0xCD, High-Byte= 0x40 Share this post Link to post Share on other sites