Hi,
ich will meinen Zähler auslesen der alle paar Sekunden eine SML
Nachricht schickt. Das Problem ist nur das die CRC Berechnung der
Nachricht nicht funktioniert. Die Berechnung soll nach CRC16-CCITT
erfolgen und somit nutze ich folgenden Code:
uint16_t sml_calculate_checksum(uint16_t crc, uint8_t data)
{
int i;
crc = crc ^ ((uint16_t)data << 8);
for (i=0; i<8; i++)
{
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
return crc;
}
für jedes Byte was rein kommt berechne ich die CRC neu.
Als Start CRC wert habe ich 0x0000 und 0xFFFF ausprobiert.
Laut Spezifikation sollte ja erst ab dem 9. Byte mit der Berechnung
begonnen werden und dann bis zum 3. Letzen Byte da die letzen beiden
Bytes die CRC der Nachricht enthält.
Ich hab die Spec. nochmal an diese Nachricht angehängt.
Jemand hier aus dem Forum schonmal so was ausgelesen?
Gruß
Daniel
Ach ja hier mal eine Testnachricht:
uint8_t simu_massage[312] = {0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01,
0x01, 0x76, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x77, 0xEB, 0x62, 0x00, 0x62,
0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x07, 0x00, 0x1A, 0x00,
0x0D, 0x27, 0xF9, 0x09, 0x04, 0x03, 0x9F, 0xC8, 0xDE, 0x57, 0xE9, 0x6D,
0x01, 0x01, 0x63, 0xD3, 0xDA, 0x00, 0x76, 0x07, 0x00, 0x1A, 0x00, 0x00,
0x77, 0xEC, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77, 0x01,
0x09, 0x04, 0x03, 0x9F, 0xC8, 0xDE, 0x57, 0xE9, 0x6D, 0x01, 0x72, 0x62,
0x01, 0x65, 0x00, 0x0D, 0x09, 0x8D, 0x77, 0x77, 0x07, 0x81, 0x81, 0xC7,
0x82, 0x03, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x04, 0x45, 0x4D, 0x48, 0x01,
0x77, 0x07, 0x01, 0x00, 0x00, 0x00, 0x09, 0xFF, 0x01, 0x01, 0x01, 0x01,
0x09, 0x04, 0x03, 0x9F, 0xC8, 0xDE, 0x57, 0xE9, 0x6D, 0x01, 0x77, 0x07,
0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x63, 0x02, 0x00, 0x01, 0x62, 0x1E,
0x52, 0xFF, 0x56, 0x00, 0x00, 0x00, 0x7F, 0x97, 0x01, 0x77, 0x07, 0x01,
0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x56,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08,
0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x56, 0x00, 0x00, 0x00,
0x7F, 0x97, 0x01, 0x77, 0x07, 0x01, 0x00, 0x0F, 0x07, 0x00, 0xFF, 0x01,
0x01, 0x62, 0x1B, 0x52, 0xFF, 0x55, 0x00, 0x00, 0x00, 0x00, 0x01, 0x77,
0x07, 0x81, 0x81, 0xC7, 0x82, 0x05, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x83,
0x02, 0x2A, 0x81, 0x58, 0xE0, 0xA4, 0x20, 0x04, 0x4A, 0x5C, 0xAE, 0x4D,
0xAA, 0xEF, 0x00, 0x74, 0xEF, 0xBD, 0xFE, 0xC1, 0x81, 0xAD, 0x29, 0xAE,
0x1D, 0xF2, 0x24, 0x4F, 0x82, 0x58, 0x02, 0x93, 0x38, 0x48, 0xCE, 0xD8,
0x7C, 0x55, 0xEA, 0x25, 0xC3, 0x55, 0x88, 0x0F, 0x97, 0x26, 0x10, 0xFF,
0x27, 0x01, 0x01, 0x01, 0x63, 0x3B, 0x1C, 0x00, 0x76, 0x07, 0x00, 0x1A,
0x00, 0x00, 0x77, 0xEF, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01,
0x71, 0x01, 0x63, 0xFC, 0x37, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B,
0x1B, 0x1A, 0x03, 0x81, 0x13};
Ich versuche dasselbe auch und komme nicht weiter: http://www.photovoltaikforum.com/freesol-f113/sml-pruefsummenberechnung-ich-verzweifle-an-crc-t78798.html#p716050 Bin für jeden Hinweis dankbar. Thomas
Eventuell schiebst du die Bits in der verkehrten Richtung rein??
Ich hab das jetzt nurmal ganz grob überflogen. Funktionieren beide Prüfsummen nicht? Welche Werte benutzt Du für die beiden CRC16?
Aus F2-2_PJM_5_Beschreibung_SML_Datenprotokoll_V1.2_26.04.2011.pdf,
Abschnitt 9 das Beispiel herausgezogen und:
pycrc.py --model=ccitt
--check-hexstring=760749544130303162006200726307017701093131303231323334
01726201654b8c03857577078181c78203ff01010101044954410177070100000000ff01
01010105110212340177070100010800ff0101621e520055009d51c00177070100020800
ff0101621e520055002e630101770701000f0700ff0101621b5200550000000201770701
00190700ff0101622152fd55000004b101010163
0x6d61
Bingo!
pycrc kann Dir auch (korrekten) C-Code generieren. *
F2-2_PJM_5_Beschreibung_SML_Datenprotokoll_V1.2_26.04.2011.p (2,6 MB, 13
Downloads)
* F2-2_PJM_5_Beschreibung_SML_Datenprotokoll_V1.2_26.04.2011.p (2,6
MB, 13 Downloads)
Hi ich habe mal versucht für das Smartmeter den CRC mit der cpan-Libary
Digest::CRC zu berechnen. Es ist mir leider nicht geglückt.
Ist CRC16 oder CRC-CCITT etwas anderes als das Smartmeter CCITT-CRC16?
Mein Versuch:
#!/usr/bin/perl
use strict;
use Digest::CRC qw(crc64 crc32 crc16 crcccitt crc crc8 crcopenpgparmor);
my
$x="7607000D000BB2E1620062007263010176010107000D04B5E64B0B06454D48010271
5466F50101633FB6007607000D000BB2E2620062007263070177010B06454D4801027154
66F5017262016504B5825E7777078181C78203FF0101010104454D480177070100000009
FF010101010B06454D480102715466F50177070100010800FF63020001621E52FF560005
083F1D0177070100010801FF0101621E52FF560001DB16240177070100010802FF010162
1E52FF5600032D28F901770701000F0700FF0101621B52FF55000000000177078181C782
05FF0101010183022D71B54A09ACC232221CE8C146CAAA4077F0DB516FC0E1F96D6931BA
2509566133FB1D8EF519BF19B149790E864EEA46010101631097007607000D000BB2E362
00620072630201710163";
my $crc = crc16($x);
print "CRC: $crc\n";
printf("%x",$crc);
print "\n";
my $crc = crcccitt($x);
print "CRC: $crc\n";
printf("%x",$crc);
print "\n";
Ergebnis:
CRC: 4212
1074
CRC: 9283
2443
Rauskommen sollte aber wohl 3CDD
Hier noch der Vollständigkeit halber der ganze Datensatz
1B1B1B1B010101017607000D000BB2E1620062007263010176010107000D04B5E64B0B06
454D480102715466F50101633FB6007607000D000BB2E2620062007263070177010B0645
4D480102715466F5017262016504B5825E7777078181C78203FF0101010104454D480177
070100000009FF010101010B06454D480102715466F50177070100010800FF6302000162
1E52FF560005083F1D0177070100010801FF0101621E52FF560001DB1624017707010001
0802FF0101621E52FF5600032D28F901770701000F0700FF0101621B52FF550000000001
77078181C78205FF0101010183022D71B54A09ACC232221CE8C146CAAA4077F0DB516FC0
E1F96D6931BA2509566133FB1D8EF519BF19B149790E864EEA4601010163109700760700
0D000BB2E362006200726302017101633CDD00001B1B1B1B1A011174
Jemand eine Idee?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.