Forum: PC-Programmierung Meter Bus in C


von lena (Gast)


Lesenswert?

Hallo,
hat jemand Erfahrung mit M-Bus, genauer gesagt mit der Implementierung 
von einem M-Bus Slave.

von Falko (Gast)


Lesenswert?

ist M-Bus das gleiche wie Modbus?
Da hab ich gerade mein erste Implementierung geschafft (via Serielle 
RS485 Verbindung):-).... mit dem TCP-IP Variante versuche ich gerade 
Ahnung zu bekommen...
Gruß
der Falko

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

lena schrieb:
> hat jemand Erfahrung mit M-Bus, genauer gesagt mit der Implementierung
> von einem M-Bus Slave.
Hast du ein konkretes Problem, oder willst du nur wissen, ob das schon 
mal jemand gemacht hat?

von lena (Gast)


Lesenswert?

ich will zuerst wissen, ob jemand das schon gemacht hat. Dann kann ich 
meine Frage stellen.
@Falko M-Bus ist nicht das gleiche wie Modbus.

von Leon E. (adiagi)


Lesenswert?

lena schrieb:
> ich will zuerst wissen, ob jemand das schon gemacht hat

Wieso?

Tu nicht so auf schüchternes mädchen.
Sag einfach was du willst.
Wir fressen dich nicht auf keine Angst.

gruß

Agit

von horst (Gast)


Lesenswert?

Haha, ich habs schon gemacht und schon sehr oft gesehen... Ich muss aber 
sagen das die meisten Implementationen einfach nur zum spastischem 
stoßweisen hochwürgens des Mageninhalts sind... Einfach nur grausam wenn 
man damit schaffen muss

Die physikalische Umsetzung lief über OptoLink(IR), RS232-TTL und 
natürlich dem MBus Standard selbst.

Lena, hättest Du Deine Frage hier schon offengelegt hätte ich mich gerne 
direkt daran versucht sie zu beantworten.

von lena (Gast)


Lesenswert?

was ist zu beachten, wenn man ein M-Bus Slave Protokoll implementieren 
soll. Was unterscheidet sich zum M-Bus Master Protokoll.

von horst (Gast)


Lesenswert?

Der Slave darf nur auf Pakete vom Master antworten. Selbst darf er nicht 
aktiv senden. Der Slave darf auch nur dann antworten wenn er adressiert 
wurde. Es gibt noch eine Master Call Adresse (0xFE). Auf diese muss 
jeder Slave antworten.

von lena (Gast)


Lesenswert?

wie kann ich einen unsigned long long (ArrayofByte, 8 Byte) für einen 
M-Bus Slave codieren.
Meine Decodierungsfunktion sieht so aus:
1
long long long_long_decode(u8 *data, int length){
2
  int i;
3
  long long result;
4
  result = 0;
5
6
  for(i = length; i > 0; i--){
7
    result = (result << 8) + data[i-1];
8
  }
9
  return result;
10
}

von Karl H. (kbuchegg)


Lesenswert?

lena schrieb:

>
1
long long long_long_decode(u8 *data, int length){
2
>   int i;
3
>   long long result;
4
>   result = 0;
5
> 
6
>   for(i = length; i > 0; i--){
7
>     result = (result << 8) + data[i-1];
8
>   }
9
>   return result;
10
> }


Wenn man die mal analysiert, dann stellt sich raus, dass sie so 
arbeitet.

Da hat man also zb die ominösen 8 Byte im Array

   aa bb cc dd ee ff gg hh       (jeder Buchstabe ist eine Hex-Ziffer)

Was macht die Funtkion damit?
Nun, zentrales Element ist die for Schleife. DIe würde in diesem Fall 8 
mal durchlaufen werden, wobei i von oben herunter in RIchtung 0 zählt. 
Also. i nimmt nacheinander die Zahlen 8, 7, 6, 5, 4, 3, 2, 1 an (und 
natürlich 0, aber dann bricht die Schleife ab)

Was macht der Schleifenkörper mit dem i.

    data[i-1]

Aha. Er nimmt also das i-1 te Byte aus dem Array. Warum -1? Logisch, 
weil i ja bei 8 anfängt und der letzte INdex in einem Array mit 8 
Elementen ist nun mal 7. Bei den vorgegebenen 8 Bytes wäre data[i-1] 
also das hier

   aa bb cc dd ee ff gg hh
                        **

so weit so gut. Was passiert damit?

  (result << 8) + data[i-1]

zu diesem Byte wird noch was dazugezählt. Da result im Moment noch 0 ist

   result = 0;

und man eine 0 nach links verschieben kann sooft man will, da kommt 
trotzdem 0 raus, bleibt es also bei diesem Byte. Was passiert weite?

   result = (result << 8) + data[i-1];

das wird also result zugewiesen. die 8 Bytes von result sehen also so 
aus

   00 00 00 00 00 00 00 hh

Damit ist dieser Schleifendurchlauf fertig und die Schleife beginnt von 
vorne, diesmal mit einem Wert von 7 für i.

Was passiert

  data[i-1]

