Jump to content

AlexA

Members
  • Posts

    225
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by AlexA

  1. Update: I understand why the states are unstable. The fact that idle can enque itself combined with the fact that the queue can receive a "Run" command while the idle state is happening and then the idle state enqueus itself means the states swap enqueuing themselves back and forth. As mentioned above, I think the key is to remove the idle state. The problem with this is, I can't then figure out how to handle typo errors in the state commands without the default structure having that error handling ability. That's fine for me, as I can be really rigorous, but if I want to give this to anyone else, for sure they'll make a typo at some stage. Anyone got any ideas? Alternatively, I could make the run action flush the queue every time, this seems kludgey to me though, and I'm not sure how expensive it is CPU wise. Also, I'm about to test whether removing the idle state actually does fry the FPGA, wish me luck! Report: It doesn't, at least on the VI I tested, yay! I realised that I actually can still have the typo error handling. When each parallel process starts up, it runs an Init state (w/e is needed), then goes into wait mode. Running the action command goes into a loop of continuous action, until a pause command is sent, then it goes to a pause state which flushes the queue, and then waits again. I'm pretty happy with that actually, can anyone see any obvious holes I'm missing or ways to break that pattern?
  2. Ok, further thoughts. I've seen Daklu say around this forum that letting a message handler enque to itself is dangerous. So I've tryed to change the architecture of the parallel process VI's (not in the latest zip file) to be a bit of a compromise. The only state that's allowed to enque to itself now is the action state. The problem is, this doesn't seem to play nice with the FPGA. Arggh, it would be nice if there was a simple bug in the code linked above which explained the state flickering.
  3. Hey Guys, I'm a pretty stubborn guy, so I couldn't just let the approach I was taking go without tinkering a bit more. It's now working for the funtionality I've implemented, namely, starting and closing an FPGA. Listening to a specific set of FIFOs from said FPGA, and triggering the FPGA to do something. Hopefully it doesn't break too badly. Paths are fixed again and the main vi is actually in the "Scratch Pad" sub folder, it's called "Main Scratch Pad.vi" (though of course you guys won't have the FPGA set up that I do). Hopefully I've addressed a lot of the concerns you raised James, though there are some nasty cludges, particularly in the handling of the messenger queues while in host (look at the run/stop trigger and similar states). I still need to implement the functionality of listening to the queue provided by the VI which is listening to the FPGA FIFO and dequeing to display etc. Which as you stated previously James, could be pretty nasty. Hopefully I've addressed that by making the queue itself package all the relevant data from the FPGA listener. So it should just be a matter of dequeuing and processing. Can you take a look at this and see what fundamental flaws there are in the design? As I mentioned previously, the one glaring fault that jumps out to me is the handling of the messenger queues. I can't figure out how to encapsulate the queue information (i.e. which queue to use), so that it's obvious to any state that wants to talk to a certain VI exactly which queue it should load its messages on. Edit: Oh and another thing: I've noticed that my sub-vis running in parallel, when sent the command to run whatever their task is (which takes place in a run state which enqueues itself until a pause command flushes the queue) will constantly flicker between "Idle" and "Action", even though the only thing entering the message queue should be "action". All the VI's reference a sub-vi called "State Manager Sub" which simply enques whatever is input to it and checks for an error, flushing the queue and enqueuing and error state (which in turn calls exit and shuts down the VI). My understanding is that the application should generate a new version of that code for each VI that calls it, but I was suspicious they might somehow be sharing a queue, so I took all the stuff out of State Manager and just put it straight on the BD, no change, I still see the flickering between states. Can anyone tell me what's up?
  4. Ahh, yep that matches with my understanding. The last week has been very much tinkering week for me. It's the first time I've ever created a folder called scratch code, and it's already exploded to some 20 something VI's... Back to tinkering! Oh, I just remembered, the kind of nitty gritty guts of my question is: Suppose I have a method that takes the reference to the FPGA and starts listening to its FIFOs and loading the result onto a queue. How does one start and stop this method while still going on to perform other methods. Is there an OOP equivalent of "Run VI"?
  5. Hey AQ, Thanks for the input. I think trying to dive into OOP via this problem I'm working on might be a little out of reach, given the time pressure I'm under, but your input is much appreciated. Just a quick question further to your first, short answer. My answer to your question, based on my current understanding of Labview, would be to pass a reference to the variable between VI's, but from the reading I've been doing around the internet, passing references to classes seems to be a big no no in the OOP world. Have I misunderstood something fundamental here?
  6. Hey James, Thanks very much for the input! I actually do have a working prototype of the code I'm trying to achieve which was the image I posted a few posts back.I think you're right in that I'm trying to do too much at once, perhaps I should just compress the FIFO read loops into some sub-VI's. On the subject of queues and passing data around, of course I see the potential for errors if the queues get out of sync. It was just the only way I could think to decouple certain sections of the code so that I could stop them if I didn't want that functionality. I guess it's needless compartmentalisation though, as whenever I want one I'm going to want the other. In any case, you've given me a lot to think about! And at worst, I've learnt a whole lot about Labview that I didn't know existed before!
  7. Hi guys, Sorry in advance for this post being a rambly display of gross, conceptual misunderstanding, I'm putting out feelers to try and figure out a little bit about this OOP thing. As per the thread title, how would you deal with the prospect of parallel processes that need to be called from the main VI and return information to it, without creating a new object (and subsequently, a new set of data? In my very superficial grasp of the subject I'm imagining something like the following (context is the project I'm currently working on): I'm tasked with talking to an FPGA module, getting data from it and storing some data on disk, and presenting other data to some sort of control algorithm. I imagine an "FPGA Communications" Class. Data: -FPGA Constants (certain parameters which are read once when the FPGA is started and used in future calculations) -FPGA Reference -FPGA Data (a constant for accepting data from the FPGA)?? Methods: -Initialise FPGA Constants -Start FPGA -Stop FPGA -Listen to FPGA FIFOs (continuous process, possibly listens to the FIFO then writes the value to the FIFO data??) -Present FIFO Data (accesor class)?? -Trigger FPGA activity (potentially continuous process) So I guess the key thing is how one deals with the "Listen to FPGA FIFOs" method? I've also included an accessor VI for the FPGA data. I guess one class would handle communications with 1 FPGA device. If I want to have a data processing class (I think I'm still too stuck in the idea of having tasks rather than actors), anyway, this class would access the FPGA Data presented by Communications Class and do something to it. This idea of storing real time output from an FPGA in class data and then accessing, how does this fall apart when speed becomes a requirement?
  8. So I thought I'd reopen this discussion as I searched the forum for using classes as clusters. I'm working on a state machine which does the typical thing of passing constants, inside a cluster, around on a shift register. I've read that mimicing this behaviour using classes is a good way to start getting into OOP. I've broken up all the constants into categories that I think make sense (such as FPGA initlisation constants and Messenger Queue Refs). What is the best way of passing these classes on one wire? Similar to the way the data cluster is one wire. Conceptually, it's nice to break the constants up into areas of responsibility and initialise them using methods and such, but I don't want to pass a class wire for every set of constants. I also don't want to group all my constants into one Class as it seems yucky to me. What's the best solution?
  9. Hey guys, I started a thread over in Application Design and Architecture: http://lavag.org/top...block-diagrams/ It's spiralled into a bit of a story about my painful birthing process in discovering proper coding practises, state-machines, sub-vi's (and the dynamic launching thereof). As per this post: http://lavag.org/top...dpost__p__89479 I would like to change the title of the thread to more accurately reflect what's in the thread now. I was thinking something like "Factoring Code and Instantiating Parallel Processes in Sub-VI's". Also, I posted another thread which was related to the first but a more specific question, another user recommended keeping tangential questions in one thread so others can follow the discussion and thought processes. As such, could I request a merger of the following thread: http://lavag.org/top...-state-machine/ with the first one. Thanks in advance, Alex P.S. Sorry about coming through this forum, but I couldn't find out who to contact for problems like this, and I didn't want to abuse the "report to moderator" button.
  10. @drdjpowell Hey, the files are in there, in the Sub-VI's folder, but in my code they're using absolute paths, so I guess that's why they wouldn't be launching for you. On another tack: Last night as I was tossing and turning I decided to browse the LAVA OOP sub-forum and I found this two part tutorial by Michael Aivaliotis from JKI which does exactly what I was trying to do, but more elegantly. So for people following along with my case or looking at a similar problem here is the link again. If I have edit priviledges, I'm going to change the title of this thread to more accurately reflect what's here. Note: From "Examples of massive programs and your block diagrams" to "Factoring Code and Instantiating Parallel Processes in Sub-VI's" Edit: Ok, I don't have priviledges so I'll send a PM to the moderator. Edit 2: Ok, colour me stupid but I can't seem to find a list of the moderators responsible for this sub-forum, or even a list of moderators full stop, can anyone let me know who to contact?
  11. Ok, I've attached a zip of my project as it currently stands. I've taken the approach where I separate functionality into dynamically launched sub-VI's. I have a feeling like I'm a babe walking into a dark wood and the sun is setting quicker than I realise. It's quickly getting out of my control and it's all stemming from trying to separate things into small chunks which are supposed to operate in parallel but be started individually and arbitrarily. It would be great if someone could have a glance over the project, specifically "main.vi" and the subs it calls, and tell me if there's a better way of doing what I'm trying to do. Specifically the idea of running parallel processes which are meant to talk to each other from a single, management type, user events handler. The reason I was trying to get things all being triggered from a consumer type events manager is that to do otherwise (i.e. use dynamic events to trigger the parallel loops in the main host) is that in terms of foot-print it really wouldn't be any more efficient than what I was doing already. Regards, Alex
  12. Ok, now I am stumped, I've been merrily going along triggering VI's from my main VI, all working as intended. Until I got to one that I didn't write, a VI that acts as a serial server allowing the transfer of commands through the code to the camera attached to the FPGA. I've tested this VI in two ways. If I try to run it using the Run VI method it results in a time out error with the camera configuration software. If I run it as a sub-vi (the way it's run in the example code provided with the NI-1483 adaptor) inside the exact same state (which locks up the state machine). Then it works fine, but of course I can't then leave it alone and go do other things. I could of course just write a dynamic user event that transfers the start serial server command to another loop, but I'd much rather understand why Run VI doesn't work like launching it as a sub-vi in this case. So my question, what would be difference between the two runs (I've taken care to use the Ctrl Val.Set method to make sure all the inputs are the same in each case)?
  13. Ahh, apologies for the split. Could I request a mod merge this with this thread: http://lavag.org/topic/14883-examples-of-massive-programs-and-your-block-diagrams/ and a change of title to that thread, something like "A conversation on factoring code" (and a subsequent lock to this thread). I intend to upload an example of my now factored code into that thread shortly once I'm happy with some of the functionality. As I hope this thread will be merged I'll add the following comment here: I've managed to figure out how to dynamically load VI's and leave them running in the background. It might be overkill but boy do I like it! It really compresses things and makes the block diagram easier to intrepet and modify in my opinion.
  14. So, I've learned the value of scratch pad VI's . I've figured out how to run a VI in the back-ground, haven't tried listening to its queues yet but that's next. Still a little bit stuck on how to close it properly. When I call close VI reference it works but leaves the VI running, when I use abort, then close, it doesn't actually stop and then close reference returns an error. Anyone got any insight into this behaviour?
  15. Hey guys, I imagine you're getting heartily sick of my flurry of questions by now. This one's been bothering me for a couple of days. Is there a conventional way for triggering a continuous process inside a state, without locking the state machine? The only hint I've seen how to do this is to place the process inside a sub-vi and launch it with "wait until complete" set as false. I've also read a little bit about Daemon's on the lava wiki, is this what I should be looking at? What I'm trying to achieve is: I have an FPGA which performs two functions, generates a stream of images, and performs a set of calculations resulting in a single number out which describes a characteristic of each frame. In my host code, I want the user to be able to interact with these two functions independantly. I currently have a state machine/producer-consumer architecture. The UI loop is the producer and loads commands into a queue which is unloaded by the consumer and acted upon. Currently I have a third loop bolted on to this which when triggered, starts listening to the FPGA FIFO for data and packaging it up into a Queue. I would like to if possible, move this bolted on loop into a sub-vi which can be triggered and stopped all from inside the state machine. I would also like to create a similar sort of triggered "listening" state which dequeues from the FIFO gathering loop and processes. Anyone got any good ideas for dealing with the goal of triggering continuous processes (and stopping them arbitrarily) from inside states, without locking the state machine. Regards all, Alex
  16. Yeah, there's a problem in that I also need to pass information to the "consumer" loop along with the "go" type instruction. I need to pass a reference to an FPGA vi. I got really excited and started off using a JKI state machine to handle the user interface and a few calibration routines. Now that I want to listen to the output of the stream from the "consumer" loop at any given time, the JKI architecture doesn't make as much sense. To go into a listening state locks up my user interface so the listening state can't be cancelled. I think I'll have to move to a 3 loop architecture. I saw it around on these forums but can't remember what it's called, MVC maybe? I'm thinking a UI loop based on an events handler which enques messages for a general loop which handles messages and acts on them and a "stream" loop which starts and stops the data stream from the FPGA. When started the stream loop loads data via lossy enque into a queue and the act of dequeuing and processing is handled in the "general loop". Should I handle constants which are initialised at program start-up, but subject to future reinitilisation depending on the result of a calibration routine, in the UI loop? Or in the "general" loop? Arrgghh, started with a bang into this state-machine type coding and now it's all spaghetti but I just can't see the wires . Could someone link me a "getting started with state-machine/producer consumer" type reading, preferably free if such a thing exists.
  17. Hey guys, Some of you may have looked at the thread I posted recently about trying to refactor my code to not be a squiggly mess. I'm trying to break apart the functionality of the program into sub-vis as well as decoupling the UI from the processing. One of the problems I'm having is that I have a series of loops which are interacting with an FPGA. Most are listening to FIFO's waiting for blocks of data to arrive suitable for processing. One is triggering the initiation of data capture. I'm trying to wrap my head around how I can trigger these loops to start listening once the user is ready for that to happen (after they've performed some calibration and constant initialisation), but also to trigger the stop condition on these loops when the user doesn't want to listen anymore, and then to start it again when they're ready to. Mostly I'm struggling to figure out how I can pass the stop condition across the multiple parallel loops (is the best way really to use a local variable like I have been)? I have tried to diagram below the structure of the code in abstract as I currently imagine it. Can anyone point me in a better direction for what I'm trying to do? As a general question, is it ok to nest event structures and while loops like that? Your wisdom is much appreciated. Regards
  18. Hahaha, there's definitely a bit of thumb twiddling going on while the BDCleanup goes. Today is refactor day so I'll post my results in 7 hours or so of how far I've got rationalising it and tidying it all up. Wish me luck!
  19. Hey everyone, This is exactly the sort of advice I was looking for, some really beautiful little block diagrams. I'm definitely going to work on getting the code broken down into sub-vi's. Thanks for your examples. @P de Boevere: Hahaha, I wish I had that luxury, unfortunately I'm a lowly PhD student trying to thrash out all the stuff I've been tasked with doing. For your entertainment pleasure, I've included the block diagram of my main vi: Obviously I've got a lot to learn...
  20. Hey all, I'm currently constructing a whopping program that after tidying (and commiting the crime of hiding a routine in a stacked sequence structure) is a couple of screens across horizontally. I was wondering if anyone would be keen to upload a screen shot of the block diagram of their current massive project. I'm not really interested in what it does, just the individual approaches people are taking to keep their code tidy and easy to interpret. Also, if anyone knows of a really good resource for tips regarding organising your code elegantly in labview, please let me know. Regards all, Alex
  21. Interesting, I was having a lot of problems with DMA write time outs and buffer over-runs, you're saying a lot of it could be solved by simply making my host buffer larger? What proportion of the DMA FIFO fills up before the engine writes the data to ram? Is there anyway to control this?
  22. How exactly does the different buffer size thing work? If I'm writing data into the DMA FIFO in the FPGA and it's got x elements, but those elements fill up before I can get a read command off, how does having a bigger buffer on the host side help? I would love to use DMA, but in my experience I can't balance the read commands accurately. Either I call for too many elements and get a "read could not be processed in the specified time out" or I don't call for enough and the buffer over runs, I start losing data.
  23. Yeah, DMA doesn't really work at the throughputs I'm talking about either. I'm streaming images out from the FPGA at least 52MBs/s, you can't build a DMA FIFO big enough to handle that sort of throughput due to the differences between the speeds of write in FPGA and read in windows, whatever size you build is going to fill up. Because of the non-determinism you can't reliably hit a certain number of elements in the FIFO on every read call, which makes handling the data a bitch in the host code. My skin crawls at the idea of trying to rely on a-priori knowledge about the different data rates to get the read quantities right given how variable windows is. The best I've come up with is to use the onboard DRAM to handle high-speed writes then read it out at a later point at a much more sedate rate, hence the hand shaking.
  24. Ok, I couldn't figure out the best way to synthesise my problem down for a title but that will have to do. I'm trying to send information around between the target FPGA and a windows host machine. The problem is that, because the information coming from the FPGA is from a single-cycle timed loop, and the windows host code is slow and not deterministic, I can't rely on polling a "data ready" type indicator to begin the transfer without latching said indicator. If I latch it, I don't know how to unlatch it so it's not a one off event. Does anyone have any good advice for this sort of problem?
  25. Hey all, I am using a PXIe-7965R in a PXIe-1073 Chassis. This box is connected to a computer running Labview RT via a MXI cable to a PCIe receiver card. The 7965R has a NI 1483 cameralink adaptor module plugged into it, this is in turn connected to a Photonfocus camera with an 80MHz pixel clock. 8bit pixel data is gathered at a rate of 100MHz, using at least 512 lines. The problem is that the system bandwidth listed on the NI website for the PXIe-1073 Chassis is 250MB/s. To stream 8bit at 100MHz (if I just use a to host DMA FIFO) requires 800MB/s. So, I'm stuck with some architectural issues on top of some fundamental questions. Given that an RT system can't perform read operations as fast as the FPGA can perform writes, I think I'm always going to get write timeouts and data loss, would this be correct? One solution, assuming that the aforementioned problem is not as important as I think it is, would be to use a really big DMA FIFO and only trigger the capture on a succesful read out, this has issues in that it wastes FPGA resources which I want to use for other image processing functionality (FFT's etc.). An alternative solution (which I believe may not be possible after reading the help file) Is to use the onboard DRAM to store the images, then read out from it later at a slower rate. According to the help file, you can not use memory to transfer data between clock domains on the FPGA, is this the case when using DRAM? Does anyone have any insight on this issue? I'm prepared to accept less than optimal streaming, (I'm thinking of bursts of high-speed images stored in DRAM and read out slowly) if it's possible, or am I stuffed? Regards everyone, Alex
×
×
  • Create New...

Important Information

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