The hex result of this code sample is 0xBA (186 decimal)
Not so far as I can tell; it's 0xB5, which is expected for a simple reason that you'll see. And when modified slightly it matches the 0x49 value. I'm inclined to trust that your code is correct, so far as you've shown it, but your report of what's doing is not correct.
I verified every input parameters with gets and prints, they're all correct
Well, no. As I mentioned in a comments on the question, I get the expected 0x49 on the first site you mentioned with the correct settings. I'm not sure why you're showing 0x6E. But guess what happen if I hit enter after "TEMPS;"? 0x6E. The newline character matters. Also, I do get a 0xBA if I use the correct input but fail to set CRC8 to custom and change 0x07 to a 0x31 in the polynomial. So, maybe that's how you found that value.
If you switch to bytes mode the site expects a sequence of character code values and ignores whitespace (apart from treating it as a delimiter). You can put 0x54 0x45 0x4d 0x50 0x53 into it in bytes mode to see 0x49 result also. You can then add 0x0D (newline) to see it to result in a 0x6E from before.
Regarding the middle site, the settings aren't correct (the reverse setting is on for input and output) and I don't see how to make them correct; they don't seem to have a custom option. However, you can turn on the reflect options on the first site to get the same result as in the 2nd site in order to convince yourself that is what is going on. The third site's output is correct for what you've put into it. It just doesn't match what you're code is actually doing.
Your basic problem is the +1
in this line:
crcTrame.add((uint8_t *)arrayForCrc, crcDataLength+1);
You've included the null terminator in the calculation. This is 7 bytes: 'T', 'E', 'M', 'P', 'S', ';', '\0'. These websites just aren't doing that; they are not automatically adding a null terminator at the end of whatever you type in string mode. Alternately, if you wanted the null terminator in the CRC calculation, your code is fine, but you're going to need to switch to HEX input mode on the website and enter a 0x00 into it after the hex values for the other characters in TEMPS; so as to match. And it will match, I've tested this. You can also: put the first site into bytes mode and put "0x54 0x45 0x4d 0x50 0x53 0x3b 0x00" into it and you will see it now produces a 0xB5, like your current code.
Otherwise, you just need to not enter the null terminator into the calculation:
crcTrame.add((uint8_t *)arrayForCrc, crcDataLength);
This will result in 0x49
coming out of crcTrame.getCRC()
instead of 0xB5
:
#include "CRC8.h"
void setup() {
Serial.begin(9600);
}
void loop() {
String crcData = "TEMPS;";
int crcDataLength = crcData.length();
char arrayForCrc[crcDataLength+1];
crcData.toCharArray(arrayForCrc, crcDataLength+1);
auto crcTrame = CRC8(0x31,0,0,false,false);
crcTrame.add((uint8_t *)arrayForCrc, crcDataLength);
String stringCrcNoHex = String(crcTrame.getCRC());
String stringCrc = String(crcTrame.getCRC(), HEX);
Serial.println(stringCrc);
}
If you also want to sanity check what happened with the 0x6E output earlier, you can then change crcData
to String crcData = "TEMPS;\n"
(adding the newline) and watch it start printing 6E.
There's a .getBytes()
function in String that is pretty much what you have without needin the cast:
crcTrame.getBytes(arrayForCrc, crcDataLength);
I'm not sure if you have a good reason for "TEMPS;" to begin life in a String
or then to have to get it into an character array. If you're only doing this so you can then call crcTrame.add()
, well, you needn't:
#include "CRC8.h"
void setup() {
Serial.begin(9600);
}
void loop() {
String crcData = "TEMPS;";
int crcDataLength = crcData.length();
auto crcTrame = CRC8(0x31,0,0,false,false);
crcTrame.add(
(const uint8_t *)crcData.c_str(),
crcData.length() // <- Does not count null terminator.
);
String stringCrcNoHex = String(crcTrame.getCRC());
String stringCrc = String(crcTrame.getCRC(), HEX);
Serial.println(stringCrc);
}
Note: I'm only creating stringCrc
to mirror what you were doing. Here, it could just as easily be Serial.println(crcTrame.getCRC(), HEX);
and potentially in whatever context you're doing it in. The cast can also be done in a more C++ approved (though uglier way with crcTrame.add(reinterpret_cast<const uint8_t *>(crcData.c_str()), crcData.length());
Any sequence of any number of add()
calls that delivers the same data in the same order into calculation will yield the same CRC. There's also an overload of add()
that takes an individual character without needing to involve a pointer at all. So your data doesn't need to come from a String
, nor be a null-terminated string, or character array, nor fit entirely in memory.