da i den Wert 7 hat, ist das also das Byte mit dem Index 6 aus dem 
Array. Also das hier

   aa bb cc dd ee ff gg hh
                     **

Was pssiert in

  (result << 8) + data[i-1]

Nun, zunächst mal  result << 8.
der Inhalt von result wird also um 8 Bits nach links geschoben, was 
effektiv einer Verschiebung aller Bytes von result um 1 Byte nach links 
entspricht. result verändert sich also zu

   00 00 00 00 00 00 hh 00

und dazu wird dann noch

  (result << 8) + data[i-1]

data[i-1] dazugezählt, von dem wir schon wissen, dass es das Byte gg aus 
dem Array war. Das Endergebnis ist also

   00 00 00 00 00 00 hh gg

und das wird dann wieder an result

   result = (result << 8) + data[i-1];

zugewiesen.

Das wars für diesen Schleifendurchlauf, der nächste Durchlauf beginnt, 
diesmal hat i den Wert 6.

data[i-1] ist daher                            aa bb cc dd ee ff gg hh
                                                              **
result um 8 Bits nach links geschoben ergibt   00 00 00 00 00 hh gg 00
und da dann die ff von data[i-1] addiert       00 00 00 00 00 hh gg ff
was wiederrum in result abgelegt wird.

Nächster Durchlauf: i ist jetzt 5

data[i-1] ist daher                            aa bb cc dd ee ff gg hh
                                                           **
result um 8 Bits nach links geschoben ergibt   00 00 00 00 hh gg ff 00
und da dann die ee von data[i-1] addiert       00 00 00 00 hh gg ff ee
was wiederrum in result abgelegt wird.

Nächster Durchlauf: i ist jetzt 4


Und ich glaub den Rest kann ich mir sparen. Man sieht schon, nach 
welchem Muster sich der long long aus den Bytes das Arrays 
zusammensetzt. Im Endergebnis stehen die 8 Bytes aus dem Array so im 
long long

das war das Array                       aa bb cc dd ee ff gg hh
und so sehen die Bytes in result aus    hh gg ff ee dd cc bb aa


Damit ist klargestellt, WIE denn die Dekodierung arbeitet.
Und damit kommst du ins Spiel. Du brauchst jetzt die Umkehrung. Also: 
Was hast du zu tun, damit sich die 8 Bytes eines long long so in das 
Array einpassen, damit nach der Dekodierung wieder alles richtig 
rauskommt?

von lena (Gast)


Lesenswert?

wäre diese Codierung dann in Ordnung?
1
unsigned long long long_long_encode(u8 *data, int length, unsigned long long value){
2
  int i;
3
  for(i = 0; i < length; i++){
4
    data[i] = (value >> (i*8)) & 0xFF;
5
  }
6
  return 0;
7
}

von Peitscher (Gast)


Lesenswert?

lena schrieb:
> wäre diese Codierung dann in Ordnung?unsigned long long long_long_encode(u8 
*data, int length, unsigned long long value){
>
>   int i;
>
>   for(i = 0; i < length; i++){
>
>     data[i] = (value >> (i*8)) & 0xFF;
>
>   }
>
>   return 0;
>
> }

Ist dein Debugger kaputt?

Wenn du implemntiert hast, musst du ja offensichtlich deine 
Anforderungen kennen. Wenn du diese kennst kann es doch kein Problem 
sein, einen möglichen Test zu schreiben.

von Karl H. (kbuchegg)


Lesenswert?

lena schrieb:
> wäre diese Codierung dann in Ordnung?

Warum probierst du es nicht einfach aus? Da das eine die Umkehrung vom 
anderen ist, drängt es sich doch geradezu auf, da ein Testprogramm zu 
machen, welches das ausnutzt. Einmal Codeieren, das Ergebnis Decodieren 
und dann muss am Ende wieder dasselbe rauskommen:

int main()
{
  u8 tmp[8];
  long long val1;
  long long val2;

  for( val1 = 0; val1 < 5000000; val1++ ) {
    long_long_encode( tmp, 8, val1 );
    val2 = long_long_decode(tmp, 8 );

    if( val1 != val2 )
      printf( "Fehler" );
  }
}

setz dein Funktionen ein, ergänze sonst noch was du brauchst um das 
compilierbar zu bekommen, teste vielleicht auch noch andere 
Zahlenbereiche und wenn das Testprogramm "Fehler" meldet, dann weißt du 
dass auf jeden Fall erst mal ein Fehler enthalten ist. Vergiss auch 
nicht darauf, dass ein long long auch negativ sein kann!

Eine gute Frage ist zb die Frage: Wenn ich tatsächliche alle Zahlen, die 
mit einem long long möglich sind, da druchschleuse, schafft mein PC das, 
wenn er die Nacht durcharbeiten kann?

Wenn das aus Rechenzeitgründen nicht geht, was wären denn gute 
Zahlenbereiche, die man durchtesten kann, so dass man davon ausgehen 
kann dass wenn die funktionieren, das dann auch die nicht getesteten 
Zahlenbereich funktionieren werden?

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.