Forum: PC-Programmierung Android BLE Schreiben von Characteristic schlägt fehl


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von kk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit meinem nrf51822(Adafruit UART BLE Friend 
Board). Ich habe über meinem Mikrocontroller(XMC4500) das Modul 
konfiguriert, und hab meine Costum Services und Characteristics 
hinzugefügt. Diese kann ich auch mit meiner NRF Connect App sehen. Ich 
kann mit einem Android 4.4.4 Device, die Characteristics zugreifen und 
darauf schreiben(mit der NRF APP). Versuche ich nun diese 
Characteristics mit Android 9.0 zu beschreiben, dann scheitert die App, 
und es kommt laut log zu einem Gatt Error 133 (mit auch ohne Bonding).

Der Log:

V  19:19:30.820  Writing request to characteristic 
00000002-0000-1000-8000-00805f9b34fb
D  19:19:30.820 
gatt.writeCharacteristic(00000002-0000-1000-8000-00805f9b34fb, 
value=0x23702E33)
E  19:20:00.825  Error 133 (0x85): GATT ERROR

Daher habe ich meine eigene App geschrieben, für Android 9.0. Jedoch 
tritt bei mir der selbe Fehler auf, wie in der NRF Connect App. Ich 
sende die Daten folgender Maßen:
void sendMessage(byte[] message,  String uuid_se, String uuid_ch) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.e(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mCustomService_w = mBluetoothGatt.getService(UUID.fromString(uuid_se));
        if(mCustomService_w == null){
            Log.e(TAG, "Custom BLE Service not found");
            return;
        }
        mWriteCharacteristic = mCustomService_w.getCharacteristic(UUID.fromString(uuid_ch));
        mWriteCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

        synchronized (this) {
            if (isSending) {
                messageQueue.add(message);
                return;
            }
            isSending = true;
        }
        mWriteCharacteristic.setValue(message);
        final int charaProp = mWriteCharacteristic.getProperties();
        if((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
            boolean status = mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
            if (status == false) {
                Log.e(TAG, "Failed to write characteristic");
            } else {
                byte[] bytes = mWriteCharacteristic.getValue();
                StringBuilder sb = new StringBuilder();
                for (byte b : bytes) {
                    sb.append(String.format("%02X ", b));
                }
                Log.w(TAG, "Write message: hal: " + mWriteCharacteristic.getStringValue(0) + " Mess_len: " + mWriteCharacteristic.getValue().length + " BYTES " + sb.toString());
                Log.e(TAG, "Message sent");
            }
        }
    }

    protected void sendDataWithCRC(byte[] data, String uuid_se, String uuid_ch) {

        // Calculate checksum
        byte checksum = 0;
        for (byte aData : data) {
            checksum += aData;
        }
        checksum = (byte) (~checksum);       // Invert

        // Add crc to data
        byte dataCrc[] = new byte[data.length + 1];
        System.arraycopy(data, 0, dataCrc, 0, data.length);
        dataCrc[data.length] = checksum;

        // Send it
        Log.d(TAG, "Send to UART: ");
        sendMessage(dataCrc, uuid_se, uuid_ch);
    }
//CALLBACK wird nach der Übertragung aufgerufen, jedoch schreibt dieser //einen Status 133(GATT ERROR) hinaus. 


Ich versuche es schon seit 3 Tagen, aber leider scheitere ich daran. 
Kennt jemand das Problem?

Noch die die gesendeten AT Commands:
error_identifier(atcommand_send("AT+GATTADDSERVICE=UUID128=00-11-00-11-44-55-66-77-88-99-AA-BB-CC-DD-EE-FF", &se_brightness_id));
  error_identifier(atcommand_send("AT+GATTADDCHAR=UUID=0x0002,PROPERTIES=0x08,MIN_LEN=1,MAX_LEN=15,VALUE=#p.100", &ch_brightness_write_id))

LG
Vielen Dank im Voraus!

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Die App nNRF Connect funktioniert hier auf meinen Android 9.0 Geräten.

Braucht zwingend die "Standort" Berechtigung - das brauchen alle BT LE 
Apps, die nach BT Geräten scannen.

> BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT

Probiere mal: BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE

Bei "default" muss AFAIK das BT Gerät korrekt antworten. Kann man in der 
nRF Connect app über "Write Value->Advanced->(x)Command" einstellen.

Wie sieht die Characteristic Definition aus? Sagt die App "WRITE" oder 
"WRITE NO RESPONSE"?

von Joachim (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ist zwar mit hoher Wahrscheinlichkeit nicht die Ursache des hier 
vorliegenden Problems, aber die UUIDs Deiner Characteristics und 
Services sollten nicht wie hier "00000002-0000-1000-8000-00805f9b34fb" 
sein.
Denn BLE UUIDs, die auf das Muster 
"xxxxxxxx-0000-1000-8000-00805F9B34FB" passen, sind für offizielle, 
standardisierte Services und Characteristics reserviert.

Für nicht standardisierte Services und Characteristics, die Du Dir 
selbst ausgedacht hast, solltest Du als UUID daher keine 16- oder 
32-Bit-Integer-Zahl nehmen, sondern eine vollständige, 128 Bit lange, 
(pseudo)zufällig generierte UUID, z.B. von hier:
https://www.uuidgenerator.net/

von kk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Braucht zwingend die "Standort" Berechtigung - das brauchen alle BT LE
> Apps, die nach BT Geräten scannen.

Vielen Dank für die Antwort. Die Rechte für den Standort und die 
Permission im Code habe ich abgefragt. Das Scannen und listen der 
Services der Geräte funktioniert. Auch in Mainfest.xml hinzugefügt
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            }else {
                Toast.makeText(this, R.string.no_permisson_gps, Toast.LENGTH_SHORT).show();
                if (!this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_FINE_LOCATION);
                }
            }
        }

