Jump to content

robijn

Members
  • Posts

    171
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by robijn

  1. Error 56 sounds logical. It only means that there was no data received in time. This has nothing to do with the TCP timeout (which I think you cannot set from within LabVIEW). If you only read and don't receive anything the connection is not considered lost at all. The other side just didn't send anything. It is only after some data is tried to be send and no acknowledge is received from the other side that the TCP layer will say that the connection is lost. But that is usually only after a considereable time (at least half a minute but possibly a few minutes). This is why it is often good to have some form of keep-alive built into your app, a packet that is sent from both sides at regular intervals. At least then you detect when the connection is lost.

    Joris

  2. About the third point. What I suggest is that the connector pane would complitely determine the behaviour of the VI. This means that there should be something similar to the dynamic dispatch terminal in static VIs. This terminal wouldn't affect dispatching but would determine if the output is automatically typecasted. Methods written in LabVIEW 8.20 should be automatically upgraded to use this new type of terminal so that every method, the output of which is typecasted in 8.20, would be upgraded to have these new terminals instead of standard terminals.

    I reported this as well, but it was discarded as "not a bug". I also think you should be able to define what you want, or how you want to see it, and that LabVIEW should not try to think for the programmer. It may be that the programmer simply made a mistake. If LabVIEW suddenly thinks it can solve the problem by replacing the VI with the more generic one, this may have consequences that the compiler could never had thought of. We all know that when computer starts to think for us, things go wrong ;)

    For example, we have an appliaction that feed birds by calling a Bird.feed method. If we by accident wire a Bear to this method LabVIEW automatically replaces the Bird.feed VI with the more generic Animal.feed VI. This may yield unexpected problems because feeding Bears is a different ball game. We should have taken precautions before we started feeding the Bear. To a non-OO programmer this may sound far-fetched because we don't deal with Bears in LabVIEW, but similar problems occur with programs. As a programmer we know the classes we work with. On some classes we can do actions immediately, but on others the same method may require other things to be done first. If we wanted to be able to feed all animals including bears, we had written a method that was able to do that and had allowed Bears to be fed as well, by specifying Animal as the input type. If LabVIEW adjust the output type to what it sees in the diagram going into the VI, this can have unexpected effects on things further on in the program.

    If you have to specify, at least you have thought about it.

    Joris

    You could add an option at the method call named "adjust output type to input". It would best give a visible "bumb" on the output to indicate that it is automatically casted. You would then keep be able to have predictable visible behaviour under all circumstances.

    Joris

  3. I've seen something related (most probably already reported too). It seems an array control or constant can remember that it was wired to a fixed size array. Then when you paste it somewhere else, the array wire does not allow to be changed size anymore. I was unable to remove the problem changing control/wire properties or by setting FPGA options off and restarting LV.

    Workaround: create the wire/control again from scratch.

  4. Strange!

    I could read but not write with the cable...

    The driver of the cable is not recognised by Windows, and it causes blue screen sometimes.

    There are many I2C to serial converters (especially multiple port devices) that have similar problems with VISA. Some or all functions then don't work (properly).

    I have very good experience with Prolific drivers, all devices with Prolific drivers always work.

    Joris

  5. Stephen,

    I hope you now understand my "obnoxious" remark. I think many, many programmers got irritated by the optimization problems. As a professional I can hardly explain my customers that for most applications we still prefer 7.1.1 (not only for stability reasons). All I would suggest is to take less risk and to keep basic things as they are. What you need as a professional programmer is a good basis, all the rest you can add yourself with helper VI's, tools etc. With a good basis we can sell LV programs that do not give the customer nor us any headaches.

    Joris

  6. Actually not necessarily. This is a behaviour that also occurres in C, at least the compilers I know of and it has its uses when you read in data from a stream in a certain format but later want to reinterpret some of the data. I know for sure a few cases where I have relied on this fact and changing that now would certainly break lots of peoples VIs.

    Indeed, I've also relied on that many times. If the behaviour is to be changed (which would not be a bad thing on itself IYAM), the automatic version upgrade process should replace the U32 or I32 nodes by Typecasts nodes. Because from the Typecast function that behaviour is expectable.

    I find it strange that the typecast node sometimes modifies data. It should never do that.

    Joris

  7. Hi,

    You'll have a hard time debugging apps like this. And making any extension to it will especially be difficult. You can check each time if the valueof a combobox has changed, but it's much easier to detect it with an event structure and a value change.

    I see you did use the shift register to store the comm transcript. If you go for some state machine / queued message handler (for example the one I proposed to you earlier) you should put that string in the state cluster.

    Joris

  8. I've thought of this issue as well. I had the same idea as you in the beginning. However, if you go into more detail you notice that such a typeless type will cause you also some troubles. There exists very advanced template techniques is some modern programming languages that would solve this problem in much more elegant way. I don't go into detail here as it's a field of computer science of it's own.

    I know about template trouble in C. But unlike C, LV already has its way of determining propagating datatypes of wires, which would work here as well.

    What problems do you see ?

    Joris

  9. I don't agree with you robijn. Twenty years ago this was the case as the compilers were so unefficient that programmers were forced to do all the optimization by themselves. Today most mainstream compilers are pretty good in making efficient code. So it's better to write code that is easier to read; this easy-to-read code shall compile to efficient code anyhow. Computing constant expressions at compile time is one example of such modern way of programming; instead of using constant value 12.56 you should write pi*(2^2) as it makes more sense when reading the code. The following two constant expressions represent the an array of integers x^2 with x values ranging from 0 to 100. The diagram above is much easier to read than the constant below.

    post-4014-1168802435.png?width=400

    Yes for these examples you are certainly right. But then, how far should the optimization go ? Because optimization creates a risk, as we've all seen ...

    Joris

  10. I would like to propose the typeless wire. Along with that comes a typeless control and indicator. Black might be a good colour. It's a bit like a template type in C, but then better because it's LabVIEW :)

    post-1555-1168804663.gif?width=400

    Actually the proposed wire is only typeless in the diagram of the VI concerned. As soon as the VI is placed somewhere as a subVI, the connections made to the VI determine the actual type of the wires inside the VI. For example, you could make a VI with a typeless input and output, place an array resize function in the VI that resizes a connected array to be able to set an element (as in picture above). It would work on any 1D array that is connected. Whether the VI is compilable or not depends on the type of wires that are connected where it is placed. The type of a typeless output terminal is also determined by these connections.

    To keep the behaviour similar to normal VIs, the VI should lock like any other VI, so that only one instance can be running at a time. Extra code will be generated for the type of wires that are connected. There should not be completely different instances of code for each type, because a great part of the code can be shared between different types. The compiler can insert a branch instruction when a typeless wire is reached, to jump to the code required to execute an action for the wire of the specific type.

    If you would connect a typeless wire to a shift register, each type would generate its own instance of the shift register. However, if a normal (typed) wire is connected to an another shift register in the same VI, that shift register is shared between all types. That way you could for example create a "generic" storage functional global.

    post-1555-1168804719.gif?width=400

    To be able to do different things for different connected types, the case structure could be used to switch between the various behaviours. It would then switch based on the wired type. E.g. if you create case frames for a DBL and a Boolean, the VI is compilable for those types. The wire is available in the case frame as of this type. It would allow you to return a string for both a double and a boolean: "3.14" and "True". If a type is connected to a typeless input of the VI for which there is no case frame, the VI is not compilable.

    This mechanism as an alternative to polymorphic VIs. Polymorphics require multiple VI's, with often identical diagrams, which causes code duplication. Untyped wires allow to have only a single diagram for multiple types. They are easier to manage and understand, give smaller code and don't require all the types to be known and implemented beforehand.

    Something for LV9 ?

    Joris

  11. Are you being obnoxious on purpose or by accident? Your statement seems like a deliberate flamebait.

    [LATER EDIT] Sorry, Joris. My original reply was uncalled-for and has now been edited. But your comment really doesn't make sense. What's the difference between constant folding and any other compiler optimization?

    Don't worry I did not see it ;)

    I meant it as an ironic marketing line. Usually marketing departments introduce new features that are better, faster, more reliable. Usually that goes for something that was "added". But you don't hear them about negative consequences of the addition. So I turned everything around, made an improvement of a removal, just to make a point. It seems it hit harder than intended.

    If you think about the folding optimizations, they hardly give any improvement because a reasonable programmer will always think about the program he's writing. If the programmer places a loop that does nothing, he just didn't think enough. The same goes when he could better have placed a calculation outside a loop. Many inefficiencies cannot be detected by an optimizing compiler, because they are caused by an efficient structure of the program. There's always a bottleneck in any program, and no matter how good the compiler optimizes, the compiler cannot improve the design. The problem is usally with the programmer, not with the compiler. So improving the user may give much larger speed gains. This may sound like a stupid statement but it is possible to learn a programmer better ways of programming.

    More optimizations always requires more code. And more code will introduce more bugs. I really cannot understand why NI decided to do this. It is dangerous and there's no real gain. It only undermines the stability, reliability and clarity, and those are important factors when you are working in environments where LV is often used. LV is not an office application.

    To come back to your question, I think these folding optimizations are something different than a loop speed optimization because loop speeds are a hard limit. The program cannot loop any faster than the LV generated code allows it to. Then, generating better looping code has gain. But all folding optimization gains can also be achieved by the programmer writing his program slightly more efficient. That's why I consider them different.

    Joris

  12. You have now three actions in a single VI, and you cannot perform multiple actions triggered by buttons.

    1. You need to split this into three subVIs: open device, query device and close device. (replace "device" by the name of your device.)

    1.1 Create subVI's for them. Test them by running them individually.

    1.2 Give them the connector pane with 12 connections (default in LV8)

    1.3 Connect the connector pane. Connect the error connectors and text/data input/output connectors. Keep left for input and right for output. Connect error in and error out to the bottom left and right connector.

    1.4 Give them an icon with short text describing their function.

    2. Create the basis for a "real" program.

    2.1 You will at least need a while loop.

    2.2 Better would be to use what is called a Queued Message Handler. I've attached a simple template of one, that you could use. Read more on how QMH's work on the NI site or maybe on this site. It's a template only, you will need to adapt the VI to suit your needs.

    2.3 Add the button actions in the user event handling part of the QMH. Create new separate actions by modifying the Type definition of the enum. Call those actions from the event structure.

    2.4 When doing the actual actions for the buttons, in the frames of the case structure, call the "query device" VI created in step 1 to perform the communication.

    2.5 You can update the string indicator by storing the full communication transcript in the state shift register of the QMH, and appending new data to that string when it arrives. You will need to find out how a shift register works and how bundling and unbundling clusters works. Update the string on the front panel by calling the update display state.

    How to actually do many of these things will cost some time to find out yourself, but I hope I can give you some line of what things need to be done, what direction to go. Work these points one by one. If you cannot do a next point, you did not study the previous point sufficiently ;)

    If you manage to do all this you have a pretty decent program.

    Joris

    Download File:post-1555-1168506856.zip

  13. The VI also works correctly if you popup on the 2 that is wired to the Index Array and select "Change to Control".

    The bug seems to be something in the constant folding. I'll let JeffK know... did you already file the bug with NI?

    Best feature of LV9: No more constant folding ! More reliable programs without any practical loss of speed and linking VI's in statically becomes more consistent !

    :thumbup:

    Joris

  14. Another question: what is the character for the "Enter" key?

    On modem-like connections it's usually \r (carriage return). There's a constant for it in the palette.

    You can place the \r and \n chars the Format Into String format input as well.

    I could not write String s = "x\r"; which won't work.

    You could, if you set \-mode for the control or constant.

    And for the event of button, where could I find such information??

    Help on event structure.

    (Can't imagine my answers are long... ;) )

    Joris

  15. The deadline is tomorrow

    You can't learn a language in one day...

    Some things even work competely different in labview than in any text based language. For example: your connections dictate the execution sequence, but by default everything is executed in parallel...

    I know that I should use VISA for the RS-232, however, I did not know how to make the program check the COM Port by itself, the default is COM1. But in my computer, the right one is COM3 or COM4...Is there such funtion to automatically check all avaiable and connected COM ports by itself??

    No you have to do that yourself. You could iterate over the COMx ports and send something and check what comes back. You can format a string in a C like way with Format Into String, so you can build a "COMx" string and wire that to the VISA function.

    In C#, user should first open the port, and then begin write to or read from the port. LabVIEW will immediately read fom the COM port, right??

    On itself that's true but you probably need to set the speed etc first anyway.

    I need to develop a LabVIEW front panel similar as above.

    Does LabVIEW have "textarea" which shows the message received from the COM Port? And "Group" to put "buttons" together?

    Yes, you can find it on the palette. Because the string indicator/control can be resized and given a scrollbar.

    You could use an event handler to handle the button presses and typed texts.

    You could continuously set the cursor at the last position in the text so that it "types" like a terminal.

    And when I press the button, it will send a string to the COM Port, some buttons send more than one command, so there should be some delay between these commands, in C#, I use "Thread.sleep(100)" as the delay time...How to implement this in LabVIEW??

    No problem. Have a look in the help and examples. Wiring the error wire through is the best way to make a sequence of actions. One of those action could be a wait function.

    For your each specific problem search the NI forums: forums.NI.com

    There is lots of info on communicating with devices in various protocols.

    Success,

    Joris

  16. when it only runs occassionally, as custom probes do when they have data values to update, you lose a lot of the live display potential of the XControl.

    Yes, right now they are called as a handler. NI could change the behaviour and make them run continously. I have often many windows running in parallel, handling their own events. New data could arrive in the event structure.

    I like the idea for registering properties, creating custom events.

    Joris

  17. Judging by the name "get all front panel controls", I wrote VI's doing similar things and because that was implemented with property nodes, I set them to run in the UI thread, preventing thread switches. Because it was in 7.1.1 I did not have your slowdown problem, but running in the UI thread gave an enormous speedup already. Maybe the slowdown is caused by a bug in the thread switching. Maybe you can try running this VI in the UI thread (if not already).

    Joris

  18. But there is one feature in LabVIEW 8.2 that does recognize versions of data and automatically provide the ability to unflatten and mutate old data into the current format -- LabVIEW classes. When you edit a LabVIEW class' cluster, the .lvclass file creates a recipe of how to get from the old cluster to the new cluster based on the edits you make in the control editor. When LV class data is flattened, it writes down the version number of the class as part of the flattened string. So when you unflatten, LV knows which recipe to apply. Unflattening LVClass data is pretty fast if it is already in the current version. I can't really give benchmarks for unflattening old version data since it depends heavily upon what edits were made, but it tries to be as efficient as possible.

    Well Aristos, that's a very nifty feature !

    All other methods have the problem of "what do you rename to what" and like this you have a perfect solution for that. My compliments for the excelent idea (to whoever at NI that came up with it).

    Joris

  19. :lightbulb: Actually, GPIB uses error code zero, so be careful with that idea.

    Error 0: Error connecting to driver or device.

    Yes, which idiot introduced that :angry:

    I always use the attached VI called Suppress error codes.vi which removes given errors from the wire. The errors to remove/suppress are specified with an I32 array. When one of those errors has been found it is removed and a boolean indicator is set so you can respond to the error. You could then create your own error instead of the old one, or perform some action. It also removes warnings that match the given number so you can also remove for example the VISA warning for "More characters are waiting in the buffer" (of which I don't know the error code because it is specifically chosen to be impossible to remember).

    Joris

    Download File:post-1555-1166086583.vi

×
×
  • Create New...

Important Information

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