10-17-2018 09:57 AM
Thanks for all of the cleanup guys. I tested the snippet to see if it included the subVI for generating the lookup table and when I tried it the subVI was included. That is odd.
To the OP, did you know you can save the picture and then drag that into a VI? Snippets do copy the code so it was included. Unless of course you are using an older version of LabVIEW then you wouldn't be able to open the snippet.
10-17-2018 10:53 AM
@Mark_Yedinak wrote:
Thanks for all of the cleanup guys. I tested the snippet to see if it included the subVI for generating the lookup table and when I tried it the subVI was included. That is odd.
Is the subVI really included in the snippet, or is it because the original subVI is somewhere on your local hard drive and the snippet is linked to that file. This is the message I get when hover over the icon.
10-17-2018 10:55 AM
It must have found it on my system. I'll have to keep that in mind in the future.
10-17-2018 12:13 PM
@jamiva wrote:Is the subVI really included in the snippet, or is it because the original subVI is somewhere on your local hard drive and the snippet is linked to that file
Snippets do not include subVIs. So it definitely used the one already on Mark's hard drive.
10-18-2018 03:10 AM
Thanks for all the input, I now have something that works.
However, referring back to my first question, I spent the best part of yesterday checking the function and code used to create the .dll file and everything seemed to be working, and I only experienced problems implementing it in LabVIEW.
Does anyone have any suggestions as to why that was the case?
10-18-2018 06:12 AM
@CCloggie wrote:
Does anyone have any suggestions as to why that was the case?
If I had to take a completely wild guess, it would be that the byte array was being treated as a C string, which terminates with a NULL character (0x00). But I didn't see anything in your call that should have done that.
10-18-2018 06:41 AM
Hi!
Bear in mind that there's not "the" CRC function.
Without going into detail, the CRC algorithm needs a constant parameter, which is different between use-cases.
https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Polynomial_representations_of_cyclic_redundanc... lists 11 different values for that parameter in CRC-16 (3rd row in table). And there are different definitions how to read the parameter.
Next, there's a start value, which of course also can be different from one to the next use-case. In my current project, the start value is the result from the last CRC calculation .
And then, the calculated CRC value is often XORed with an other number to get the actual CRC value. And that other number is, as you might guess, not the same everywhere.
Now, there are different implementations of CRC functions out there. Some reduce computing time by using a lookup table at some point, others just don't care and calculate everything.
I needed a special CRC8 function myself these days, and derived the attached VI from some C code found on the web. That C code can be found as screen shot in the block diagram.
This isn't CRC16, but it should be adaptable.
Hope that helps!
10-18-2018 09:39 AM - edited 10-18-2018 09:50 AM
@CCloggie wrote:
However, referring back to my first question, I spent the best part of yesterday checking the function and code used to create the .dll file and everything seemed to be working, and I only experienced problems implementing it in LabVIEW.
Does anyone have any suggestions as to why that was the case?
Don't know if this will help. I have successfully created CRC .dlls in the past. I can't for the life of me remember why, but I always define the "C" function prototype for the Data as "UNSIGNED CHAR" (in both the *.c and *.h files). HOWEVER, when I configure the LabVIEW function prototype in the "Call Library Function", I still declare the LabVIEW as a pointer to a U8 array. Why having two different prototypes between C and LabVIEW works for me...who knows??? Will it work for you?? If you have the time, try it and see.
/* My C Function Prototype */
unsigned long get_crc (unsigned char *blk, unsigned long blk_len);
EDIT: This prototype is for a CRC32. For a CRC16, use unsigned int instead of unsigned long for the return type.
My LabVIEW Function Prototype
10-19-2018 06:54 AM
Don't know if this will help. I have successfully created CRC .dlls in the past. I can't for the life of me remember why, but I always define the "C" function prototype for the Data as "UNSIGNED CHAR"
I think I may have remembered why. It's not the CHAR, but rather it's the UNSIGNED declaration that is important in the prototype. As described here (https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts), there is a difference between an arithmetic shift and a logical shift. An logical shift right will shift in ZEROs on the MSB. An arithmetic shift will shift in the "sign bit" for SIGNED integers.
From what I read, the implementation of the ">>" operator depends on the C compiler. I verified with LabWindows that ">>" does an arithmetic shift for SIGNED integers (not what you want). That's why I needed to explicitly type it as an unsigned char to force a logical shift, not an arithmetic shift.
LabWindow's (for a SIGNED integer)
0xA4 (0b10100100) 0xA4>>2 = 0xE9 (0b11101001)
This may be the reason that the *.dll doesn't work now as expected (did the OP change compilers?). In the first exemplar the OP used, all the interim values of CRCV>>8 just happened to have a ZERO sign bit and it worked perfect. His second exemplar did not.
crcv = (crcv >> 8) ^ crc_16_table[*(data++) ^ (crcv & 0xff)];
1st exemplar with correct CRC
2nd exemplar with incorrect CRC