capacitor-community / bluetooth-le

Capacitor plugin for Bluetooth Low Energy
MIT License
284 stars 86 forks source link

Unable to read Data from Bluetooth sensor on 100ms #710

Open safiUllahRai opened 2 weeks ago

safiUllahRai commented 2 weeks ago

A clear and concise description of what the bug is. I am developing the application where it use this plugin to interact with Bluetooth pressure sensor called "TESS 5600" where I have to fetch pressure data from sensor. Application is fetching pressure data on 1 second interval even app is fetching data on 500ms but it is giving error when I am setting the interval value to 100ms

Screenshots at 100ms at 500ms

I have attached the 2 screenshots where it is fetching data at 500ms and giving error at 100ms interval

Plugin version:

peitschie commented 2 weeks ago

Hi @safiUllahRai

Can you show what the characteristic read code on the javascript side looks like?

Sometimes a peripheral will have it's own limitations that can prevent reading data too quickly.

safiUllahRai commented 2 weeks ago

Hi @peitschie Here is my code for reading pressure values using characteristic and service ids

async readPressureValue(deviceId: string) { try { const result = await BluetoothLe.read({ deviceId, serviceId, characteristicId, });

  if (result.value) {
    let buffer: Uint8Array;

    if (typeof result.value === 'string') {

      // Parse the string data into an array of bytes
      const byteString = result.value.replace(/\s+/g, '');
      const byteArray = byteString.match(/.{1,2}/g);
      if (byteArray) {
        buffer = new Uint8Array(byteArray.map(byte => parseInt(byte, 16)));
      } else {
        console.error('No byte data found in the string');
        return;
      }
    } else if (result.value instanceof DataView) {
      buffer = new Uint8Array(result.value.buffer);
    } else {
      console.error('Unsupported data format:', result.value);
      return;
    }

    const pressureBytes = buffer.slice(2, 6);

    // Convert to unsigned integer (little-endian)
    const rawPressureValue = new DataView(pressureBytes.buffer).getUint32(0, true); // Little-endian format

    // Conversion factors
    const scaleFactor = 0.1; // Example scale factor for Pascal (Pa), replace with the actual one from your protocol
    const paToPsiFactor = 0.000145038; // Conversion factor from Pascal to PSI

    // Convert raw value to Pascal
    const pressureInPa = rawPressureValue * scaleFactor;

    // Convert Pascal to PSI
    const pressureValueInPSI = pressureInPa * paToPsiFactor;

    // You can assign the value to a class variable if needed
    this.pressureValueInPSI = pressureValueInPSI;
    if (this.rec2 && this.rec2.connectionType && this.rec2.connectionOD) {
      if (this.rec2.connectionType === 'Breakout') {
        this.calculatedTorque = this.pressureValueInPSI * ((-0.041748 * this.rec2.connectionOD) + 1.1894);
        this.torqueValue = this.calculatedTorque
      } else if (this.rec2.connectionType === 'Makeup') {
        this.calculatedTorque = this.pressureValueInPSI * ((-0.020802 * this.rec2.connectionOD) + 0.51037);
        this.torqueValue = this.calculatedTorque
      }
    }
  } else {

  }
} catch (error) {
  console.error('Error reading sensor values', error);
}

}

peitschie commented 2 weeks ago

In your screenshot above... it appears that sometimes you end up with a new read request while the previous one is still not yet returned?

image

How are you triggering these reads currently? Do you wait for the last read to complete first, or are you triggering these on a setInterval or similarly fixed timer?

Usually, overlapping reads on the same characteristic like this are not well supported.