![]() |
BluetoothLE Verhalten bei Wiederverbinden
Hallo Leute,
ich habe eine Anwendung auf Basis des HearTrateMonitor Beispiels gebaut (mit einem anderen Messystem): 1. DiscoverDevices 2. DiscoverServices 3. GetCharacteristics 4. Start Monitoring Funktioniert soweit ganz gut. Allerdings bekomme ich es nicht hin wenn der Client abgeschaltet wird (PowerOff). Das Abschalten bekomme ich noch mit, weil ich regelmäßig mit RSSIRead auf IsAlive prüfe. Wenn nicht mehr da, dann setzt ich alles auf Anfang. Habe mit TBluetoothManagerLE.ClearServices; versucht den Adapter rückzusetzen. Aber egal was, wenn ich wieder ober 1,2,3,4 mache bekomme ich nicht die Funktionierende Verbinding hin. Wenn ich die App neu Starte dann gehts. Wie muss man den BT-Stack stoppen, abbauen, etc. damit man sich erneut verbinden kann ? Hat irgendjemand ein ähnliches Problem ? Rollo |
AW: BluetoothLE Verhalten bei Wiederverbinden
DoScan; ?
BluetoothLE1.DiscoverDevices(2500, [HRService]) // It only exposes devices with the Heart Rate service to the BluetoothLE client. ![]() ![]() |
AW: BluetoothLE Verhalten bei Wiederverbinden
Hallo hator,
danke für die Hilfe. Ich denke ich habe das Problem gefunden: Es war eine Abfrage auf EnableBluetooth
Code:
Das "EnableBluetooth" wird anscheinend nur in Android wirklich ausgewertet,
{$IFDEF ANDROID}
if TBluetoothLEManager.Current.EnableBluetooth then {$ENDIF nANDROID} begin BluetoothLE1.CancelDiscovery; BluetoothLE1.ClearServices; {$IFDEF ANDROID} end else begin unter allen anderen Platformen geben abgeleiteten Funktionen jeweils nur hardkodiert
Code:
zurück.
Result := False;
Dadurch wurde
Code:
nie aufgerufen, und diese beiden Funtkionen setzen den Stack wohl zurück, so wie gewünscht.BluetoothLE1.CancelDiscovery; BluetoothLE1.ClearServices; Deshalb habe ich die Abrage nur für AMDROID gemacht. Ich kann jetzt den BT verbinden, ausschalten, neu verbinden so oft ich will. Rollo |
AW: BluetoothLE Verhalten bei Wiederverbinden
Ich abe anscheinend immer noch Probleme mit BLE.
Nachdem ein Device gefunden wird MUSS ich durch alle Services und Characteristics durch, ansonsten scheint die Methode direkt auf Characteristics zuzugreifen nicht zu funktionieren. Hier muss nichts gemacht werden, andscheinen sucht fmx nur intern die Daten ab und generiert interne Listen daraus. Ich vermute das hier ein Bug beim Zugriff auf solche Listen ist, denn es funktioniert meistens, aber ich bekommen auch regelmässig (nur beim Wiederverbinden), einen Zugriffsfehler den ich nicht näher lokalisieren kann. Hat jemand ähnliche Probleme mit BT ? Ach ja, unten in den Loops kann ich so auch die Daten ausgeben lassen (jetzt auskommentiert), aber wenn ich die Kommentare wegnehme kracht es auch hier schon. So als ob der Zugriff auf die internen Listen im TBluetoothLE ein Problem hätten. Wie gesagt, nach Neustart ist alles super, nur wenn Device abgeschaltet und neu Verbunden wird scheint sich im TBlueToothLE noch etwas zu befinden was nicht ganz korrekt ist. Ich werde demnächst versuchen TBLuetothLE nicht als Komponente, sondern als Runtime Feld anzulegen, damit ich das komplett entfernen kann, aber dazu muss ich einiges umbauen. Rollo
Code:
// // Loop through all SERVICES
for I := 0 to FDeviceCurrent.Services.Count - 1 do begin // svc := FDeviceCurrent.Services[I]; // Add( 'Service', svc.UUIDName); // Add( ' ', svc.UUID.ToString); // if svc.ServiceType = TBluetoothServiceType.Primary then // Add('SvcType', 'Primary') // else // Add('SvcType', 'Secondary'); // MUST LOOP through all, so that the desired information is gathered // otherwise the characteristics cannot be set reliably // // // Loop through all CHARACTERISTICS for J := 0 to FDeviceCurrent.Services[I].Characteristics.Count - 1 do begin // svcC := FDeviceCurrent.Services[I].Characteristics[J]; // Add( '-Charact', svcC.UUIDName); // Add( ' ', svcC.UUID.ToString); FTimerTimeout := 0; // // Loop through all CHARACTERISTICS DESCRIPTORS for K := 0 to FDeviceCurrent.Services[I].Characteristics[J].Descriptors.Count - 1 do begin // svcD := svcC.Descriptors[K]; // Add('--Descr ', svcD.UUIDName); // Add(' ', svcD.UUID.ToString); FTimerTimeout := 0; end; end; end; |
AW: BluetoothLE Verhalten bei Wiederverbinden
Ich habe noch eine Möglichkeit/Notwendigkeit gefunden:
BluetoothLE.Enable := False; // Beendet den ganzen internen Thread der Komponente BluetoothLE.Enable := True; // Restartet wieder Wenn man das nach verlorener Verbindung aufruft wird es etwas besser. Es hat zumindest die ständigen Zugriffs-Exceptions beim Wiederverbinden erheblich reduziert, aber die kommen leider immer noch sporadisch vor. Beim ersten Verbinden funktionierts aber eigentlich immer, sonst passiert eigentlich nicht viel in der App, deswegen denke ich das es mit dem internen Lesen der Characteristics zu tun hat, oder das beim internen Lesen die BT-Verbindung abstürzt. Rollo |
AW: BluetoothLE Verhalten bei Wiederverbinden
offene Fragen über Fragen?
welche Android Version (4.3.x / 4.4.x / 5.x.x) ? welches Delphi (XE7/XE7.1/XE8/XE8.1) ? "wo"/"wann" werden die einzelnen BLE Funktionen aufgerufen? Ganz allgemein: - Im Wenn möglich nur "OnEnd(Discovery)Events" benutzen, und im OnDiscover(Devices) besser keine weiteren BLE Funktionen aufrufen, "kurzen" Timer starten und im TimerEvent erst weitere BLE Funktionen verwenden. Emba. kapselt die Java/IOS Api noch sehr "variabel" in eigene Threads und/oder nutzt Zwischenschichten. Wenn es nicht auf 0.1sec ankommt, lieber eine sequenzielle State-Maschine bauen und jeden StateWechsel zusätzlich über ein einzelnes 100ms TimerEvent entkoppeln. - besser vor einem neuem Suchen ein CancelDiscovery zuviel wie eines zu wenig - bis Android 4.4. ist alles sehr Hersteller und geräteabhängig... z.B. Sony Android4.4.x ist allgemein sehr stabil, Huawei Android 4.4.x sehr empfindlich - ab Android 5.0.1 ist BLE besser, aber leider von Delphi (noch) nicht direkt per Onboard-FMX unterstützt... - wenn für gefundene Geräte(also nach DiscoverDevices) der (Re)Connect, also "DiscoverServices" nicht klappt, dann kann man da etwas mit dem Timing spielen... einmal möglichst schnell danach und einmal mit ~300ms Pause dazwischen ...stell doch einfach mal (d)ein TestProjekt hier rein |
AW: BluetoothLE Verhalten bei Wiederverbinden
Hallo Mensch72,
du hast ja Recht: Im Moment iOS 8.1 bis 8.3, RadStudio XE8 Pro (mit und ohne Upd1) Getestet auf iPhone 4, 5S, 6. Unter Android bisher nur unter Sansung Galaxy 5, mit akt. Version, aber da läuft es auch. Scheint ein Problem unter iOS zu haben. Ich habe als Basis das Emba HeartRateMonitor Beispiel benutzt, welches auch erstmal gut lief. Aber ich hatte nur unter Android und auf dem MacBook getestet. Ich bin gerade dabei die RadXE8 Subscription zu besorgen, in der Hoffnung das ein grosses Upd1 auch hier Verbesserungen bringt. Ich hatte nur die Recharge-Version, bin aber davon ausgegangen das es 1:1 das Gleiche ist. Wen ich damit nicht weiter komme werde ich nochmal ein abgespecktes Demo machen: - aber ich benutze die OnEndDiscoveryDevices, OnEnd--Services, etc. - die einzelnen States habe ich entweder durch Tastendruck, oder durch Timer getrennt, mit mind. 0.5 Sec. dely - mehrere CancelServices hatte ich noch nicht probiert, ist eine gute Idee, werde ich aber mal machen. Hast du einen Event falls sich das BT-Gerät abschaltet (AutoShutOff) ? Das passiert namlich, und ich bekomme das so nicht mit. Ich habe versucht über regelmäßige ReadRSSI herauszufinden wann das Gerät weg ist, aber das ist auch nur suboptimal. Am Besten wäre es ein OnConnectionLost Event, den es aber leider nicht gibt. Rollo Rollo |
AW: BluetoothLE Verhalten bei Wiederverbinden
"Am Besten wäre es ein OnConnectionLost Event"...
Viele Charakteristics können ja abonniert werden... also einfach nach DiscoverServices ein EnableNotifycation aufrufen. - da kommt dann sofort per Event der aktuelle Wert, und dann zyklisch eine Aktualisierung - also einfach die Empfangszeit merken und beim nächsten Event die Zeitdifferenz mal "2,2" als TimeOut nehmen und bei jedem Empfang so weiterführen - so kann einmal eine Aktualisierung verloren gehen ohne das ein gleich der TimeOut kommt - wenn TimeOut erreicht, hast du dein "OnConnectionLost Event", weil sich das BLE Device dann 2x nicht regelmäßig gemeldet hat - RSSI Polling ist aus meiner Sicht ungünstig, weil dies je nach BLE Gerät sogar ein Connect/Reconnect auslöst, ohne das alle Delphilisten dann intern aktuell sind - PushNotify Events mit bekannter Wiederholrate und TimeOut-Faktor 1,1(kein Ausfall erlaubt) oder 2,2(ein Ausfall erlaubt) sind die eleganteste und BLE seitig stromsparendste Lösung |
AW: BluetoothLE Verhalten bei Wiederverbinden
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo mensch72,
danke für die Hinweise. Events für EnableNotification würde ich gerne setzten, finde aber keine. Nur zur Klarstellung: Ich lese Rssi nicht vom IOS-Device, sonder vom lokalen Host-Stack. Das sollte eigentlich eine Variable sein die sofort, ohne Transfter over-the-air, auslesbar sein sollte weil das nur vom eingebauten BT-Chip kommt. Deshalb havbe ich Polling für Rssi eingebaut über 3sec. Timer:
Code:
Es hat für mich auch noch einen anderen Grund:
if not DeviceCurrent.ReadRemoteRSSI then // Obtain RSSI
begin ... procedure TS4BleConnectDm.BluetoothLE1ReadRSSI(const Sender: TObject; ARssiValue: Integer; AGattStatus: TBluetoothGattStatus); begin ... - Ich habe eine Service Notification beim Gerät registriert, und dieses sendet nur ab und zu wenn der Nutzer eine Taste drückt, durch das Polling glaube ich das Timing besser Steuerun zu können. D.h. wenn User eine datenpaket sendet spar ich mir einen Rssi Zyklus (denn beides ist mein KeepAlive Signal). Wenn du weisst wie man den Rssi-Wert als Event oder Notification ausliest dann hilf mir bitte auf die Sprünge. Ich habe schon einiges durchgesehen, finde aber nichts. Jetzt will ich nochmal schauen wie die Beacons das machen, denn das ist ja eigentlich das Gleiche Problem. Es gibt die neue RssiToDistance Funktion bei den Beacons, aber wie die an den RssiWert kommen muss ich noch checken. Ich habe hier etwas von David I gefunden, siehe Bild im Anhang ![]() Heisst das das mit LastDiscoveredDevice geprüft werden kann ob ein Gerät noch am Leben ist ? Rollo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz