Create a continuous data stream from C++, and read it in LabView

Hello all.
I'm working on a project which involves connecting to a motion tracker and reading position and orientation data from it in realtime. The code to get the data is in c++, so I decided that the best way to do this would be to create a c++ DLL file which contains all the necessary functions to first connect to the device and read the data from it, and use the Call Library Function node to feed this data into Labview. 
I'm having trouble though, since ideally I would like a continuous stream of data from the c++ code into Labview, and I'm not sure how to achieve this. Putting the call library function node in a while loop seems like an obvious solution, but if I do it this way I would have to reconnect to the device every time I get the data, which is quite a bit too slow. 
So my question is, if I created c++ function which created a data stream, could I read this into Labview without having to continually call a function? I'd prefer to only have to call a function once, and then read the data stream until a stop command is given.
I'm using Labview 2010, version 10.0.
Apologies if the question is poorly phrased, many thanks for your help.
Dave
Solved!
Go to Solution.

dr8086 wrote:
This method sounds like an excellent suggestion, but I do have a few questions where I dont think I've understood fully.
From what I understand the basic premise is to use one call library function node to access a DLL which creates an instance of the device object, and passes a pointer too it into labview. Then a seperate call library function node would pass this pointer to another DLL which could access the device object, update it and read the data. This part could be in a while loop and carry on reading the data until a stop command is given.
That's it. I'm including some skeleton code as an example. I'm also including the code because I don't know how much you have experience with multi threading, so I'm showing how you'd have to use critical sections to guard the interactions between threads so that they don't lead to issues.
// exported function to access the devices
extern "C" __declspec(dllexport) int __stdcall init(uintptr_t *ptrOut)
*ptrOut= (uintptr_t)new CDevice();
return 0;
extern "C" __declspec(dllexport) int __stdcall get_data(uintptr_t ptr, double vals[], int size)
return ((CDevice*)ptr)->get_data(vals, size);
extern "C" __declspec(dllexport) int __stdcall close(uintptr_t ptr, double last_vals[], int size)
int r= ((CDevice*)ptr)->close();
((CDevice*)ptr)->get_data(last_vals, size);
delete (CDevice*)ptr;
return r;
// h file
// Represents a device
class CDevice
public:
virtual ~CDevice();
int init();
int get_data(double vals[], int size);
int close();
// only called by new thread
int ThreadProc();
private:
CRITICAL_SECTION rBufferSafe; // Needed for thread saftey
vhtTrackerEmulator *tracker;
HANDLE hThread;
double buffer[500];
int buffer_used;
bool done; // this HAS to be protected by critical section since 2 threads access it. Use a get/set method with critical sections inside
//cpp file
DWORD WINAPI DeviceProc(LPVOID lpParam)
((CDevice*)lpParam)->ThreadProc(); // Call the function to do the work
return 0;
CDevice::~CDevice()
DeleteCriticalSection(&rBufferSafe);
int CDevice::init()
tracker = new vhtTrackerEmulator();
InitializeCriticalSection(&rBufferSafe);
buffer_used= 0;
done= false;
hThread = CreateThread(NULL, 0, DeviceProc, this, 0, NULL); // this thread will now be saving data to an internal buffer
return 0;
int CDevice::get_data(double vals[], int size)
EnterCriticalSection(&rBufferSafe);
if (vals) // provides a way to get the current used buffer size
memcpy(vals, buffer, min(size, buffer_used));
int len= min(size, buffer_used);
buffer_used= 0; // Whatever wasn't read is erased
} else // just return the buffer size
int len= buffer_used;
LeaveCriticalSection(&rBufferSafe);
return len;
int CDevice::close()
done= true;
WaitForSingleObject(hThread, INFINITE); // handle timeouts etc.
delete tracker;
tracker= NULL;
return 0;
int CDevice::ThreadProc()
while (!bdone)
tracker->update();
EnterCriticalSection(&rBufferSafe);
if (buffer_used<500)
buffer[buffer_used++]= tracker->getRawData(0);
LeaveCriticalSection(&rBufferSafe);
Sleep(100);
return 0;
dr8086 wrote:
My main concern is that the object may go out of memory or be deallocated, since it wouldnt be held in any namespace or anything.
Since you create the object with new, the object won't expire until either the dll is unloaded or the process (LabVIEW) closes. So the object will stay valid between dll calls provided LabVIEW didn't unload the dll (which it does if the VIs are closed). When that happens, I'm not exactly sure what happens to live objects (i.e. if you forgot to call close), I imagine the system reclaims the memory but the device might still be open.
What I do to make sure that everything gets closed when the dll unloads before I could call close and delete the object is to everytime I create a new object in the dll I add it to a list, when the dll unloads, if the object is still on the list I delete it.
dr8086 wrote:
I also have a more general programming question about the purpose of the buffer. Would the buffer basically be a big table of position values, which are stored until they can be read into the rest of the VI? 
Yes, see the example code.
However, depending on the frequency with which you need to collect data from the device you might not need this buffer at all. I.e. if you collect a sample about every 100ms then you could remove all threading and buffer related functions and instead read the data from the read function itself like this:
double CDevice::get_data()
tracker->update();
return tracker->getRawData(0);
 Because you'd only need a buffer and a seperate thread if you collect data at a high frequency and you cannot lose any data.
