In de telegrammen die ik uitlees uit de P1 poort van de slimme meter zit een CRC16 checksum.
Het lukt mij echter niet om die zelf uit te rekenen. Dit is nodig om te zien of het telegram geldig is.
De DSMR spec schrijft op
http://www.netbeheerneder...el=Documenten&pageindex=1
CRC is a CRC16 value calculated over the preceding characters in the data message (from
“/” to “!” using the polynomial: x16+x15+x2+1). CRC16 uses no XOR in, no XOR out and is
computed with least significant bit first. The value is represented as 4 hexadecimal charac-
ters (MSB first).
- is nu ¨/¨ het eerste teken waar begonnen moeten worden?
- is ¨ |¨ het laatste teken of juist het teken ervoor waar gestopt moet worden?
- worden alle tekens, ook CR en LF mee genomen ?
- welk van de tig CRC16 algoritmes wordt bebruikt ?
Ik gebruikt onderstaand:
#define BYTE unsigned char
#define USHORT unsigned short
USHORT crc16(const BYTE *data_p, int length)
{
int pos;
int i;
USHORT crc = 0x0;
for (pos = 0; pos < length; pos++)
{
crc ^= (USHORT) data_p[pos];
for (i = 0; i < 8; i++)
{
if ((crc & 0x0001) == 0x0001)
crc = (crc >> 1) ^ 0xA001;
else
crc >>= 1;
}
}
return crc;
}
...
Het lukt mij echter niet om die zelf uit te rekenen. Dit is nodig om te zien of het telegram geldig is.
De DSMR spec schrijft op
http://www.netbeheerneder...el=Documenten&pageindex=1
CRC is a CRC16 value calculated over the preceding characters in the data message (from
“/” to “!” using the polynomial: x16+x15+x2+1). CRC16 uses no XOR in, no XOR out and is
computed with least significant bit first. The value is represented as 4 hexadecimal charac-
ters (MSB first).
- is nu ¨/¨ het eerste teken waar begonnen moeten worden?
- is ¨ |¨ het laatste teken of juist het teken ervoor waar gestopt moet worden?
- worden alle tekens, ook CR en LF mee genomen ?
- welk van de tig CRC16 algoritmes wordt bebruikt ?
Ik gebruikt onderstaand:
#define BYTE unsigned char
#define USHORT unsigned short
USHORT crc16(const BYTE *data_p, int length)
{
int pos;
int i;
USHORT crc = 0x0;
for (pos = 0; pos < length; pos++)
{
crc ^= (USHORT) data_p[pos];
for (i = 0; i < 8; i++)
{
if ((crc & 0x0001) == 0x0001)
crc = (crc >> 1) ^ 0xA001;
else
crc >>= 1;
}
}
return crc;
}
...