Jump to content

Communicate with Omron E5CC using Modbus


Recommended Posts

I'm trying to read (PV process value) and write (SP set point) the temperature on a Omron E5CC temperature controller using LabVIEW, Modbus, RS-485.  I'm new to Modbus and have installed the free LabVIEW modbus library. LabVIEW "Create Serial Slave" seems straight forward, but I'm having issues with "Read Holding Registers".  I'm not sure what to input for "starting address" and "number of inputs".  I attached the E5CC communications manual, I just can't make sense of the addresses and commands and where/ how I use them in the LabVIEW code.  Also is there a easy command or operation I can execute to verify I can communicate with the device and all my protocol settings are correct?

Thanks

E5_C_CommunicationsManual_EN_201404_H175-E1-08.pdf

Link to comment

It looks like they deliberately made their terminology confusing. I cant imagine how they managed it unless they were actively trying ;)

First, obligatory intro to modbus document if you arent familiar: http://www.ni.com/white-paper/7675/en/

Skipping ahead to section 5 in your pdf you can see what you put in those fields. It looks like the easiest thing to check would be the 'status' field, so you'd enter either:
0x0002 for starting address and 4 for bytes to read, or
0x2001 for starting address and 2 for bytes to read

If you do this and get a visa error or error 56, it means you failed to communicate with the device. Depending on the library you are using there is an error range associated with modbus errors, meaning communication was successful but the device rejected your request. The object-based libraries return the modbus error code as a labview error code with an offset (eg error 100001 = modbus error 1) with the issue being to figure out what that offset is (varies by library). Pg 4-9 has the error codes possible for your device, which in this case are just two standard modbus errors 0x02 and 0x03.

If you get 56 or similar, be sure to check pg 1-2 for the right serial settings to use. It looks like your device might have a similar issue to what I described here with regards to # of bits.

The default configuration of your device does not appear to match the modbus protocol, instead it seems to match their custom protocol. However to their credit they take note of this in the * below the table in section 1-1-6.

Finally, if the NI one fails you, and you just need master functionality, try this one: http://sine.ni.com/nips/cds/view/p/lang/en/nid/214230

Edited by smithd
Link to comment

Thanks for the response.

I'm using what I believe is an updated free NI API module https://forums.ni.com/t5/NI-Labs-Toolkits/LabVIEW-Modbus-API/ta-p/3524019  (Link starts to download the Module http://forums.ni.com/ni/attachments/ni/7324/526/6/ni_lib_modbus_library-1.1.5.39.vip). However I tried to get help from the NI forums and got a NI response that they don't support this module..thanks.  They only support the modules that cost money.

Regardless I tried your advice, but haven't been able to read a hold register.  I think I'm still doing something wrong.  I'm not getting any response from the device including any error.  I attached a screenshot from my simple block diagram and GUI.  I thought maybe I should convert the HEX to DEC considering the API input is an integer type.  I also get the same response if I use "2001" for the starting address and any combination of RTU and ASCII too.  The TX light on my USB to RS485 adapter is also not illuminating.  I thought it would at least flash when I sent the command.

I'm also trying to contact Omron, but they haven't returned by emails.

I'm open to trying any other ideas.

 

 

Modbus VI 2017-04-12.PNG

Link to comment
20 hours ago, Nathan_MerlinIC said:

I also ran a NI I/O Trace to catch the exact string that was being sent to the device.  I attached a screenshot of the I/O Trace.  From what I can tell the read address status "0x3FFF0006" doesn't resemble the string I thought it would send.  Not sure if this helps.

That's the status return value of the viRead() function and is meant as a warning "The number of bytes transferred is equal to the requested input count. More data might be available.".

And as you can see, viRead() is called for the session COM12 and with a request for 0 bytes, so something is not quite setup right, since a read for 0 bytes is pretty much a "no operation". 

  • Like 1
Link to comment
19 hours ago, rolfk said:

That's the status return value of the viRead() function and is meant as a warning "The number of bytes transferred is equal to the requested input count. More data might be available.".

And as you can see, viRead() is called for the session COM12 and with a request for 0 bytes, so something is not quite setup right, since a read for 0 bytes is pretty much a "no operation". 

Note: by the time I got to the end I saw the issue but I'm leaving my thoughts here in case they help

I can't recall exactly but I believe that is still part of the init function (basically its a flush on init, get all bytes at port=0 and read that many bytes; note flush I/O buffer right afterwards which is the end of init). That is, that part of the trace makes sense (steps 1-12).

During the read, the RTU library must poll the port, which is why you see its getting attributes over and over again (in this case, bytes at port). Then close gets called, but the library continues to poll bytes at port, which makes no sense to me. Just based on the trace, I would assume there is a race condition but in the code there doesn't appear to be one. Finally, there is no *write*, which is important given that modbus is a request-response protocol.