Matt

Similar Messages

  • Data Streaming to HDD and Reading

    Hi,
    I have three channels at 1 KHz to 5 KHz selectable sampling rate. I would like to stream all three channels to disk in binary format with user supplied header / file name. I would like to watch data graph while continuously saving to disk and also need controls to select time duration to save data. I want to use same VI panel to read data with slider bar control. All three channels must show separate graph charts.
    This is like simple data recording and reading application in same window with three channels and binary format.
    Any help is highly appreciated,
    Kishor
    [email protected]

    I would be glad to help, but your posting sounds like you would like us to write the code for you. Have you started the project and have a specific question? You may want to look at the LabVIEW shipping examples. (open labVIEW 6.1 >> help >> find examples >> fundamentals >> file input and output. There are several examples for reading and writting to file. You may also be interested in the DAQ examples to see how to aquire the signal. Your outline for the slider suggests that you also need to know how to make a control work like an indicator and vise versa. This would be done with property nodes or local variables. Look for property examples at find examples >> programatically controlling VIs >> controlling front panel objects.

  • I want to know hardware to collect voltage and current from battery and read it through labview

    Hi all ,
    As per requirement of my job I want to measure voltage and current of battery connected to motor. I want to read those voltage and current through Labview. I want to know what hardware I need to acquire that voltage and current and feed it to computer and read through Labview.
    I also want to know, whether I need to program according to hardware I use or Whatever I will program will read data coming from hardfwarwe?
    Please give suggestions over it .
    Thanks
    c59409

    c54909,
    It depends on what equipment you have available and what is your budget.  You could for example use a storage oscilloscope with a current probe to accomplish this task.  This will give you very good timing waveforms if your charging sequences are short.
    If you are looking to automate I would recommend using any GPIB controllable power supply by Agilent or HP such as a (Agilent E3634A) and a USB-HS from National Instruments.
    Keep in mind depending on how accurate you want your data you may need a GPIB current meter to read low currents in the uA.  If you only need mA resolution you can usually use the same power supply you are making the voltage reading from.  You want to make sure you pay attention to things like current limits on your supply and Over Current Protection settings (OCP) as they can make testing interesting.
    Regards,
    -SS

  • How to create automatic creation of BP from customer and vendor master data

    Hi gurus,
    can any one tell how to create automatic creation of BP from customer and vendor master data.
    Please give me the steps.
    Thanks
    Sasikanth.

    HI,
    Goto SPRO\ Cross application components \ Master data synchronization \ Synchronization control.
    Assign account groups of customer and vendors to respective BP grouping. This setting is enough to create BP in background while creating customer / vendor. But the fields groups are very much important, ensure mandatory fields should be sync.
    rgds,
    Srini

  • Creating a Java content tree from scratch and then marshal it to XML data

    Hi,
    After binding a schema using JAXB binding, I wrote a class to create a Java content tree from scratch and then marshal it to create an XML document. To see if the resulting xml document is correct, I opened it in XMLSpy and tried to validate it against the original schema.... I got the following error:
    "Unable to locate a reference to a supported schema kind (DTD, DCD, W3C Schema, XML-Data, Biz Talk) within this document instance"
    Then I realized that the generated xml document didnot contain the following for the root element:
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" and xsi:schemaLocation="....."
    i.e, the XML Schema Instance namespace and the schema location.
    How do I get these attributes incorporated into the XML document generated during the marshal process.
    Thanks.

    How do I get these attributes incorporated into the XML document generated during the marshal process.
    Add xmlns:xsi and xsi:schemaLocation attributes to the root element in the schema.
    <xsd:attribute name="xmlns:xsi"  fixed="http://www.w3.org/2001/XMLSchema-instance"/>

  • Triggering a 6024E into data acquisition from start and end number of finite pulse generator from a 6602

    My motion control system is driven by a 6602 I wanted to acquire analog current (to a voltage via I/V converter) from a 6024 AI when:
    (1) At the start of the pulse generation
    (2) Stop at the end of the pulse generation
    (3) Read every possible data between and stream it on the harddisk
    (4) Option to skip at regular intervals to reduce amount of data accumulation
    Anyone have some suggestions? What I did try and attempted was to "loop an AI from a triggered intermediate Analog Input VIs" this is rather erratic!My question for the analog input software are:
    (1)Can you trigger an AI to start a continuous acquisition?
    (2) How do you do AI from a "start" p
    ulse train to "end" pulse train?
    (3) How do you manage time for File I/O meanwhile doing (1) and (2) above?
    Bernardino Jerez Buenaobra
    Senior Test and Systems Development Engineer
    Test and Systems Development Group
    Integrated Microelectronics Inc.- Philippines
    Telephone:+632772-4941-43
    Fax/Data: +632772-4944
    URL: http://www.imiphil.com/our_location.html
    email: [email protected]

    "(1)Can you trigger an AI to start a continuous acquisition?
    (2) How do you do AI from a "start" pulse train to "end" pulse train?
    (3) How do you manage time for File I/O meanwhile doing (1) and (2) above?"
    Answer 1 and 2)
    Yes you can, This VI is part of the search examples that ships with LV:
    "Continuous Acquisition & Graph Using Digital Triggering and External Scan Clock
    Demonstrates how to continuously retrieve data from one or more analog input channels using an external scan clock when a digital start trigger occurs."
    Go to Search Examples in the Help/Contents of LV. Then pick I/O Interfaces/Data Acquisition (DAQ)/Analog Input/Triggering an Acquisition/Triggering a Continuous Acquistion.
    This VI is appropriate ifs you want to clock the DAQ with some clock (external scan clock) other than the on board clock.
    The start trigger required by the DAQ card will be a TTL signal attached to the PFI0/TRIG1 pin of you DAQ card (via whatever signal conditioning you have).
    The external clock also needs to be TTL and is attached to the PFI7/STARTSCAN pin.
    You tell it which AI channel to use and wire that up appropriately.
    All of this stuff is in the context help for the VI.
    Answer 3)
    You have a misconception of how the acquisition makes its way into a file on the hard disk. You don't really "stream to disk." The VI above will run a buffered acquisition. The DAQ card sets up a buffer that fills with the data continously. When you use the VI you set up how the buffer is configured, you will see controls for buffer size, number of scans to read at a time, etc. The acquisition runs data into the buffer continously and reads from the buffer are a parallel process where chuncks of the buffer are extracted serially. You can end up with a scan backlog where the reads are falling behind the data. Making the buffer bigger helps. All of this is limited by the sampling capability of the DAQ card. 200kSamples/second is for one channel of AI. Divide by 2 for 2 channels. etc.
    The short answer is that the VI and DAQ card manage the file I/O for you.
    The VI above writes the scan out to the waveform chart on the front panel. You will want to wire that data out from the AI Read Sub VI to a spreadsheet file in tab delimited form or similar.
    Look inside the VI block diagram. There is a While loop containing the AI Read. Every time the loop runs (unless you hit STOP), the AI Read plucks the specified # of scans from the buffer (starting from the last unread datum). If you wire the double orange wire from AI Read out of the loop (and set the tunnel for Auto Indexing) the Vi will build another buffer in memory that is a series of AI Reads appended to each other, a sequencial record of the acquisition. Here you put in a Write to Spreadsheet VI. This is in the Functions Pallete, it is the first VI in the File I/O Pallette (icon looks like a 3 1/2 disckette).
    There is more to it than this. The spreadsheet Write is 1D or 2D only. By running the array out of the while loop with auto indexing enabled, you create a 3D array. (If you turn off auto indexing you will only get the last array performed by the AI Read.) You will need to create a new array withe the pages of the array placed serially into a 2d array. I don't think I want to get into that. It isn't that bad to do, but you should get some time messing with arrays on your own, then you will see how to do it yourself. One solution is to only run the While loop once with a buffer big enough to hold the whole acquisition, or in other words no loop at all. I don't know how many scans you want. The other thing is by wiring that AI Read out of the loop you are creating an array that must be dynamically resized as the loop runs. Kind of a no no. Better to know what you are acquiring size wise and letting the VI set up buffers and array space that does not need to be changed as the program runs.
    Caveat: I am fairly new to this and I could be wrong about the arrays and buffers and system resources stuff. However, I have done essentially what you are trying to do succesfully, but not "continuously." I limited the AI Read to one large read that gets what I need.
    "Continously" is usually reserved for screen writes as in the VI above. The computer is not required to continually allocate space for an ever expanding array to be written as a file later. Each time this VI runs the While Loop the data goes to the waveforn chart. Each new AI read overwrites the previous one. Sort of like if you turn the Auto Indexing off. When the VI stops, the waveform chart on screen would show the same data as was written to the spreadsheet.
    Feel free to email me directly: [email protected]. I will help as I can.
    Mike Ross

  • Create withholding tax data subsequently for reconciled and open items in c

    Hi All,
    Mine is a US co code and I have a  vendor for which invoice and payment documents are posted. After posting the invoice i found that the vendor is subjected to classic withholding tax which i did not calculate when posting invoice, making payments.
    Now i have changed the vendor master data with relevant withholding tax details.
    I know the program RFWT0020 allows us to create withholding tax data subsequently for reconciled and open items in cases where vendors or customers become liable for withholding tax with a tax rate of 0 %.
    It is not working out for me.
    Can any body help me on this.
    Thanks in advance.

    Dear all,
    by se38 --> report documentation, You can read carefully the following:
    The auxiliary program makes it possible to convert both classic and extended withholding tax data. However, with classic withholding tax, ONLY VENDOR data can be converted.
    In addition, the program enables the withholding tax code to be changed for reconciled and open items with existing withholding tax data. For this, the tax rate of the existing withholding tax data as well as the tax rate of the new withholding tax code must be 0%. The new withholding tax codes are taken from the customer or vendor master data. In the case of extended withholding tax, the withholding tax code is only changed if the related withholding tax categories are the same.  The withholding tax base amount is not changed by this procedure.
    Recreating or changing the withholding tax data requires that the program first be executed for INVOICES and then executed for PAYMENTS in a subsequent step.
    I hope this helps You.
    Mauri

  • Data stream from OEM device, TCP/IP "not enough memory"

    Hi Everyone,
    I'm trying to catch a data stream from an OEM device over a TCP/IP link.  I can start the data stream, or pause/resume it, but the OEM device determines when the data stream has ended.  The data stream begins, and within 20 seconds, I get the famed "not enough memory" error.  Once this happens, data is lost from the stream, and quite often the final message indicating completion is missed.  I see two solutions to this.  1) Watch how many bytes are backed up on my TCP/IP port, and issue a pause command until I can process the backed up bytes at which point a resume will be issued.  ...or 2) Use my application's memory usage in the same manner.  Does anyone know how to do either of these things?
    Thanks much

    Hi Toader,
    Thanks for your response.
    1) I'm not sending any data.  I'm trying to consume an incoming data stream which is being driven by an OEM device.  This device basically has an FPGA hooked up to a 100Mbit/s hose.  You can start it, pause it and resume it.  Those are the available operations related to consuming the data stream.  I think the crux of the problem is deciding when to pause the OEM device to give the LabView app a chance to process and store the accumulated portion of the data stream.
    2) Sure, but it's not my program and is large and complicated.  I guess I could write my own program within a program, but I would rather use the existing architecture.  I might write my own micro app, but I doubt it will keep up with the FPGA driven hose.  If I could detect the condition leading up to the "not enough memory" error, which it seems many LV developers have encountered, but not really solved, then I could issue a pause to the OEM device.
    3) Well using a LabView application under a 2Ghz Windows box may not be sufficient hardware.  But I really think it's the Windows operating system that I'm having trouble with, not the hardware platform.
    I've tried several counters in the LabView application, watched task manager before/during/after the "not enough memory" error, and downloaded an interesting app called taskmanager.vi in an attempt to get something to correlate with the error message.  I've not succeeded yet.  Here's what I think is happening.  The Windows OS is managing my wireless hardware, when it receives a TCP/IP packet, it puts it in the Windows Message que of my LabView application.  I think the "not enough memory" error relates to a Windows OS allocation for my message que which is being exceeded.  Any Windows programmers out there who would know how to look at the application's message que during runtime?
    Thanks for your classic suggestions Toader, I may try a micro app which is spawned by the main app when its time to grab the data.  My intuition is that no software limited by the Windows OS is going to keep up with single minded FPGA hardware.
    I thought this very interesting discussion was the answer and it may still be, but after trying 30+ various counters under Memory, System, Process, TCP, and Server, none correlated to the error.
    http://forums.ni.com/t5/LabVIEW/System-monitor-counter/m-p/1653448/message-uid/1653448/highlight/tru...
    I also tried a taskmanager.vi, but none of the various flavors of memory tracked by that little gem correlated with the error either.  At this point, I started to wonder "what memory was there not enough of?".
    Terry

  • Data streaming between server and client does not complete

    Using an ad-hoc app, data streaming between server
    and client does not complete as it supposed to be.
    The process runs well in solaris 5.8, however under 5.9
    we have found the characters stream buffer length limitation
    is around 900 to 950 characters (by default we are using 3072
    characters).
    Example:
    - We are transfering HTML file, which will be displayed
    in the App client, with buffer=3072, the HTML only displayed / transfered
    as xxxxxxxx characters, but with buffer=900 the HTML is displayed properly,
    in this case, the only problem that we have is the file transfer will
    eventually longer than usual.
    - There is another case, where we have to transfer information (data) as stream
    to the client. A long data stream will not appear at all in the client.
    Any ideas why the change between 5.8 and 5.9 woudl cause problems?
    The current app-driver that we are using is compiled using Solaris 5.6,
    if possible we would like to have use of a later version, which is compiled using Solaris 5.9, do you think this will probably solve our problem?
    Thanks
    Paul

    Does this have anything to do with Java RMI? or with Java come to think of it?

  • Issue in creating a custom data model from BP

    Hi Team
    We have a requirement to create a custom data model by copying data model BP. I have successfully created new data model ZP . I have copied the UI for searching from BP. Issue is when i search a business partner  ideally it should not display any entries because i have just created the data model, But it is taking entries from BP and getting displayed. Please let me know how to map data model to search UI. I dont see option USMD_MODEL here

    Hi Imran,
    actually that is not an issue but a designed feature. I'm afraid that you need to re-think your whole project. The explanations is rather simple:
    Data model BP in MDG is a so called Re-Use Area data modell. This means that active data (records that are currently not stored in a change request) are saved in existing SAP ERP data base tables like BUT000 for the business partner master data and LFA1 or KNA1 for Vendor or Customer master data.
    If you copy data model BP to ZP you still refer to the same active area. You will always find the same active objects - no matter which data model you are actually using for the user interface. The only difference wil occur for objects being currently processed in a change request. In that case a separation between BP and ZP is possible. But this won't help to solve your issue.
    From SAP side I can only recommend not to copy BP but to find a different way of integrating your project needs into BP.
    Best regards
    Michael

  • Data extraction from SD and MM modules

    Hello people,
                        I want to know what are all the ways by which we can extract data from SD and MM modules including LO LiS cockpit, like how easy or difficult it will be using LO, can we extract this data using business content, creating two background users in BW and R/3 systems and using logical and client systems for extraction. what would be the simplest way to extract this data?
    thanks and Regards,
    Ethan

    Hi Ravi,
                thanks for your time. Is LO or LIS cockpit the only way to extract data from SD and MM modules ? are there any other ways and if business content can be used in those ways, please let me know. Also, tell me if  these steps would work in extracting data from SD and MM modules:
    1. creating a logical system for the R/3 client
    2. creating a logical system for the BW client
    3. Naming background users
    4. Creating R/3 source system in BW
    5. transferring R/3 global settings
    6. replicating R/3 data sources.
    7. Installing business content objects and then loading R/3 data.
    Thanks and regards
    Ethan

  • Continuous data transfer from vi to sub-vi

    I am working on a data acquisition vi, and one of the
    features is to have one or more user-configurable x-y
    plots displaying real-time data. I have it working
    with the plot running in the main vi. Now I want to
    create a sub-vi for the plot, and once it's open, to
    write additional data to it as the data is acquired.
    I'm thinking I will use a queue, but I'm open to any
    expert opinion on the best way to do this.

    A queue would be a good way to do it in that queues will guarantee you won't lose any data. The only problem you might have is if the data source is streaming data to the display really, really fast. If the display VI is doing any find of processing that would slow it down, you could overrun your queue. All in all though, it sounds like a good approach, give it a try and keep us posted on how it comes out...
    Mike...
    Certified Professional Instructor
    Certified LabVIEW Architect
    LabVIEW Champion
    "... after all, He's not a tame lion..."
    Be thinking ahead and mark your dance card for NI Week 2015 now: TS 6139 - Object Oriented First Steps

  • Data Extraction from CRM and Informatica

    Hi Guru's,
    Could any one tell me how to extract the data from the CRM and Informatica in to BW.
    Please give me the steps.
    Thanks in advance....

    Steps for Extracting data from CRM:
    Configuration Steps
    1.Click on ->Assign Dialog RFC destination
    If your default RFC destination is not a dialog RFC destination, you need to create an additional dialog RFC destination in addition and then assign it to your default RFC destination
    2.Execute Transaction SBIW in CRM
    3.Open BC DataSources.
    4.Click on Transfer Application Component Hierarchy
    Application Component hierarchy is transferred.
    5.SPRO in CRM .Go to CRM->CRM Analytics
    6.Go to transaction SBIW-> Settings for Application specific Data Source ->Settings for BW adapter
    7.Click on Activate BW Adapter Metadata
    Select the relevant data sources for CRM sales
    8.Click on Copy data sources
    Say yes and proceed
    9.Logon to BW system and execute transaction RSA1.
    Create a source system to establish connectivity with CRM Server
    A source system is created. (LSYSCRM200)(Prerequisites: Both BW and CRM should have defined Back ground, RFC users and logical systems)
    10.Business content activation for CRM sales area is done
    11.Click on source system and choose replicate datasources.
    KJ!!!

  • Data transfer from R3 and BW TO external system

    Hi experts
    I got one question which I couldnt find good answer.
    it concerns...data transfer from both R3 system and BW(here data is master data) to an external system.
    what are the various options to do this both from BW side and R3 side?
    which of them offers best performance?
    Thanks
    BR
    Amanda
    Edited by: amanda ciders on Nov 20, 2008 2:17 PM

    Hi
    Im aware that I can use OpenHub Functionality for this.Can anyone explain how to do this as I am unable to implement this for this situation.....
    do anybody know other solutions like creating views or FM like that...
    .it will be of great help if u can explain any solution in greater detail(including open hub)..
    Thanks
    BR
    Amanda
    Edited by: amanda ciders on Nov 20, 2008 2:26 PM

  • CS6 creates tiled image when moving from LR4 and HDR Effex Pro

    Just recently I've had a problem with CS6 where it creates a partial (tiled) image when "Edit In" from LR4 and when saving back to CS6 from HDR Effex Pro. THe image may have one or several retangles which may be black, white, or part of the image that's in the wrong place if that makes any sense. All software is running with current updates. I've had the software about 6 months and never incurred this problem until the last week. Help!

    I've run through several scenarios and find that it's always in CS6 that I have the problem. I opened a file in all modules of Nik as well as OnOne's Perfect Photo Suite. When I go back (save) to CS6 there is always a problem. When I save in CS6 and then open up in LR the image is fine. So the file must not be corrupt, it just doesn't present it properly in CS6. The GPU driver appears to be up to date....last update was in 2011 and I've had this computer since late 2012.

Maybe you are looking for