Discussion:
Is it possible to do DAQ with sample sizes that are not predetermined?
(too old to reply)
PigeonMan
2008-07-30 19:10:08 UTC
Permalink
This is a question that I think is independent of platform and/or soft/hardware. When using single- or double-buffered acquisition, it is my understanding that one has to specify a buffer and block size when starting sampling an analog signal. When sampling is finished, one can retrieve one complete block from the buffer, but not fractions of it. In my application, I can't know the block-size beforehand. Consider the following application: You have a START button (which starts sampling) and a STOP button (when some variable time interval -- anything between 20 sec and 10 min -- has elapsed), which should retrieve the samples that were collected between START and STOP. What is the general scheme to program this? (I am not using LabVIEW but NI-DAQ drivers with C/C++ and Metrowerks on a Mac).Any hint would be greatly appreciated.P.S. If you are curious ... I study bird behavior. I measure the bird's beak opening by using a Hall effect device and a small magnet (harmlessly glued to the bird's upper and lower beak). The resulting analog signal (changes in voltage proportional to beak opening) is sampled. But I only want to measure beak openings for certain amounts of time (between the presentation of a visual stimulus and the bird's peck to the stimulus, which could be of very short or very long latency).
Paul C.
2008-07-31 16:10:10 UTC
Permalink
Hi PigeonMan,I assume you are using our DAQmx Base driver which is supported on Mac's.  It is actually quite possible to read data from the DAQ card in fractions.  The DAQmx base read function call allows you to specify the number of samples to read.  On a continuous acquisition or an acquisition over some length of time, all you need to do is call the DAQmx read in a loop and specify the amount of samples to read from the buffer each iteration.  This is demonstrated in the contAcquireNChan.c example.  These examples are typically installed on a Mac to the folder here: /Applications/National Instruments/NI-DAQmx
Base/examples.  Calling the DAQmx read in a loop as shown in this example will allow you to collect data from the buffer while it is acquiring new data.  If you have any additional questions or need more explanation, please include which DAQ card and driver / version you are using.  This will help me better tailor a solution that meets your needs.I hope this helps,Paul C.
PigeonMan
2008-07-31 18:10:13 UTC
Permalink
Hi Paul C., I appreciate your help.I am using NI-DAQ 4.9 and a PCI 1200 board on Mac OS 9.2.2 (beige mini tower) ...I have been using this set-up for about 10 years. I know it's high time -- to say the least -- to update my hardware and software but I am trying to fix this problem until I have a chance to upgrade. (I am running a small psychology lab at CUNY with no tech support -- and I am only a self-taught programmer -- and the equipment is paid for by grant money which is hard to come by nowadays. So as long as I can keep afloat, the better for now.)I realize that there might not be any support for my set-up anymore, and, if I know it's not possible to get around this problem, I may have to finally make the jump and upgrade. Good in the long run. But I thought that the application I described was a common one (i.e., being able to specify the block size after the fact and it would add tremendous functionality to the set-up), thus I'd be surprised if this was not possible to do even with the old, low-cost equipment.Any hint or help is appreciated. I'll check into your detailed suggestions and try to find out if these are applicable to my current set-up. But if you do know any information off hand, it'd be great.Bertram
Paul C.
2008-07-31 19:40:16 UTC
Permalink
Hi Bertram, Our driver has changed a bit over the years so my above solution was more geared towards our newer driver and how it behaves.  In regards to NI-DAQ 4.9 things behaved a little differently.  First of all the driver is different in how it handles setting up a buffer and interacting with that buffer.  Our newer driver uses something that looks like a circular buffer in how it writes data from the device to the buffer.  This is all handled automatically by the driver.  If you do have the budget, I would highly recommend taking a look at some of our newer low-cost devices to replace your older system.  The newer driver makes this type of application very easy to implement.  In regards to using the older software, things must be done a bit more manually.  The way I understand the question is that your current way of using the driver is to setup an acquisition, acquire all the data, and call a single read to gather all of the data from the buffer.  I assume that "block size" refers to all the data acquired. The theory behind the information I suggested previous post could still be done.  After configuring and starting a continous acquisition, you can setup a loop in software to read chunks of data (chunks of the entire block of data) from the previously setup buffer.  All that needs to be done to set this up is to make sure that you are configuring your DAQ task to do a continous acquisition.  This will allow you to call the AI Read in a loop after the acquisition starts to essentially read chunks of the "block size" before the acquisition finishes.  This allows you to run for a variable amount of time without changing configuration.I hope this helps you get started a bit.  I've been searching around and unable to find any examples that demonstrate some of this behavior.  You best option would be to search through the installed examples that shipped with the driver and see if you can find any that talk about continuous acquisition.Regards,Paul C.Regards,Paul C.
PigeonMan
2008-07-31 20:10:10 UTC
Permalink
Hi Paul, I think I understand the logic of this and I'll try. However, it seems to me that if I put a software loop in as you suggested (i.e., for AI calls), (a) nothing else can be done during that time because the loop is not in the background (checking on occurrences of other events) and (b) I won't have control over the clock rate. Is this correct?Do you know where/how I could find a software developer "for hire" to just provide me with the sample code, if needed? I have some money available for this?I have considered purchasing new cards but that'd also require me to get new computers and new touch screen monitors. I am using four computers, so this would go into the thousands quickly. In addition, Apple has switched to XCode (if I understand correctly, you can embed C/C++ into this), and I don't have the expertise in switching to a new software approach in addition to new hardware. I know I will have to do this sooner or later (rather sooner than later) but for the one specific problem I am dragging my heels. I was hoping that I can continue with what I have and then, separately start building one prototype system to learn the approach.Again, I appreciate that you are helping me with this.Bertram
Paul C.
2008-08-01 14:40:21 UTC
Permalink
Hi Bertram, The loop that handles the read can also handle the checking of other events.&nbsp; I'm not sure what you mean by "clock rate".&nbsp; If you mean the sample rate, then yes you cannot change this without stopping and starting the task.&nbsp; If you mean how long the total acquisition occurrs, this can all be done inside the loop by checking a clock rate variable and breaking out of the loop after that amount of time.In regards to the software developer "for hire".&nbsp; We have several alliance members that write code for customers.&nbsp; A list of these companies can be found by going to <a href="http://www.ni.com/alliance/" target="_blank">here</a>. Regards,Paul C.
PigeonMan
2008-08-01 20:40:09 UTC
Permalink
Hi Paul, The list of programmers is very helpful. I'll have a much bigger project (game development for working with children with autism) coming up and we have been looking for someone who can help with this. (Probably not before January though.)I might also try to hire someone just to work out this one problem we had been discussing. My abilities are probably too limited to implement the suggestions you made. However, I thought about the problem a bit more. It's really like a digital recorder (instead of an audio wave it's a relatively simple wave corresponding to beak movement). Now with a digital audio recorder you hit "Record" and the sampling starts (no way of knowing beforehand for how long you'll record) and you stop it by pushing STOP. Then there is an audio file that you can process anyway you want.So I have been looking through the examples that are provided with the old NI-DAQ 4.9. There is one example "StreamToDisk(1ch)" which supposedly works with PCI 1200 and NI-DAQ 4.9. Description: " ... perform single-channel data acquisition and stream the data to disk as the data is acquired." Presumably I should be able to start and stop the streaming process. (I am sampling two channels actually, but to go from one channel to two should be trivial as the commands that are being used are adaptable to multi channel acquisition and I have used them before.) Does this sound like a reasonable approach to pursue? Perhaps this example does what you suggested?Bertram
Paul C.
2008-08-04 13:40:09 UTC
Permalink
Hi Bertram, That actually sounds exactly like what I was mentioning above.&nbsp; Now, that example might include some file save features that I didn't mention, but it sounds like that is what you will be looking to do anyway.&nbsp; Let me know if that example works for what your looking to do.Regards,Paul C.
PigeonMan
2008-08-15 19:40:20 UTC
Permalink
Hi Paul,&nbsp;I haven't made any headway with this issue. I have no idea why it's not working. I don't get error messages. When I use DAQ2TGet repeatedly (in a while loop until no more samples can be retrieved), it also does this without error. But I do not get any samples in the array (specified in the DAQ2TGet function). I suspect it has to do with DAQ2Config, Lab_ISCAN_Start, and DAQ2TGet and how I specify the size of the circular buffer and the smaller block.&nbsp;The examples provided are for one channel only or do not use my PCI 1200 board. One example with double-buffered acquisition and streaming to a disk uses &quot;continuous mode disabled&quot;. Why would one want to disable continuous acquisition if in double-buffered mode? I thought the entire idea of using DAQ2 IS to be able to acquire data continuously.&nbsp;&nbsp;I have looked into the Alliance Partner registry to locate someone who might be able to help me for pay but I couldn't identify anyone. Search 0.&nbsp;... so I am at my rope's end.&nbsp;Bertram&nbsp;
PigeonMan
2008-08-15 21:10:07 UTC
Permalink
Hi Paul,&nbsp;I think I figured out what is going on but I still don't know how to solve it. The background sampling is working fine (thus no errors). I think I have been using DAQ2TGet incorrectly (because I made wrong assumptions). For example:&nbsp;// ...&nbsp;while (samplesRemain &gt; smallBlock){ // ...&nbsp; DAQ2TGet(slot, 0, 0, 0, bigBuffer, 0L, smallBlock, &amp;samplesRemain, 0L);} &nbsp;This works fine EXCEPT smallBlock always writes into bigBuffer at the same (begin) index, thus overwrites the content of bigBuffer. After the while loop, I only get the last smallBlock, stored in the beginning of bigBuffer. I had incorrectly assumed that it'd automatically advance the index in bigBuffer every time it retrieves smallBlock).&nbsp;In one example provided by NI, there is a line which uses the left-shift operator &quot;&lt;&lt;&quot; but it's used to write to a file. I want it to act on bigBuffer so everytime smallBlock is retrieved, it'll concatenate to bigBuffer. How can one force new data to be written to a new index in an array (bigBuffer)?&nbsp;Bertram&nbsp;
Loading...