Moin Leute, ich versuche gerade für dieses Gerät eine schönere App mit App Inventor zu kreieren, die sich via BLE mit dem Gerät verbindet. http://www.junteks.com/product/278218225 Ich habe bereits ein Bluetooth-Protokoll aus meinem Smartphone gezogen, das protokolliert, wie ich die originale App öffne und mich mit dem Gerät verbinde. Ich kann das Protokoll mit Wireshark öffnen, aber so richtig verstehe ich nicht, was da passiert. (btsnoop_hci_202201251007.cfa) Außerdem habe ich die originale App dekompiliert. Da gibt es auch eine Datei, die wichtigen Inhalte preisgibt, aber auch hier fällt es mir schwer dem etwas Sinnvolles zu entnehmen. (MainActivity.java) Außerdem habe ich mit App Inventor einen der Bluetooth Services abonniert und empfange damit tatsächlich eine Datenreihe aus der ich Laufzeit, Spannung, Strom und Leistung auslesen kann. Allerdings ist das so umständlich, dass ich davon ausgehe, dass es noch einen anderen Weg geben muss. Z.B. wird im HEX -Format die Laufzeit in Sekunden gefolgt vom Wert D5 angezeigt. (D5 (HEX-Wert) taucht z.B. als Dezimalzahl in der Java-Datei wieder auf.) Immer mal wieder ändert sich der Wert dann aber sprunghaft und es wird ein völlig falscher Wert für die Laufzeit gefolgt vom Wert D5 angezeigt. Der Wert für die Spannung hat jeweils unterschiedlich viele Stellen, sodass man nie so recht weiß, welche Stellen man jetzt verwenden muss etc. Kann jemand von Euch jemand etwas mit dem Bluetooth-Protokoll oder mit der dekompilierten App anfangen und mir ggf. helfen, mit der App weiterzukommen?
Hast Du mal beim Hersteller nach Dokumentation zum Protokoll gefragt? Ansonsten kannst Du Dir mit einem generischen GATT-Client, die Services und die dazugehörigen Characteristics angucken. Das sollte deutlich einfacher sein, als sich das mit einem Sniffer die Discovery-Prozedur anzugucken. Wenn dabei allerdings etwas komplexere Mechanismen, wie Control-Points verwendet werden, kommt man damit recht schnell an die Grenzen.
Der Hersteller antwortet leider nicht. Ich habe mir die Bluetooth Services und GATTs mit dieser App angeschaut. https://play.google.com/store/apps/details?id=com.siliconlabs.bledemo&hl=de&gl=US Ich nehme an, das ist so eine Art generischer GATT-Client, oder?
Tim B. schrieb: > Ich nehme an, das ist so eine Art generischer GATT-Client, oder? Richtig :-) Damit kannst Du wahrscheinlich schon heraus bekommen, wie das Protokoll funktioniert. Die Characteristic ab Handle 0x0021 scheint ja irgendwie die interessante zu sein. Vielleicht verwenden die diese Characteristic nur wie eine Art UART. 0xbb könnte dann so etwas wie eine Frame-Anfang zu sein und 0xee das Ende (Packet 930 bis 934 würde dann zusammen einen Frame ergeben). Die Notifications, die im Sekundentakt gesendet werden, haben dann wahrscheinlich den Frame-Type Opcode whatever von 0x50 und die Nutzlast wäre dann z.B.:
1 | 0x08 0xd5 0x88 |
2 | 0x09 0xd5 0x89 |
3 | 0x10 0xd5 0x96 |
4 | 0x11 0xd5 0x97 |
die würde ich mal Beobachten, wenn Du die Messwerte änderst
Puh, da komm ich nicht mehr mit Frame-Type Opcode whatever von 0x50. Da verstehe ich nur noch Bahnhof :-) Also, wenn ich die Service UUID ffe0 und die Char UUID ffe1 verwende bekomme ich im Sekundentakt eine Zeichenkette gesendet. Ich vermute mal, dass ich mit App Inventor das UART Protokoll zu sehen bekomme. Die habe ich mir genauer angeschaut und festgestellt, dass die Kette entweder im Sekundentakt die Laufzeit oder sofort eine Spannungs-, Strom- oder Leistungänderung mitteilt. Im ersten Fall lautet die Zeichenkette z.B. 187 3 85 33 213 40 238. Die 187 scheint eine Art Anfangszeichen zu sein. Die 213 gibt an, dass davor die Zeit steht. Die 40 weiß ich nicht, die ändert sich aber auch im Sekundentakt. Evt. eine Prüfsumme. Die 238 ist das Schlusslicht. Wenn ich die Zeichenkette zwischen 187 und 213 zusammen setze und ins HEX-Format umwandle, dann habe ich die Laufzeit. Leider ändert sich dieser Wert gelegentlich plötzlich und die Laufzeit wird falsch angezeigt. Warum konnte ich noch nicht herausfinden. Bei einer Änderung von Spannung oder Strom werden die jeweiligen Werte gefolgt von 192, 193 angezeigt. Auch hier muss ich ins HEX-Format konvertieren. Nun frage ich mich, warum das dermaßen kompliziert gemacht ist. Ich weiß z.B. nie, wie viele Stellen die Spannung denn jetzt hat. Klar kann ich was programmieren, das mir die Stellen zwischen der 187 und der 192 ausrechnet, aber ich frage mich, ob es nicht auch einfacher geht. Außerdem kann ich die Werte für Spannung und Strom nicht manuel abrufen und bekomme sie erst, wenn es eine Änderung gibt. In der originalen App wird die Spannung aber gleich zu Beginn angezeigt. Wenn ich so etwas programmieren würde, dann würde ich doch eine Zeichenkette senden, die alle Infos in immer derselben Reihenfolge enthält, damit ich der Reihe die einfach entnehmen kann. Darum kommt mir immer wieder der Gedanke, dass ich hier irgendwas falsch mache...
MainActivity.java Reengineeren. Insbesondere private void parseCommand(int n, int n2) {
Und ich würde untersuchen, ob die App das BLE-Gerät gezielt abfragt. public void sendData(byte[] arrby) { BluetoothGatt bluetoothGatt; if (this.able && (bluetoothGatt = this.mBluetoothGatt) != null) { BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGatt.getService(UUID.fromString((String)"0000fff0-0000-1000-800 0-00805f9b34fb")).getCharacteristic(UUID.fromString((String)"0000fff2-00 00-1000-8000-00805f9b34fb")); bluetoothGattCharacteristic.setValue(arrby); this.mBluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic); } }
Und jetzt die wichtigen Fragen. ;-) Reden wir über einen KG-140F, wo kann man den bestellen und was kostet das Gerät?
Tim B. schrieb: > Die habe > ich mir genauer angeschaut und festgestellt, dass die Kette entweder im > Sekundentakt die Laufzeit oder sofort eine Spannungs-, Strom- oder > Leistungänderung mitteilt. > Im ersten Fall lautet die Zeichenkette z.B. 187 3 85 33 213 40 238. > 187 scheint eine Art Anfangszeichen zu sein... Ja, oder eben BB in hexadezimal. In der Software-Entwicklung ist es recht üblich, die C-Notation für hexadezimale Zahlen (literals) zu verwenden: 0xBB > Die 40 weiß ich nicht, die ändert sich aber auch im > Sekundentakt. Evt. eine Prüfsumme. Kann sein, wäre bei einer UART nicht unüblich. Den Typen der Daten kodiert man "üblicherweise" mit einem bestimmten Wert am Anfang, damit mit man relativ früh erkennt, wie die Daten zu Interpretieren wären. Ich würde dann eher darauf tippen, dass die 3 (0x03) anzeigen, dass es sich um die Laufzeit handelt. > Leider ändert sich > dieser Wert gelegentlich plötzlich und die Laufzeit wird falsch > angezeigt. Versuch mal nur Werte miteinander zu vergleichen, bei denen die Zahl hinter dem 187 (0xbb) identisch sind. > Auch hier muss ich ins HEX-Format > konvertieren. > Nun frage ich mich, warum das dermaßen kompliziert gemacht ist. Ich weiß > z.B. nie, wie viele Stellen die Spannung denn jetzt hat. Du must dort nichts in's HEX-Format konvertieren. Das ist nur eine Art, Zahlen darzustellen. Was Du machen must (und das machst Du dann implizit, wenn Du Zahlen (Bytes) in's HEX-Format konvertierst), ist die einzelnen Bytes wieder zusammen zu einer größeren Zahl zusammensetzen (deserialisieren). > Klar kann ich > was programmieren, das mir die Stellen zwischen der 187 und der 192 > ausrechnet, aber ich frage mich, ob es nicht auch einfacher geht. Das ist so ziemlich die einfachste, binäre Darstellung von Zahlen, die möglich ist (von dem Frame (0xbb, 0xee) und der CRC mal angesehen). > Außerdem kann ich die Werte für Spannung und Strom nicht manuel abrufen > und bekomme sie erst, wenn es eine Änderung gibt. In der originalen App > wird die Spannung aber gleich zu Beginn angezeigt. Im gezeigten Mitschnitt, sendet das Gerät direkt mit dem Subscribe auf die Characteristic die ersten Daten (frame 921). Vielleicht hast Du da noch ein Problem in Deiner App, dass die z.B. zuerst auf die Characteristic subscribed und dann den dazu nötigen Callback installiert. > Wenn ich so etwas > programmieren würde, dann würde ich doch eine Zeichenkette senden, die > alle Infos in immer derselben Reihenfolge enthält, damit ich der Reihe > die einfach entnehmen kann. Darum kommt mir immer wieder der Gedanke, > dass ich hier irgendwas falsch mache... Binäre Protokolle sind halt deutlich effektiver. Für Zahlen von 0-1000 bräuchtest Du 4 Byte, ein Binärprotokoll aber nur 2 Byte. HTH Torsten
noreply@noreply.com schrieb: > Und jetzt die wichtigen Fragen. ;-) > Reden wir über einen KG-140F, wo kann man den bestellen und was kostet > das Gerät? Ich habe ein KG-110F. Gibts z.B. bei Aliexpress für ca. 30€ https://de.aliexpress.com/item/1005003414812628.html?gatewayAdapt=glo2deu&spm=a2g0o.9042311.0.0.1ae04c4diXvJgI
Vielen Dank für die Vielen Antworten. >> 187 scheint eine Art Anfangszeichen zu sein... > > Ja, oder eben BB in hexadezimal. In der Software-Entwicklung ist es > recht üblich, die C-Notation für hexadezimale Zahlen (literals) zu > verwenden: 0xBB Okay, ich hatte mich nur gewundert, weil in App Inventor erst mal Dezimalzahlen angezeigt werden und auch in dem dekompilierten Java-Code sind Dezimalzahlen angegeben... aber der Code ist ja auch dekompiliert:-) und App Inventor ist eben App Inventor :-) >> Die 40 weiß ich nicht, die ändert sich aber auch im >> Sekundentakt. Evt. eine Prüfsumme. > > Kann sein, wäre bei einer UART nicht unüblich. Den Typen der Daten > kodiert man "üblicherweise" mit einem bestimmten Wert am Anfang, damit > mit man relativ früh erkennt, wie die Daten zu Interpretieren wären. Ich > würde dann eher darauf tippen, dass die 3 (0x03) anzeigen, dass es sich > um die Laufzeit handelt. Seltsamerweise ist es hier andersrum und die Typen der Daten werden nach dem Wert angegeben (liest man in China nicht von rechts nach links?). Tatsächlich gehört die 3 mit zur Laufzeit. Alles was zwischen 187 und 213 steht ist die Laufzeit in Sekunden, da bin ich mir ziemlich sicher. Nur die 40 weiß ich noch nicht. Da die aber eben auch im Sekundentakt hochzählt würde es ja Sinn machen, wenn das eine Prüfsumme wäre. Da muss ich wohl mal ein bisschen hin und her rechnen um rauszufinden, wie die berechnet wird. Vielleicht die Quersumme oder so... >> Leider ändert sich >> dieser Wert gelegentlich plötzlich und die Laufzeit wird falsch >> angezeigt. > > Versuch mal nur Werte miteinander zu vergleichen, bei denen die Zahl > hinter dem 187 (0xbb) identisch sind. Wie meinst Du das? > >> Auch hier muss ich ins HEX-Format >> konvertieren. >> Nun frage ich mich, warum das dermaßen kompliziert gemacht ist. Ich weiß >> z.B. nie, wie viele Stellen die Spannung denn jetzt hat. > > Du must dort nichts in's HEX-Format konvertieren. Das ist nur eine Art, > Zahlen darzustellen. Was Du machen must (und das machst Du dann > implizit, wenn Du Zahlen (Bytes) in's HEX-Format konvertierst), ist die > einzelnen Bytes wieder zusammen zu einer größeren Zahl zusammensetzen > (deserialisieren). > >> Klar kann ich >> was programmieren, das mir die Stellen zwischen der 187 und der 192 >> ausrechnet, aber ich frage mich, ob es nicht auch einfacher geht. > > Das ist so ziemlich die einfachste, binäre Darstellung von Zahlen, die > möglich ist (von dem Frame (0xbb, 0xee) und der CRC mal angesehen). Schon, aber es wäre doch kein Problem gewesen, z.B. eine Null voran zu stellen, damit die Zahlenfolge immer gleich lang ist z.B. 01000 für 10 Volt. Oder immer Spannung, Strom und Leistung zusammen zu übertragen und nicht mal das eine und mal das andere. Wahrscheinlich hat der Programmierer versucht immer so wenig Daten wie möglich zu übertragen. So würde das Sinn ergeben. Aber das wieder auseinander zu pflücken ist echt aufwendig. >> Außerdem kann ich die Werte für Spannung und Strom nicht manuel abrufen >> und bekomme sie erst, wenn es eine Änderung gibt. In der originalen App >> wird die Spannung aber gleich zu Beginn angezeigt. > > Im gezeigten Mitschnitt, sendet das Gerät direkt mit dem Subscribe auf > die Characteristic die ersten Daten (frame 921). Vielleicht hast Du da > noch ein Problem in Deiner App, dass die z.B. zuerst auf die > Characteristic subscribed und dann den dazu nötigen Callback > installiert. Danke, das hilft mir sehr weiter. Dann weiß ich jetzt, wo ich nach dem Fehler suchen muss. > >> Wenn ich so etwas >> programmieren würde, dann würde ich doch eine Zeichenkette senden, die >> alle Infos in immer derselben Reihenfolge enthält, damit ich der Reihe >> die einfach entnehmen kann. Darum kommt mir immer wieder der Gedanke, >> dass ich hier irgendwas falsch mache... > > Binäre Protokolle sind halt deutlich effektiver. Für Zahlen von 0-1000 > bräuchtest Du 4 Byte, ein Binärprotokoll aber nur 2 Byte. > > HTH > Torsten
noreply@noreply.com schrieb: > Und ich würde untersuchen, ob die App das BLE-Gerät gezielt abfragt. > > > public void sendData(byte[] arrby) { > BluetoothGatt bluetoothGatt; > if (this.able && (bluetoothGatt = this.mBluetoothGatt) != null) > { > BluetoothGattCharacteristic bluetoothGattCharacteristic = > bluetoothGatt.getService(UUID.fromString((String)"0000fff0-0000-1000-800 0-00805f9b34fb")).getCharacteristic(UUID.fromString((String)"0000fff2-00 00-1000-8000-00805f9b34fb")); > bluetoothGattCharacteristic.setValue(arrby); > this.mBluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic); > } > } Ja, das könnte z.B. auch das Zurücksetzen des Stromzählers sein. Leider verstehe ich kein Wort javajanisch. Ich glaube, der wichtige Satz wäre hier bluetoothGattCharacteristic.setValue(arrby); Den Rest kann ich in etwa nachvollziehen. aber was ist mit arrby gemeint?
noreply@noreply.com schrieb: > MainActivity.java Reengineeren. > Insbesondere private void parseCommand(int n, int n2) { Ja eben dabei hatte ich mir Hilfe erhofft, weil ich eben kein Java kann. Die besagte Stelle habe ich auch schon entdeckt. Z.B. wird eben mit der 192 die Spannung abgefragt. Die taucht ja auch in der Zeichenfolge, die ich empfange, auf. Was ich verstehe ist, dass er erst mal ausschließt, dass 182, 183, 224 und 225 in der Zeichenfolge auftauchen. Die ganzen switch und default kann ich nicht verstehen und auch nicht, was direkt darunter bei der 217 steht. Was anschließend kommt kann ich mir wieder in etwa zusammen reimen, weil ich ja z.B. auch schon herausgefunden habe, dass vor der 192 (bzw. C0) die Spannung steht. Aber was dann weiter unten bei Main Activity steht kann ich auch wieder nicht nachvollziehen.
Die UUIDs sehen aus wie beim HM-17, das ist ein beliebtes UART-auf-BTLE Wandler Modul. Wenn man da gelegentlich Fehler findet könnte das am Modul liegen, denn das verliert bei schneller UART Übertragung öfter mal Daten. Die App ignoriert das Problem, denn im Code findet am Anfang von processCommand() eine simple Summenprüfung statt - bei der fehlerhafte Daten rausfliegen. Normalwerweise hat man schon gewonnen wenn man die Werte aus der Anzeige hexadezimal im Datenstrom auffindet.
Tim B. schrieb: > Ich glaube, der wichtige Satz wäre > hier bluetoothGattCharacteristic.setValue(arrby); Bitte die Bibliothek nochmal des wegen befragen. Ich gehe aber von nachfolgenden verhaltens aus. arrby ist ein array of bytes, das gesendet werden soll. mit nachfolgenden Kommando wird dann das array of bytes dann gesendet. this.mBluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic);
Tim B. schrieb: > Was ich verstehe ist, dass er erst mal ausschließt, dass 182, 183, 224 > und 225 in der Zeichenfolge auftauchen. Die Werte scheinen dominant zu sein. Das ganze if/switchkonstrukt scheint laufzeitoptimiert zu sein. Habe ich aber so noch nie gesehen. n = Kommando n2 = Wert Da wird das Endgerät nach Konfigurationsparametern abgefragt und in parseCommand Attributen der Benutzergui zugeordnet. z.B. in den tieferen Schichten. wenn n=199, dann wird n2 den Attribut OCP über eine Setterroutine zugeordnet case 199: { ((SettingFragment)((Object)this.this$0.fragmentList.get(1))).setOCP(this .val$num); return; } Das hier ist noch schwieriger zu verstehen. Bei n=192 wird ein Attribut Vol gesetzt. Könnte Voltage sein. case 192: } ((MainFragment)((Object)this.this$0.fragmentList.get(0))).setSettingVol( this.val$num); return;
Die nachfolgenden Klassen wäre wichtig zu verstehen, wenn man eigene Kommandos aufbauen möchte. Die sind noch dekompiliert. import com.juntek.celiangvat.util.BCDCode; import com.juntek.celiangvat.util.BCDUtil; import com.juntek.celiangvat.util.Command;
noreply@noreply.com schrieb: > Die nachfolgenden Klassen wäre wichtig zu verstehen, wenn man eigene > Kommandos aufbauen möchte. Die sind noch dekompiliert. > > import com.juntek.celiangvat.util.BCDCode; > import com.juntek.celiangvat.util.BCDUtil; > import com.juntek.celiangvat.util.Command; Die sind alle in einem Ordner namens Util. Ich habe auch gleich mal den ganzen Ordner mit den dekompilierten Files angehängt. BCD Code sieht mir nach Umwandlung von dezimal nach hexadezimal aus. TimeFormat ist auch klar. Insgesamt kann ich oft schon erkennen, was da so ungefähr gemacht wird...aber eben nur sehr ungefähr :-) und das hilft mir beim App schreiben nicht so recht weiter...
noreply@noreply.com schrieb: > Tim B. schrieb: >> Was ich verstehe ist, dass er erst mal ausschließt, dass 182, 183, 224 >> und 225 in der Zeichenfolge auftauchen. > > Die Werte scheinen dominant zu sein. Das ganze if/switchkonstrukt > scheint laufzeitoptimiert zu sein. Habe ich aber so noch nie gesehen. > > n = Kommando > n2 = Wert > > Da wird das Endgerät nach Konfigurationsparametern abgefragt und in > parseCommand Attributen der Benutzergui zugeordnet. > > z.B. in den tieferen Schichten. > wenn n=199, dann wird n2 den Attribut OCP über eine Setterroutine > zugeordnet > > case 199: { > ((SettingFragment)((Object)this.this$0.fragmentList.get(1))).setOCP(this .val$num); > return; > } > > Das hier ist noch schwieriger zu verstehen. Bei n=192 wird ein Attribut > Vol gesetzt. Könnte Voltage sein. > > case 192: > } > ((MainFragment)((Object)this.this$0.fragmentList.get(0))).setSettingVol( this.val$num); > return; Okay, das macht schon beides Sinn. OCP ist Overvoltageprotection. Die kann man bei dem Gerät einstellen und setSettingVol in Verbindung mit der 192 konnte ich ja sogar schon darstellen. Grundsätzlich gehe ich erst mal davon aus, dass diese Werte nach einer Änderung über die Zeichenfolge gesendet werden, die ich hier sowieso schon empfangen kann. Irgendwie muss es aber auch möglich sein, etwas an das Gerät zu senden. Z. B. um den Zähler zurückzusetzen. Da wäre es schon noch sehr wichtig herauszufinden, wie das gehen kann. Bisher verwende ich Service 0xfff0 Char 0xfff1 oder Service 0xffe1 Char ffe1. Da kommen dann im Sekundentakt Infos, die man entsprechend auswerten kann. Daten zu senden habe ich noch gar nicht ausprobiert.
Ich habe jetzt noch einmal ziemlich lange am Datenempfang rumgebastelt. Im Grunde funktioniert es jetzt ganz gut, aber es bleibt das Problem, dass ich nicht weiß, wie viele Stellen ein Wert hat. Da jedes Mal unterschiedliche Werte gesendet werden ist es auch nicht wirklich möglich die Werte zwischen zwei Bezeichnungen zu verwenden. Ein Beispiel: Ich bekomme die Zahlenfolge 187 18 20 192 54 193 4 55 216 137 238 bzw. bb 12 14 c0 36 c1 4 37 d8 89 ee Nun weiß ich, dass die Spannung 12,44V, der Strom 0,36A und die Leistung 4,37W beträgt. Nun kann es aber sein, dass sich dazwischen plötzlich ein anderer Wert mogelt. Z.B. 187 18 20 192 54 193 1 17 17 215 4 55 216 137 238 bzw. bb 12 14 c0 36 c1 1 11 d7 4 37 d8 89 ee Nun denkt meine Software natürlich, dass alles zwischen c1 und d8 die Leistung wäre und verwendet folglich 111d7437 für die Leistung. Bisher bin ich dem Problem begegnet, indem ich immer weiter alles ausgeschlossen habe, was störend sein könnte, aber da immer wieder irgendein Wert auftaucht, mit dem die Software nicht rechnet, ist das keine sichere Methode.
Tim B. schrieb: > Bisher bin ich dem Problem begegnet, indem ich immer weiter alles > ausgeschlossen habe, was störend sein könnte, aber da immer wieder > irgendein Wert auftaucht, mit dem die Software nicht rechnet, ist das > keine sichere Methode. Bilde einfach die Softwarestruktur in MainActivity.java nach: private void process() { - Liest aus einen Puffer, solange das Objekt 238 vorhanden ist. - Schreibt Bytes nach einer Liste von Integer - Unterbricht, wenn Objekt 238 gefunden wurde und gibt weiter an processCommand() - Liest danach weiter wenn weitere 238 vorhanden sind. private void processCommand(List<Integer> list) { - Schaut auf den ersten Blick nach Integritätschecks in der Liste von Integer(bytearray) aus. - macht etwas besonderes, wenn 170 in der Liste von Integer(bytearray) auftritt. - Ansonsten geht es weiter nach parsecommand(n, n2) mit zwei Werten aus der Liste von Integer(bytearray) private void parseCommand(int n, int n2) { - Analysiert die Kombinationen (n,n2) - wenn n bekannt, geht n2 ins Datenmodell - wenn n unbekannt, wird n2 implizit aus den Bytestrom entfernt.
Ist das protokoll nicht im manual beschrieben ? http://www.junteks.com/newsitem/278597309 http://68.168.132.244/KG-F_EN_manual.pdf
Chris K. schrieb: > Ist das protokoll nicht im manual beschrieben ? > http://www.junteks.com/newsitem/278597309 > http://68.168.132.244/KG-F_EN_manual.pdf Das habe ich auch gehofft, aber das Protokoll ist nur für den RS485 Bus. Ich habe sogar schon überlegt, ob ich das interne Bluetooth Modul kappe und stattdessen ein HM-10 Modul an den seriellen Port anschließe. Das Protokoll wäre auf jeden Fall sehr viel einfacher...
Wenn die Daten wirklich verschlüsselt wären, wie es der Titel des Threads suggeriert, hätte man keine Chance, ohne den Schlüssel oder größeren Aufwand irgendwelche sinnvollen Dinge in den Daten zu erkennen. Bisher sieht das alles eher nach einer Kodierung nach einem einfachen Protokoll aus.
Ich glaube, jetzt läuft es: Ich suche in der Zeichenkette nach der Angabe für einen bestimmten Wert z.B. C0 für Spannung und verwende dann alle Zeichen davor bis zum nächsten nicht nummerischen Wert. Ich habe also z.B. die Zeichenkette 187 18 17 192 85 193 6 102 216 22 238 BB 12 11 C0 55 C1 6 66 D8 16 EE Dann suche C0 und starte dann eine Routine, die die Stellen davor übernimmt. Wenn er einen nicht nummerischen Wert (hier: BB) findet, dann wird die Routine unterbrochen. Ergebnis: 1211 (mV) Dann suche ich nach C1 für den Strom und mache dasselbe etc. Ob das so im Sinne des Programmierers war, weiß ich natürlich nicht... Jetzt bleiben noch die anderen Problemchen z.B: - Abrufen der Spannung nach dem Start. Hier ist die App offensichtlich nicht schnell genug um die ersten Werte die ankommen auswerten zu können. - Die Prüfsumme. Die steht vor dem EE, aber ich konnte noch nicht herausfinden, wie sie berechnet wird. Gibt es hier neben der Quersumme noch andere übliche Methoden?
Tim B. schrieb: > Dann suche C0 und starte dann eine Routine, die die Stellen davor > übernimmt. Wenn er einen nicht nummerischen Wert (hier: BB) findet, dann > wird die Routine unterbrochen. Ergebnis: 1211 (mV) Spannend, dass würde bedeuten, dass die Daten als BCD kodiert sind. Jeweils 4 bit ergeben dann eine dezimal-Ziffer. (hat mir mein Großvater mal von erzählt) > - Die Prüfsumme. Die steht vor dem EE, aber ich konnte noch nicht > herausfinden, wie sie berechnet wird. Gibt es hier neben der Quersumme > noch andere übliche Methoden? Ich vermute mal, dass die Kollegen da ein bestehendes, serielles Protokoll auf BLE umgebogen haben. BLE hat eine 24 bit CRC in der Übertragung. Wenn Daten bei Dir ankommen, dann sind die in der Regel korrekt übertragen worden. Eine zusätzlich CRC in den Nutzdaten ist eigentlich überflüssig. Ich würde die einfach ignorieren.
Torsten R. schrieb: > BLE hat eine 24 bit CRC in der > Übertragung. Die nützt nix, wenn auf der UART Seite schon Daten verloren gehen. Und das passiert ganz schnell mal, z.B. wenn das Modul wegen einer Funkstörung kurz nix los wird. Diese fertig entwickelten Protokolle behät man dann bei, wenn man von µC + BTLE Modul auf eine Single-Chip Lösung wechselt.
Inzwischen funktioniert meine App relativ gut. Nur weiß ich noch immer nicht, wie diese vermaledeite Prüfsumme berechnet wird. Ich habe inzwischen mal Docklite installiert und damit auf die gewöhnlichen Prüfsummenverfahren geprüft - leider ohne Erfolg. Außerdem habe ich ziemlich viel hin- und hergerechnet, aber ich komme einfach nicht drauf. Hat dazu vielleicht noch jemand eine Idee?
Nochmal ein Update für die Nachwelt: Nach langem Rumgeeier habe ich mittels Bluefruit LE Sniffer (für Bluetooth LE), Python und Wireshark die Bluetooth-Verbindung ausspioniert. Ich habe einen Vormittag gebraucht, um mich einzuarbeiten. Das war also sehr viel einfacher, als ich gedacht hätte. Dadurch konnte ich sowohl herausfinden, dass ein write Befehl an eine bestimmte UUID erfolgen muss, um zu Beginn alle Daten einmal über die abonnierte UUID zu erhalten. Außerdem konnte ich den write Befehl zum Zurücksetzen des Zählers herausfinden. Ich kann im Fazit also nur empfehlen, das mit dem Sniffen zu probieren. Das ist zwar zeitaufwendig, weil man unglaublich viele Datenpakete anschauen muss, aber schlussendlich eine relativ einfache Methode, den Datenverkehr nachzubauen. Die Anleitung von Bluefruit sind dafür wirklich gut und die frei erhältliche Wireshark Software ist unbezahlbar.
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.