Hallo, hat jemand Erfahrung mit M-Bus, genauer gesagt mit der Implementierung von einem M-Bus Slave.
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
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?
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.
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
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.
was ist zu beachten, wenn man ein M-Bus Slave Protokoll implementieren soll. Was unterscheidet sich zum M-Bus Master Protokoll.
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.
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 | }
|
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?
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 | }
|
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.