> Probiere mal: BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE

BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE, hab ich probiert, 
selber Fehler. Wobei ich diesen hier nicht verstehe, weil das Programm 
nicht auf ein Acknowledge wartet.

> Bei "default" muss AFAIK das BT Gerät korrekt antworten. Kann man in der
> nRF Connect app über "Write Value->Advanced->(x)Command" einstellen.

Habe ich gemacht. Selber Fehler. Hier noch der Log. Ich war mir aber 
nicht sicher, was ich senden soll, wenn ich ein Command sende.

V 20:47:34.679 Changing write type for 
00000002-0000-1000-8000-00805f9b34fb to WRITE COMMAND
D 20:47:34.679 characteristic.setWriteType(WRITE COMMAND)
V 20:47:34.691 Writing command to characteristic 
00000002-0000-1000-8000-00805f9b34fb
D 20:47:34.691 
gatt.writeCharacteristic(00000002-0000-1000-8000-00805f9b34fb, 
value=0x23702E30)
D 20:48:04.695 [Server callback] Connection state changed with status: 0 
and new state: DISCONNECTED (0)
I 20:48:04.695 [Server] Device disconnected
E 20:48:04.709 Error 133 (0x85): GATT ERROR
D 20:48:04.743 [Callback] Connection state changed with status: 22 and 
new state: DISCONNECTED (0)
D 20:48:04.743 [Broadcast] Action received: 
android.bluetooth.device.action.ACL_DISCONNECTED
E 20:48:04.744 Error 22 (0x16): GATT CONN TERMINATE LOCAL HOST
I 20:48:04.744 Disconnected

> Wie sieht die Characteristic Definition aus? Sagt die App "WRITE" oder
> "WRITE NO RESPONSE"?

Die App sagt WRITE. Den Versuch mit 
BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE und 
BluetoothGattCharacteristic.WRITE_DEFAULT habe ich mit "WRITE" und 
"WRITE NO RESPONSE" characteristicen probiert.

von kk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Joachim schrieb:
> Ist zwar mit hoher Wahrscheinlichkeit nicht die Ursache des hier
> vorliegenden Problems, aber die UUIDs Deiner Characteristics und
> Services sollten nicht wie hier "00000002-0000-1000-8000-00805f9b34fb"
> sein.
> Denn BLE UUIDs, die auf das Muster
> "xxxxxxxx-0000-1000-8000-00805F9B34FB" passen, sind für offizielle,
> standardisierte Services und Characteristics reserviert.
>
> Für nicht standardisierte Services und Characteristics, die Du Dir
> selbst ausgedacht hast, solltest Du als UUID daher keine 16- oder
> 32-Bit-Integer-Zahl nehmen, sondern eine vollständige, 128 Bit lange,
> (pseudo)zufällig generierte UUID, z.B. von hier:

Ich dachte dies gilt nur für die UUID von Services? Ein Moment, ich 
ändere die UUID.

von Joachim (Gast)


Bewertung
0 lesenswert
nicht lesenswert
kk schrieb:
> Ich dachte dies gilt nur für die UUID von Services?

Laut
https://en.wikipedia.org/wiki/Bluetooth_Low_Energy#Identifiers
gilt das für alle "Attribute", wobei "Attribute" der gemeinsame 
Überbegriff für Services, Characteristics und Descriptors ist.

> Ein Moment, ich ändere die UUID.

Mach das. Aber ich halte es wie gesagt doch für eher unwahrscheinlich, 
dass das hier das Problem ist.

von kk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Joachim schrieb:
> kk schrieb:
>> Ich dachte dies gilt nur für die UUID von Services?
>
> Laut
> https://en.wikipedia.org/wiki/Bluetooth_Low_Energy#Identifiers
> gilt das für alle "Attribute", wobei "Attribute" der gemeinsame
> Überbegriff für Services, Characteristics und Descriptors ist.
>
>> Ein Moment, ich ändere die UUID.
>
> Mach das. Aber ich halte es wie gesagt doch für eher unwahrscheinlich,
> dass das hier das Problem ist.

Ja leider hattest du Recht, keine Veränderung. Ich glaube ich habe 
vergessen, zu erwähnen, dass das Lesen der Characteristics funktioniert. 
Ich kann z.B die ADC Spannung lesen

von kk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe etwas anderes ausprobiert. Ich habe den Interrupt, welcher die 
Informationen, vom NRF51822 holt mal ausgeschalten, weil ich gedacht 
habe, dass ev. das Polling (ich weiß man hätte es schöner lösen können), 
dass Problem ist. Jedoch tritt der selbe Fehler wieder auf. Status 133

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.