AzeoTech

Administrators
  • Posts

    6,436
  • Joined

Posts posted by AzeoTech

  1. Its not a clash between the different notations, because the different notations don't really exist.  They are totally a figment of the documentation.  The actual Modbus packet only uses 0 notation.  The packet and the device know nothing about 40,001 notation.  This is what is so frustrating about Modbus, compounded by the fact that many manufacturers misunderstand it all and document their hardware incorrectly.  This is also why I pretty much exclusively convert my Modbus registers to 0 notation.   It also makes it easier to debug the packets when necessary, as the Channel # will match what you see in the comm monitor.  If you put 40,001 instead, DAQFactory (in most cases) will strip the 4 and subtract 1 for you before sending it out the comm port.

    What you've done is good debugging.  The next step would be to open the comm monitor and look at the packets with Show time of TX/RX enabled along with Display all ASCII chars as Codes.  It should be pretty obvious which of the two devices is having a problem.  The ID (D#) is going to be the first number when both transmitting and receiving.  You will likely see a Tx/Rx combo for one of the D#'s but only a Tx on the other.

    Next thing to try would be to set the Timing to 1 on both devices, but set the Offset to 0.5 on one of them.  This will cause the queries to stagger by 0.5 seconds.  Alternatively, start incrementing SetDelay() until it works, but I like the first method.   Then, if it works with an offset of 0.5, try moving the two queries closer together by changing the 0.5 to 0.75 or 0.25.  What I believe you will find is that one of your two devices is not letting go of the transceiver in a reasonable amount of time which is blocking further comms.  This exists in general for multidrop comms, but the amount is usually a few milliseconds.  In your case, it seems to be a lot more for one device, probably that last one you added.  This will prove it.  For example, if you leave D# 17 at offset 0 and set D#30 to offset 0.95 and you get time outs, then D#30 is the issue.  If you set D#30 offset to 0.05 and you get time outs, then D#17 is likely the issue.  If you have issues for all offsets, then I'd really need to see your comm monitor to tell anything more.

     

     

  2. Your question is simpler than some, and more complex than others.  Don't downplay your challenges!  The syntax will become more obvious the more you use the program.  Most of our users are none programmers, and either get what they need with little or no programming, or grow into programming while using DAQFactory.

  3. Your Event code should mostly work, though I would just write it as:

    if (Valve_1[0] )
       Valve_2 = 0
    endif

    The problem is that there will be a small delay from when Valve_1 opens to when valve_2 closes.  The other problem is that this won't prevent valve_2 from subsequently being opened.

    A better method is to use a Test Digital Out channel for each of the valves that act as a proxy to the real valves.  So, lets say you have tValve_1 and tValve_2 which are Test Dig Out channels.  In the tValve_1 Event you would put, say:

    if (tValve_1[0])
       Valve_2 = 0
    endif
    valve_1 = tValve_1[0]

    This will cause Valve_2 to close before valve_1 opens.

    Then, in tValve_2's event, you put the same sort of thing (assuming that is what you want):

    if (tValve_2[0])
       Valve_1 = 0
    endif
    valve_2 = tValve_2[0]

    But you could also make it so if you try and open tValve2 when valve1 is still open, it just doesn't do anything rather than closing valve1:

    if (tvalve_2[0]) // we want to open valve2
       if (valve_1[0]) // but valve1 is open
          tvalve_2.addValue(0)  // stick a 0 in tValve2 to indicate that we couldn't open it
          return   // and stop
       endif
    endif
    // otherwise, we are safe to control valve2:
    valve_2 = tValve_2[0]

    Using these proxy channels give you the ability to fully validate valve states before you change any valves.  The trick is that you should never be controlling the real I/O channels, Valve_1, Valve_2, etc from anywhere else in DAQFactory, but instead controlling their proxies, tValve_1, tValve_2, etc.  You can still display or log the status of Valve_1, but you shouldn't be controlling it, otherwise you'd be bypassing the checks.

     

  4. I always use 0 notation.  So when I see 30012 documented, and once I confirm that the docs aren't 0 indexed as well, I will put 11 into DAQFactory.  You strip the 10,000's place and subtract 1.

    I would start by disabling that new channel (set the timing to 0) and see if it goes back to working.  SetDelay(100) is going to be too big, as with 7 devices, you are talking about 700ms of wasted time each iteration, not counting any actual comms time.  I'd set that back to 20.  I've never seen it need more than 20.  The issue is just giving the RS485 line time to release, so it doesn't need to be long.

    If disabling that channel fixes it, reenable it and fix the issue with the channel #, as it should be 11, not 12.  Then set the timing for all your other channels to 0 and see if you can get the new device to work on its own.  Then slowly add back each of the old devices, maybe watching the comm monitor with time stamp enabled to see if there are any surprising delays.

    Also make sure you don't have any sequences controlling outputs while you are doing all this.  If you do have sequences controlling outputs, that may the issue.  SetDelay() applies after every query, and outputs can't be optimized, so each output command would add 100ms + comm time to the overall loop time.  If that overall loop time exceeded your Timing of 1, then you'd get Timing lags pretty quick.

     

  5. No problem.  We just didn't get the notification of the new post for some reason.  Sorry about that and I'm glad you followed up.

    Unless an if() statement is in a loop, it only executes once.  But aren't you calling the sequence from your event?  Or do you want it to just run, continuously checking the value.  If the second, then yes, you need to put a while(1) along with some sort of delay() to get it to check every so often.  Something like:

    while(1)
       if (...)
       endif
       delay(1)
    endwhile

    The delay should probably match the Timing of your input channel.  There is no reason to check it faster than the values are updating.

    As for comm errors, that's going to be on the LabJack side, but here are few items to note:

    1) you cannot run DAQFactory at the same time LJControlPanel or Kipling is running.  For that matter, you can't run it at the same time as any other program that is accessing the LabJack.  This is a limitation of the LabJackUD  and M drivers, not DAQFactory.
    2) watch out for using First Found (D# 0) and an actual ID at the same time in an application.  You should only use First Found if you only have one LabJack, and in my opinion, never, since inevitably, once you see how flexible the LabJack's are, you end up buying a second one!  If you have two, then it is possible that First Found will find the same LabJack that you specified the ID for, and it won't be able to open two connections to the device.  This becomes more complicated because First Found is not predictable on what it considers "first", so might give you a different LabJack when you restart DAQFactory.  So it might work for a while and then, after a restart, stop working.
    3) make sure you are running the latest drivers and firmware from LabJack.  Being fully updated fixes a surprising number of issues.

     

  6. You started to go down the right path, but didn't.  You need three variables, like the ZeroPoint1, ZeroPoint2, and ZeroPoint3 you declared in your SetGlobalZero sequence, which apply to each of the three lasers.  You created these and also ZeroPoint, but then used the same ZeroPoint variable for all three lasers.

  7. Yes, you can do that but you have to be careful.  Just remember that the script in the channel Event runs in the same thread as the Timing loop so any delay in executing the script could affect your timing.  For example, if you have your input channel timing set to 0.02, and you do the LJTic_DAC command and that takes 0.03 seconds, then your input channel will only read at every 0.03 seconds since it was tied up adjusting the LJTic_DAC.  That is why it is sometimes better to have a secondary loop in a sequence watching the input and tweaking an output separately.  That all said, in your case, you are probably fine...

  8. First problem is that DAQFactory won't support a 64 integer in general.  All numbers in DAQFactory are stored as 64 bit floating point values (double precision floating point) which basically gives you 52-53 bits of integer.  The rest is exponent.  So, really to read 64 bit integers you need to split it into two 32 bit values and process them that way.

    Moving on, you can pretty much do what you are asking with relatively simple bitwise math.  For example, to get just the least significant 16 bits of all values in an array, it is just:

    array & 0xff

    To get just bit 37 (numbered from 0):

    array >> 37 & 0x01

     

  9. Yes and no.  There isn't a built in HOA switch, but you can easily create your own using symbols from the Symbol Factory (or any other image you want to use).  I've attached a sample showing it.  It is made of 4 components to provide labels.  The main component is a symbol component that contains three symbols, one for each possible switch position.  Which is displayed is determined by the HOA channel.  Clicking the symbol steps through the options, Off then Hand then Auto then back to Off.  There are then 3 labels for each of the positions.  If you click on the label it will jump to that state.

    You can, if you expect to use the switch a lot, group it and basically make your own component out of it.  I would likely add script to allow for changing of the output channel, but that is a bit more involved.  If you are only going to use a few of these, you can just copy and paste the four components and manually change it.

     

    hoaSample.ctl

  10. Use a single Symbol component and add the three images, giving each image a different threshold depending on your coding.  I recommend 0 for off, 1 for hand and 2 for auto.  Then in the action, if you just want to step through the states put script like this (assuming "hoa" is the variable/channel with the hoa status):

    private temp = hoa+1
    if (temp > 2)
       temp = 0
    endif
    hoa = temp

     

  11. First what hardware are you using?  If you are using a LabJack you can use on of their timer modes to achieve this, though you may need to add a latching circuit, something so that the first sensor latches the output high, then the second sensor brings it back low.  But the folks at LabJack will know how best to do this hardware wise.

    You won't be able to do this without using a hardware mode due to the extremely short time frame.

  12. You'd have to check the power supply specs, but the absolute limit is going to be determined by ohms law: V = IR.  You can calculate (or measure) the resistance of 50 meters of your cable, then plug in your desired amperage, which at 48V, 7W would be 0.145 amps (note we want the amps on the wire which is 48V, not the 9V of your hub).  Multiply the two and you'll get the voltage drop across the wire.  Subtract that from 48V and that's the voltage you'll see at the other end.  You'll also have to watch for heating and the spec on the network cable should tell you the maximum amps supported.  Those are standard, non-signal carrying calculations.  There may be other factors that will further limit it.  We use Unifi access points and those are 7W with 19W passthrough and we don't have any issues. 

    Note that you aren't going to be able to plug a 9V hub/switch directly into a 48V PoE line.  I would look instead for a PoE powered switch.  I have a little Ubiquiti PoE powered switch on my desk.  It even has pass through for my phone, but of course does not provide PoE on its own since it doesn't have to be plugged into the wall.

     

     

     

     

  13. Hmm, not sure where you found the online guide.  It might be left over from a long time ago.  I'm pretty sure there isn't a link to it anywhere on our site.  Use the guide included in the download so you are sure you are using the one that matches your release.

  14. The correct way to start DAQFactory and load the .ctl doc in one step is described in 14.6 of the user's guide.  But essentially it is (for example):

    c:\daqfactory\daqfactory.exe "c:\my folder\my document.ctl"

    Personally I don't like putting spaces in my file names, but if you do, you have to include those quotes as I demonstrated.

  15. Please email us directly for any licensing issues as they can't really be discussed on an open forum.  Make sure and include your 15 letter key when you email.

    Usually a "License error occurred" error means one of two things:

    1) the license file got corrupted.  This is usually resolved using the technique you used, uninstall, delete folder, reinstall.   I believe you actually did resolve the issue, you just are having issues reinstalling the license, which often isn't required but appears to be in your case.

    2) you started DAQFactory in a way that it can't find the license file installed in your DAQFactory folder.  This usually happens when you start DAQFactory by clicking on the .ctl document instead of using a shortcut to the DAQFactory .exe file itself, or the Run In folder is set wrong.  This possibility is much rarer and only usually happens when you either install another application that uses .ctl extensions for their documents, or you install two copies of DAQFactory on the same machine then uninstall the second copy, leaving Windows' association paths wrong.

  16. I'm not sure if this will get you what you want, but on the running machine, instead of doing File - Save As, do File - Save As With History and save the file to a different name.  This will save the file just as normal, but also save all the accumulated history so you can play with that.  You'll also probably need to bypass the LabJack driver using the SetBypass() function described in 6.13 of the user's guide.

    I personally use a registry variable when I have extra code to disable some feature or another when testing offline, something like registry.debug.  It is set to 1 on my machine, but usually not set at all (which means it defaults to 0) on the production machine.  Then I make sure any custom script for working offline is inside a check for that registry variable being 1.  This makes the application run one way on my development machine, and another way on the production machine without me forgetting to remove or reset script I added.