The issue: It looks like in your sample code above you instantiate a new serial *slave* rather than a master. Since you want read values from another device, you want to create a serial master. That is why the trace is so bizarre, there *is* a race condition. Init (1-12) is called inline, and launches a background thread to poll the port (13-16), then your VI reads from the slave memory (local access of a data value reference) and immediately closes (step 17). I'm guessing the background thread then reopens the port (step 18) and continues polling (19-26)

Solution should be to change over to a serial master instance.

Edited by smithd
Link to comment
On 4/12/2017 at 10:22 AM, Nathan_MerlinIC said:

I'm using what I believe is an updated free NI API module https://forums.ni.com/t5/NI-Labs-Toolkits/LabVIEW-Modbus-API/ta-p/3524019  (Link starts to download the Module http://forums.ni.com/ni/attachments/ni/7324/526/6/ni_lib_modbus_library-1.1.5.39.vip). However I tried to get help from the NI forums and got a NI response that they don't support this module..thanks.  They only support the modules that cost money

Yes, that library is mostly unsupported now.

Thats part of the reason I tend to recommend Porter's implementation (http://sine.ni.com/nips/cds/view/p/lang/en/nid/214230) for master-only applications. He modeled the API after that one (1.1.5.39) but its totally open source (no locked diagrams) and he made some improvements to the serial handling.

Edited by smithd
Link to comment

I think we're making progress, but I still haven't been able to read the PV (temperature).  I switched to your recommended Porter's implementation.  I attached a screenshot of the block diagram and error that occurs when I run the vi.  I also attached my latest I/O Trace.  I think I'm reading line 28 from the trace correctly.  01-device ID, 03-read function, 07D1-starting address (2001), 0001-quantity of registers to read, 23-CRC-16 not sure what this means though.  I would anticipate a response in a similar format, but I'm not sure how to interpret line 29 and I assume since it is red there is probably an error.  The TX light flashes once when I run the vi.  Any suggestions?  I really appreciate the help.

NI IO Trace Modbus Comm 2017-04-17.PNG

Error 1073807339.PNG

Link to comment

thats more like it, now you can see where it writes the command (28) and then reads back up to 513 bytes in response (max size of modbus ascii).

the thing i missed before is you selected ascii, when your device seems to use modbus RTU. If you run that code again with ASCII changed to RTU, you should see the write (28) change as well to become a binary string. Read (29) will also change size.

Link to comment

I agree, according to the manual it uses modbus RTU.  However when I switched over I still get an error from LabVIEW and nothing reported from the register.  I can't decipher the write command line 27 and it look like the data length was changed from 7 bits to 8 (ASCII line 14 vs RTU line 14).  I found in the  data bits parameter and changed it to 7, but there wasn't any change to the results or trace (except that attribute).

The labview error is a timeout issue so I changed the devices response time to 10 ms from 20 ms, but still get the error.  The serial port configuration timeout is set to 100 ms, but I think the timeout comes from a VISA read in the RX ADU.vi.  I also get an error embedded in the Read Holding Registers "MB Master.lvib:MB_Master_Serial.lvclass:Querry.vi" Error 403483 "Invalid Modbus Session".  That error doesn't get reported at the top level vi, but it obviously sounds important.  Can you tell from the I/O Trace that I have the correct device communication protocol?

−1073807339 Timeout expired before operation completed.

NI IO Trace Modbus Comm 2017-04-18 RTU.PNG

Comm Spec.PNG

Link to comment

Another note in regards to the Comm Spec's.  I re-read the manual and saw if I'm using modbus I need, the communications data length must be 8 bits, and the communications stop bits must be 1 bit by setting the communications parity to Even/Odd or it must be 2 bits by setting the parity to None. I'm running data length 8 bits and stop bit 1 bit with Even parity.  I still get the timeout error during the VISA Read...still tracking it down.

