Jump to content

Porter

Members
  • Posts

    231
  • Joined

  • Last visited

  • Days Won

    27

Posts posted by Porter

  1. Be sure to double check the ASCII/RTU mode setting.

    Make sure that you are specifying the starting address in hex format. The PV value is supposed to be at holding register 0x1000.

    You could also try increasing the timeout value to 1000 or 2000ms (instead of the default 300ms).

    A screenshot of the dwyer communication setup and the Plasmionique Modbus Comm Tester setup would be useful.

     

  2. When you say Love Controller, do you mean a Dwyer "Love" Temperature Controller? They definitely work with this library.

    For configuring the USB-RS485 adapter, I have never used labview to specify 2-wire or 4-wire mode. That is usually done via hardware (dip-switches or jumpers) or the driver (device manager). I have never used the Tripp-Lite adapter though. I typically use USB-Serial converters from Moxa or Sealevel Systems. They have proven to work very will with labview.

    If you can provide the model number or user manual of the Love controller, maybe I can give you some example commands to try.

  3. I have been transitioning my framework's core libraries to packed project libraries. Unfortunately, the higher level PPLs depend on lower level PPLs, but i think that I've managed to sort out all of the broken connections. Now the issue that is bothering me is that whenever I open a project containing a higher level PPL, I get a bunch of "VI cannot be found on disk errors" that refer to VIs within the higher level PPL.

    Capture.PNG.2dc503d3e500f4882737bd19dd4929e2.PNG

    My initial thought was that the file paths were too long, but that doesn't seem to be the case. 

    Has anyone else come across this behavior when using PPLs?

     

  4. I thought that it would be nice to extend the muParser library's functionality to include automatic CVT tag lookup. This means that if you input an expression that contains CVT tag names as variables, their values will automatically be substituted during eval.

    This new CVT expression parser IS AN expression parser. So I tried to make a child of the mupExpr class. Who's silly idea was it to pass this class by reference?! LabVIEW doesn't support dynamic dispatch on class DVRs.:oops:

    So I've re-worked the mupExpr Class to wrap only the muparser handle (hParser) in a DVR. This gives a similar protection as wrapping the class in a DVR but allows us to pass the class by value instead.

    If anyone objects to this change, please shout out now before I commit changes to github.

    The code is attached, with an example: NICVT Expression Test.vi

    You need to install NI Current Value Table v.3.3.0 before opening the project.

    NICVTExpr.zip

  5. 18 hours ago, smithd said:

    I don't actually understand what the problem was with this. As you said in your comment on that issue, each access should be synchronous for a given master or slave, so there is no such thing as multiple transactions outstanding on the connection. The transaction ID check just sort of verifies that. If an error occurs, you must close the connection and reset. I can't think of any reason that would not be the right response, can you? I'm also confused by this because that part of the code was implemented by Tanner, who is the person who posted that issue to yours, so presumably he thought that code fixed the issue?

    Note that this behavior (close and reopen) is different from serial (wait, flush the buffers, and hope things start to work again), not because the serial way is better but because serial is a 5c chip twiddling the voltage on some wires. The serial version has no connection to close.

    His code has not fixed the issue yet. It does catch the error, as did Plasmionique Modbus Master, but it is up to you to catch the error and reset the connection. If you don't reset the connection, this can happen:

    1829283365_RegisterSwap.PNG.da936389fcfd244f6b043b8beff9d713.PNG

    Yikes! No errors being reported and read register 0 is returning the value for register 1.

    Tanner's proposed fix works. I implemented it in the Plasmionique Modbus Master. With it you can have multiple pending transactions. The responses will be matched up with the requests using the transaction ID.

    TCP Test.vi

  6. 18 hours ago, smithd said:

    I do, thats why I make sure to enable the term char.

    Hah. I didn't see that. I was looking somewhere else. But anyway, I don't see a case where you would only get a LF. In the ASCII protocol, a lone LF should never be sent within the message. And if, for whatever reason, a bit flips to make an LF, then hopefully the error would be caught by failing the CRC check.

  7. 17 hours ago, smithd said:

    I think I see what you mean and attached an implementation. Looks to be about 3x faster (edit: 2x with debug off) to read from the lookup vs calculating it out.

    Just a thought tho, it probably makes other code around it slower by completely trashing your CPU cache (its about 1/4 of the L2 cache on a zynq-based cRIO).

    For comparison, I copied the CRC calculation from the modbus spec. It's slightly faster (when run on my computer) than your method. I'm not exactly sure why though. And it uses less memory (512Bytes for LUT instead of 131kBytes).

    image.png.5ef570544c9010e149596d310998d3e8.png

     

    crc bench.vi

    CRC16_Modbus.vi

  8. On 11/30/2018 at 1:28 AM, smithd said:

    I got back to looking at the code today, I had forgotten but it looks like I did make the object thread-safe. All of the request-response calls are mutexed.

    It is thread safe as long as you use the same instance of serial master when communicating with multiple slaves on the same bus.

    I finally took a look at the code. I have a couple comments/questions:

    Serial Shared Components.lvlib->Configure Serial Port.vi: Case structure for number of stop bits. I suggest having some override for this. Maybe have a property node for the stop bits setting. I've come across a number of situations where I have needed RTU with no parity and one stop bit.

    RTU Data Unit.lvclass->Calculate CRC.vi: I think that there is a more efficient way to calculate the CRC using a lookup table. I'd be happy to share it when I get around to implementing it on Plasmionique Modbus Master.

    Serial Shared Components.lvlib->Serial Read.vi: I don't like the idea of polling the bytes at port every 8ms. Why not just read the specified number of bytes and let VISA handle the timeout?

    Serial Shared Components->Serial Read to CRLF.vi: Why not just read until LF (let VISA read take care of this)?

    ASCII Data Unit.lvclass->Read ADU Packet.vi: Why is start character written to request unit ID of Serial Data Unit? Shouldn't it be the unit ID?

    IP Data Unit.lvclass->Read ADU Packet.vi: Transaction ID mismatch will discard the packet. What will happen on a noisy network connection with multiple transactions being sent out? See: https://github.com/rfporter/Modbus-Master/issues/1

    Why does TCP Master/Slave need Protocol Read to CRLF.vi?

    TCP_NODELAY.vi: Cool... Was this ever used & tested?

×
×
  • Create New...

Important Information

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