Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by G-CODE

  1. Now you've got me thinking. I'm so habituated to creating typedefs, events, and registrations for every message. Maybe there's a better way...
  2. I have to be careful what I say here because I haven't explored Messenger Library, but my inclination is to think that I'm going to have to know the type at some point in time whether it be at edit time or at run time. So at what point in time would I rather know it? I just downloaded the package and flagged your YouTube videos to watch.
  3. Tell me about it! I think I've written seven of them so far and every time I create a new one I have to reference my previous modules to help me get the new one working. It's not trivial. For that reason I moved complex logic outside of DCAF to a higher level. DCAF manages I/O like scan engine, serial/modbus instruments, calculated tags. I wrapped DCAF in a subsystem that all other subsystems must use to access I/O. Since DCAF exposes I/O data through NI's CVT, I make sure not to use the CVT elsewhere throughout my application as that would bypass the protections I put in place for writing to tags.
  4. That doesn't necessarily have to be true if you're willing to dig in to specifics of existing frameworks even if you haven't spent a lot of time developing with them. For example, Antoine points out that DQMH has good scripting tools. I agree with him, even though I haven't developed a large project with it. DQMH seems like it makes it very easy to create new messages with custom data types. Those are good suggestions to add to the comparison chart! This raises the question of what a framework should be: process startup and management, dependency management, data management, interprocess communication, etc... The answer is probably different for everyone. It depends on what's important to the project and the developers working on the project. Now you've got me interested in digging into Messenger Library which I've never taken the time to do. SMO and DQMH assume you are going to be using events to broadcast and receive messages.
  5. SMO. I'm guessing Francois will say the same thing since he wrote a large part of it. Several months ago I was comparing three common community frameworks and I had Francois chime in. I attached a screenshot of what we put together with our rankings obscured. If he's ok with me showing it, I'd love to reveal our rough rankings for the categories shown. My superficial summary of each? Actor Framework - you better love having LOTS of classes in your project and opening DO methods to figure out how the code works. JKI SMO - Use this framework and Steven Mercer will castigate you because no human alive can write code with reference class data that isn't riddled with race conditions and bugs. Honestly though, if you're that worried you can impose some rules when developing with this framework to make it more actor-like. DQMH - The fact that it was developed for customers who don't understand object oriented programming suggests that if an experienced developer wants to combine it with classes that it might be unnecessarily complicated. Sure enough, I watched the presentation on how to do hardware abstraction with classes and DQMH and it confirmed my suspicions. It makes one think about what a framework would look like if your initial design goals were NOT to hide classes from less experienced developers. Turns out that framework might look something more like SMO. In the same project that is using SMO, I'm currently using DCAF at the lower level to manage I/O because there are hundreds of I/O tags. Now that I've spent a fair amount of time developing a variety of DCAF dynamic modules for this project I think I have a good idea of DCAF's strengths and shortcomings. It is open source so if I want some of the bugs and nuisances fixed, I'm going to have to fix it myself. Whoever wrote it got us 80-90% of the way there, but that final polish is going to take a fair amount of work. A lot of the code under the hood just ain't that pretty and some people don't really care about that. I do so I find myself getting annoyed every time I dig into it.
  6. Can you show me how to make LabVIEW crash by doing this? I created and destroyed 1 million DVRs that were cast to integer and cast back to DVR and couldn't get LabVIEW to crash. Attached VI made with LabVIEW 2013. DVR to integer_2013.vi
  7. There's this reference design framework, but as far as I know it doesn't have scripting to create accessor methods. https://github.com/JKISoftware/JKI-State-Machine-Objects
  8. I'm happy to report that the bug seems to have been fixed. I opened the example code I originally posted using 17.0.1f1 (32-bit) and the buggy behavior has gone away.
  9. It might exist in 2015 as well? I realize if we can't make these issues reproducible then it's difficult to report. I'm going back and forth between two projects right now - one uses LV2015 and the other uses LV2017 - so I'm forming opinions about the apparent stability of each. The LV2015 project is YUGE!!! and it's mostly stable as long as I don't right-click on anything in the project Dependencies folder and select 'Why is this item in Dependencies?' which will instantly crash LV. The safer bet is to right-click an item and select 'Find>Callers'. So one of my few gripes with 2015 is I've seen some really strange dependency issues that have been difficult to track down because there are no typedefs, globals, etc. in these classes that would cause dependencies to exist. The LV2017 project only has about 50 classes so far, but the latest issue I'm experiencing isn't hard crashes, but the project getting stuck with a spinning wheel indicating it is working, but it just never comes around and I have to force quit the application. It seems to happen as soon as I right-click a class to save it after I've added some methods. I'll give it 3-5 minutes in hopes that it will finish whatever it is doing, but every time I eventually have to force quit and restart LV.
  10. I've been encountering so much strange behavior in the 2017 dev environment that I started taking screenshots of all the weird stuff I was seeing and I finally just gave up. I already mentioned the weird stuff with parallel access DVRs, but I keep getting some non-parallel DVRs where the wire in the DVR in place element structure is just broken for no reason. Reattaching seems to fix it for a while. One screenshot I did keep was an error state that occurred from a class appearing as a duplicate within a Typedefs folder (attached). Don't ask me how that happened. How can a class exist in two places? It certainly didn't exist in two places on disk and definitely didn't exist in the typdefs folder. Oh, and if 2017 seems to be eating up processor usage, but you have NO processes running and everything is just sitting there idle, try closing the breakpoint manager window if you have it open. That worked for me. Like I said, this is just a partial list...
  11. Glad someone else is seeing the same behavior in the example I posted. The fact that you were able to create a new VI and couldn't reproduce the behavior is indicative of what I've been experiencing. These bugs are intermittent, but the example I posted on the NI forums wasn't the first time that happened to me. LabVIEW didn't crash while I was working on the example I posted. I've got another example that exhibits the same behavior and uses code from the actual project I was working on. I haven't yet determined what will cause the code to compile that way, but imagine how difficult and strange it is to track down these bugs when all of a sudden your code just stops working. Another strange artifact I've seen by creating accessor methods this way is that sometimes LabVIEW has changed these VIs to reentrant execution and turned on inlining. I can't tell you how many times I've examined the execution properties and found these settings changed, yet I had never changed them. I definitely wouldn't turn on inlining unless there was a good reason to do it. What I've concluded from this is that DVR parallel read-only access is really buggy and shouldn't be used. It seemed innocuous enough that to turn it on for a read method shouldn't have caused any problems. After spending quite a bit of time developing a project in 2017, I agree with Neil Pate's sentiments expressed last week. The LV 2017 editor has some issues. I'm going to keep moving forward with this project in LV 2017, but if I had to start again from scratch, I'd pick LV 2015. The editor in 2015 seemed to remain responsive and snappy on big projects, unlike 2017 which will (at times) slow down to a crawl when all you're trying to do is move something across a block diagram. Additionally, I haven't mastered exactly when to press the 'W' key to turn of maintaining wire connections so that feature seems like more of a hindrance than it is helpful.
  12. I just posted this over on the NI forums. Can anyone else confirm. This seems really strange, but I still think I might be missing something. I've got a probe on a block diagram that doesn't agree with the data coming out of the VI that is the source. https://forums.ni.com/t5/LabVIEW/Parallel-Access-DVR-Bug-LV2017/m-p/3696695#M1039519
  13. You can easily instantiate a child class at runtime. You can launch your application with only the parent class in memory until you specify which child class should be instantiated. Each of your child classes can be placed in their own libraries (LLB or packed project library 'should' work). The path to the class in the library can be passed to the 'Get LV Class Default Value' function as shown in attached. However, without looking into it more, I'm not sure this really solves your problem since you are trying to load code that is specific to a LabVIEW version. It sounds like you want to create a parent class that can be opened with either LV2013 or LV2015 and then dynamically load a child class that could have been created with either LV2013 or LV2015. Is that correct? -Eric
  14. Do you observe the same behavior if instead of returning the 'AllObjs[]' property from the cluster and typcasting each to a control , you return the 'Controls[]' property instead?
  15. Well that all depends. If you've got TDMS files that you want to post process and or analyze, Python might be exactly what you want. That was the case for this particular project. It was considered advantageous to not require LabVIEW. Plotly was just used as the visualization tool after post processing the data. If the goal is to create some data in LabVIEW and display it in Plotly, then I agree that you shouldn't need to bring another language into the mix. I still think it's great that Adam Reeve put a tool out there that allows us to read TDMS without requiring LabVIEW!
  16. I've gone from TDMS to Plotly using Python. There's a guy who maintains a Python module for importing TDMS data to Python on GitHub. I've used it successfully on one project so far. https://github.com/adamreeve/npTDMS
  17. I guess I'm waiting for the day where I see a case study of a medium to large size LabVIEW app with the UI completely developed with a JavaScript framework. (Angular, React, Vue, etc). If pressed for time, I can't think of a good reason to do this assuming a standard LabVIEW UI can meet all the requirements.
  18. Shaun, would you be willing to elaborate on your process for doing this? Has this already been discussed and do I just need to be pointed to those discussions? I find this interesting, but it also seems like it would pose its own challenges. To do this it makes you a LabVIEW/front end web developer, right? Do you have a preferred JavaScript framework? Do you run into issues where browser updates break your UI? It seems like it would slow down development time so it might be a hindrance on customer projects that have aggressive delivery timelines. I probably shouldn't hijack this thread. If you'd be willing to discuss your methodology, I could start a new discussion. Eric
  19. I guess I'd need to see your code. Are your modules simply VIs that you call? If that's the case, you don't need to user events at all. Just stick each module in a different case of your case structure then send the correct string: module1, module2, module3. There's less work involved in doing that than there is in sticking each of those modules in an event structure. I wish ShaunR would chime in and try to dissuade you from going down the path of trying to call into the EXE using references since I doubt he would try to solve the problem that way. He was just providing you with an explicit answer to your exact question. I doubt he would suggest doing that if he were considering the bigger picture of what you are trying to accomplish. Eric
  20. Steven, I think this would be a useful feature. Don't we do this all the time on inputs by checking their values? Sometimes we are checking the values of inputs on VIs because we are actually concerned with the incoming value and sometimes we are checking because we want to know if the user of the function set the value (wired the input). Unless we actually comment our code well, it might not be immediately obvious what our intent was for checking the incoming values. The feature you describe would enable us to be more explicit about our intentions without actually adding code comments. Self documenting!! I remember sitting with Mike (VI Shots) once and he was wishing this feature existed. It was a couple of years ago so I'd be curious to see if he remembers saying that. Eric
  21. BTW, while ShaunR did answer your exact question, I think you're going to hit a dead end pretty quickly if you try to go down that path. Notice one of the arguments required for that function is the user event ref. Since those references change every time you start your LabVIEW application you're going to have to first pass those references out of your LabVIEW application so that you know what to call from external code. If you know how to generate a user event, then you've already got everything figured out. Your Python code can send strings via TCP: command1, command2, command3. Your LabVIEW code can receive those strings to control a case structure. Each case fires a different user event.
  22. Do you need help figuring out how to generate a user event in LabVIEW? If so I can modify that example so after the message is received it generates a user event.
  23. Allen, I spent some time looking at the python_labview_automation GitHub repo and actually trying to get the code to run. It looks like it was probably written in Python 2.X and I have 3.5.1 installed. I modified enough of the 2.X code to get it to at least establish a connection with LabVIEW. When fully functional, it looks like it is supposed to call a VI and set some control inputs. All the code on the LabVIEW side is based on actor framework which probably isn't even necessary for us since all we we want to do is create a TCP server in LabVIEW. To be honest, I think it's overkill for what you (and I) want to be able to do. It is dependent on some other libraries (hoplite, BSON) which make it more difficult to install and run. All we really need to be able to do is to call a function(with arguments) that executes some LabVIEW code. On the LabVIEW side of things we will know the data type of the arguments (received as string) so we can convert the arguments to their correct type. Then we need to send a response back to the Python function that is waiting for it. Once you receive the command in LabVIEW, you can do whatever you want with it including generating user events, notifiers, putting data in a queue... whatever. So I don't think the question to answer is how to generate a user event from Python. The question to answer is what's the best way to create a communication architecture between these two languages given that we want to call a function with arguments from Python and have it received by a process running in LabVIEW. As you'll see if you run the example code I attached to the other post, a simple version of this is really easy to implement. It will take a little bit more work to make it full featured enough so it is reusable and works well in our application. I'm thinking a community version of this on GitHub would be really useful and it's about time we have this. I'm not committing myself to doing that, just thinking about it. :-)
  24. Here's a version that should work in 2014. I started with the LabVIEW TCP server example. Note that it's reading one byte at a time which is probably not how you would implement this in your application. If your messages from Python were terminated with CRLF then you can configure the TCP Read Function in LabVIEW to read until it sees the terminator character. Simple Server-14.vi
  25. shoneill, Mercer said something prior to the sentence you quoted that is important to include in his statement about inheritance - specifically that it is "general" advice. I can think of a recent example where inheritance was a useful tool, but I broke from that convention. However, I would say that generally (most of the use cases I encounter) I would not want concrete classes inheriting from other concrete classes.
  • Create New...

Important Information

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