I also figured out how to see the full Write Command.  I can now see how the Write Command is broken down into 01-Device, 03-Function Code, 07CF- Start Address (ex 1999), 0001- Address Qty, B541 (I still don't quite understand the CRC-16).  

Any suggestions on how to solve the timeout error would be much appreciated.

NI IO Trace Modbus Comm 2017-04-18 Write Command.PNG

Link to comment
2 hours ago, Nathan_MerlinIC said:

Another note in regards to the Comm Spec's.  I re-read the manual and saw if I'm using modbus I need, the communications data length must be 8 bits, and the communications stop bits must be 1 bit by setting the communications parity to Even/Odd or it must be 2 bits by setting the parity to None. I'm running data length 8 bits and stop bit 1 bit with Even parity.  I still get the timeout error during the VISA Read...still tracking it down.

I also figured out how to see the full Write Command.  I can now see how the Write Command is broken down into 01-Device, 03-Function Code, 07CF- Start Address (ex 1999), 0001- Address Qty, B541 (I still don't quite understand the CRC-16).  

It looks like you switched your register to read between code editions. Earlier you were requesting 8193 (0x2000) and now you are requesting 0x07CF which doesn't exist according to the manual.

The timeout just means the device never responded, which likely means your device never received the message or decided to ignore the message (for example if slave address doesnt match)

 

At this point, I'd suggest simplifying this down a bit. Drop down a visa open, then visa configure serial, potentially a property node, then a write and a read, then a close. (similar to the example in post 1 here https://forums.ni.com/t5/Instrument-Control-GPIB-Serial/Read-data-from-IED-using-MODBUS-RS485/td-p/1979105)

For the write, wire up a string set to hex mode set as "01 08 00 00 12 34 ED 7C"

For the read, specify a length of 8. You should receive an exactly matching string. This is according to pdf pg 89 (manual 4-15, section 4-4-4) of the manual you attached, which specifies an echo test. 

This way you can fiddle with the settings on the serial port until you get something back, at which point you should be safe to transfer those settings to the other two libraries and try again.

Edited by smithd
Link to comment

I would recommend trying the "MB_Master Comm Tester" (you can find this in example finder) to test the communication with the unit. This way you can just focus on the serial port settings and register addresses to start.

I've successfully used the Plasmionique Modbus Master library to communicate with an Omron E5CN controller. By default, I think that the units are configured for 4-byte mode, so the temperature PV is located at holding register address 0 and the number of registers that you read should be 2.

I also recommend that you start with a 1000ms timeout.

Link to comment

I found my wires were switched.  Apparently Omron calls out A- B+ and my adapter uses A+ B- and I wired it using the letters instead of the +/-.

Using Smithd's advice I went to a simple VISA chain and was able to read the hold register. Seems like the E5CC is using 2-byte mode.  My command was 0103 2000 0001 8FCA and it responded 0103 0200 A4B9 FF, I parsed out 00A4 (164 deg C).  Even though I was able to read the register I got error -1073676294  The number of bytes transferred is equal to the requested input count. More data might be available. I'm not too worried about the error at the moment since I'm so happy just to read the register.  I tried increasing the VISA read byte count from 7 to 8, but it didn't increase the return count of 7.

I wasn't able to get Porter's API to work even though I think I have the right comm protocol.  I get error 403482 Modbus CRC/LRC error.  The command sent is 01 03 07 D0 00 01 84 87 with a response that is split in two 01 03 00 and 20 F0.  Nothing was displayed in the Registers indicator on the GUI.

I'm going to start working on trying to write to the controller and set the temperature.  Please let me know if you have any insight into these errors.  Thanks for all your help so far.

Link to comment
1 hour ago, Nathan_MerlinIC said:

I found my wires were switched.  Apparently Omron calls out A- B+ and my adapter uses A+ B- and I wired it using the letters instead of the +/-.

Using Smithd's advice I went to a simple VISA chain and was able to read the hold register. Seems like the E5CC is using 2-byte mode.  My command was 0103 2000 0001 8FCA and it responded 0103 0200 A4B9 FF, I parsed out 00A4 (164 deg C).  Even though I was able to read the register I got error -1073676294  The number of bytes transferred is equal to the requested input count. More data might be available. I'm not too worried about the error at the moment since I'm so happy just to read the register.  I tried increasing the VISA read byte count from 7 to 8, but it didn't increase the return count of 7.

I wasn't able to get Porter's API to work even though I think I have the right comm protocol.  I get error 403482 Modbus CRC/LRC error.  The command sent is 01 03 07 D0 00 01 84 87 with a response that is split in two 01 03 00 and 20 F0.  Nothing was displayed in the Registers indicator on the GUI.

I'm going to start working on trying to write to the controller and set the temperature.  Please let me know if you have any insight into these errors.  Thanks for all your help so far.

-1073676294 should be a warning, not an error, and is expected. Most protocols are CRLF delimited, and so if you request say 100 bytes and get a full 100 bytes rather than hitting a CRLF, it might mean you didn't read a big enough packet. Were I to develop VISA I probably wouldn't put it in every read call but hey.

The CRC error is weird, I'd let porter answer that one if he can. Do you get a similar CRC error with the v1.1.5.39 lib?

Link to comment

I suspect that you've entered the address of 2000 in decimal format instead of hex 0x2000. Please check the radix of the "starting address" control. d = decimal, x=hex.

2000 in decimal format equals 0x07D0 in hex as indicated in the sent command 01 03 07 D0 00 01 84 87.

Not sure why its reporting bad CRC instead of exception code 2: invalid data address (error 403462) but it might have something to do with how the E5CC handles a read request at address 0x07D0.

Link to comment
  • 9 months later...
On 20/4/2017 at 11:55 PM, Nathan_MerlinIC said:

Porter, you were right I needed to change the address to hex.  Now everything seems to be working.  I can read and set the temperature.  Thanks again!

Could you please send me a working VI for E5CC? (Tell me too what kind of configuration you are using: parity, Baud Rate, Stop Bits...) I'm having a great headache with this communication, and I would be very pleased if you can help me. I have tried everything!

Link to comment
  • 1 month later...
  • 4 months later...
  • 11 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.