Forum: Mikrocontroller und Digitale Elektronik Smart Meter Lang. CRC berechnung


von Daniel H. (doomstar)



Lesenswert?

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

von Daniel H. (doomstar)


Lesenswert?

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};

von FreeSol (Gast)


Lesenswert?

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

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Eventuell schiebst du die Bits in der verkehrten Richtung rein??

von Martin S. (sirnails)


Lesenswert?

Ich hab das jetzt nurmal ganz grob überflogen. Funktionieren beide 
Prüfsummen nicht? Welche Werte benutzt Du für die beiden CRC16?

von Tiramisu (Gast)


Lesenswert?

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)

von simon (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.