LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Sinc Filter Implementation using DLL

Solved!
Go to solution

Dear All,

 

I am trying to implement a sinc filter to a stream of data which I am getting from FPGA board. The code in C is already working and what now I am trying to do is to either implement the same algo on LabVIEW or make DLL and use it and I am currently doing the later approach (Don't know which one is better, any thoughts? ). I am using this tutorial and it is working quite fine for me in case of the same example i.e of multiplying please see the attached VI.

I am getting raw data stream in .csv file and then I am reading this file. Then what I need to do is to implement a sinc filter so that every 32 points in this data set will make 1 sample for my function. I am attaching a sample .csv file for data , a txt file of C code (for 3rd order just to give you an idea) already working, my DLLs and VI. 

Specifically I am having problem about the parameters selection for DLL for example what should I select in LabVIEW DLL function parameters that corresponds to "unsigned char *data" and also for others as written in C code. If someone can provide me with some VI he has created to implement sinc funtion or some ideas that would also be great.
Any help/advice from you guys will be highly appreciated.

 

Regards,

Naqqash

Naqqash
0 Kudos
Message 1 of 8
(5,520 Views)

unsigned char is an unsigned byte in LabVIEW. double is a 64 byte floating point number. The asterisk means it's a pointer. This could be a single byte passed by reference or an array data pointer. Which it is can not be determined from the C syntax of the declaration alone, as C syntax is rather ambigous here. That is something that needs to be elaborated over in the documentation to the function.  If it is a skalar passed as reference you are done but if it is a pointer to an array you have some more detective work to do.

 

You have to find out if the function expects data to read in that parameter, or if it will write something into that array. For an input parameter to the function you are also done now, because whatever array or string you will create in LabVIEW to pass to the function, will be enough. If the function however returns some information in that array the average LabVIEW programmer is tempeted to just pass in an empty array. After all a VI returning a string or array doesn't require anything special, it simply creates whatever string or array is needed automatically. Big failure!!!!!!

 

The C DLL has no way to create such an array in a way that LabVIEW could deal with. In fact if you would do a DLL function that creates such a memory block you could not interface it to other applications without following the exact protocol defined by this particular DLL developer, including using a very specifically defined memory manager function, documented in the funciton description, to deallocate that pointer later, or your program would create a memory leak otherwise.

 

Instead the usual way is that the caller allocates the necessary memory (being very careful to make sure to allocate for the maximum possible requirement of the DLL function) then calls the function with that buffer and then deallocates the memory afterwards with whatever method matches the used allocator. In LabVIEW this means you would use the Initialize Array function to allocate an array of the correct size, pass it as Array Data Pointer to the DLL and then use the resulting array or string like any other LabVIEW data value. No explicit deallocation is required here, since the original array created with Initialize Array is a fully managed LabVIEW data type already and will be taken care of by LabVIEW.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 2 of 8
(5,503 Views)

Wohoo so much information i've a stack overflow here 😛

 

Thanks for the reply. I am not that expert so  honestly most of the information you gave went over my head :).. Now let me explain you my situation in detail, but still got some idea.

 

I have a .csv file with data which I am reading and getting the row of that file in an array. So that array corresponds to my "unsigned char *data" variable means the values I will get from my spreadsheet file will be stored in this "data" variable and after the execution of this function I will get some values again as array in yout which is again a pointer to yout in my declaration. 

 

so to answer this part "You have to find out if the function expects data to read in that parameter, or if it will write something into that array" I am writing data to "data" variable from the .csv file and then after execution of the function I am storing the values to yout varaiable.

 

Specifically, I am trying to implement sinc function on some data and some guy already had implemented this using VC++ so this function is one part of that whole GUI. So I am guessing now I was not clear enough in this regard. The problem is that I can not change the C code or can dig deep into it and ofcourse can not provide the whole code here. So I am trying to get the general idea I have already tried few small functions even with array and pointer by same procedure but they all had some return type but here in this case there is no return type ( I don't think it should  be an issue?). It would be great if you can give me advice for this whole project. I am even not sure the DLL method is better or should I apply directly the algo but I found it more convenient this way i.e by using DLL. 

 

So summing it up let say I have 

 

unsigned char data[MAX_DATA_BYTES]; // data array for the byte-packed bit-stream
double yout[5000000+512]; // data array for filter output

 

and then the function ;

void sincfilter(int imax, unsigned char * data, double * yout, int OSR, int order) 

 

The problem is I am not getting any error also 😮 but my yout array is always empty and therefore I am guessing that I am making some mistake in passing the values.

 

 

Naqqash
0 Kudos
Message 3 of 8
(5,495 Views)

A shorter explanation (Rolf provided a detailed one): you need to initialize the Yout array, or set a minimum size for it.  The DLL does not allocate the array for you, it just modifies the array that is passed to it.  Since you pass an empty array (the Yout input is unwired) into the DLL, you get an empty array out.  Use Initialize Array to create an array of the correct size, wire that to the input side of the Call Library node, and you should get a non-empty array out.

Message 4 of 8
(5,490 Views)

I tried to give you the general discription of what to watch out for. Because in about 97% of the cases where people get an 1097 error or the Call Library Node doesn't seem to do what they want, it's because they forgot to allocate buffers for output parameters. In your C code if you declare your two variables with

 

unsigned char data[MAX_DATA_BYTES];

double yout[5000000+512];

 

you are allocating implicetedly memory on the heap as static memory. LabVIEW being a fully managed environment doesn't have something like static memory for variables, but you still need to allocate those buffers somehow. The Initialize Array node is the method to allocate a buffer to hold an array of a certain size, so that you can pass it to the Call Library Node.

 

Nathan already explained to you in detail about your specific issues. I was hoping to create a somewhat more generic explanation, so that other people coming across this might see the point they have to be careful about. I'm not sure I have succeeded though.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 5 of 8
(5,487 Views)

Rolf and Nathan,

 

thanks a lot. Now I have understood what Rolf was saying initially. But the problem for me still exist. As you guys suggested I am initializing the array for 'yout' but all I am getting is value which I am giving it to its elements nothing is being done by my function at all on yout. Any idea? The vi and the code file is attached.

Naqqash
Download All
0 Kudos
Message 6 of 8
(5,474 Views)
Solution
Accepted by topic author Naqqash

There are many discrepancies between what you do in your VI and what your text file shows is the C code.

 

1) the order of parameters is VERY different.

2) You use int64 in the LabVIEW diagram, but int in the C code. Under Windows 32 bit and 64 bit (and also Linux), an int is ALWAYS a 32 bit value.

3) You read in a 1D array of strings and pass it to the Call Library Node as native data. This passes a LabVIEW array handle of LabVIEW string handles. A VERY big difference to the byte array pointer you expect in the C code.

 

You need to convert the strings into a byte and then configure the Call Library Node to pass this as an array of unsigned 8-bit integers, passed as Array Data Pointer.

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 7 of 8
(5,470 Views)

Hi Rolf,

 

Thanks a  lot. You were write I was making mistake in case of order which later when I changed some variables did not noticed now it worked. Thanks to Nathan as well.

Naqqash
0 Kudos
Message 8 of 8
(5,467 Views)