Problem sending Data from Arduino nano BLE to Raspberry pi zero

Hi!
I am developing a code to send inbuilt accelerometer data from arduino nano BLE to Raspberry pi zero W

On arduino, i created an array with 3 values and wrote this array to the bluetooth characteristic that i have defined. The arduino and rasp berry pi code is attached below.

The code works, but on the raspberry pi the read function is able to read only the accelerometerX value and shows an output like
(0.130859375,)

I am expecting the output to be something like (0.130859375,0.23647423,-0.3247123))

Also is there a way to increase the speed at which I can read the data on raspberry pi? Right now it seems like i can read only one value per second. Where as the rate at which the data is generated on the raspberry pi is higher.

I am a beginner in embedded software design, and it would help me a lot if I can learn to get over this issue.
Thank you in advance

#include "Arduino.h"
#include <ArduinoBLE.h>
#include "Nano33BLEAccelerometer.h"
#define BLE_DEVICE_NAME                "Arduino Nano 33 BLE Sense"
#define BLE_LOCAL_NAME                "Accelerometer BLE"
Nano33BLEAccelerometerData accelerometerData;
BLEService BLEAccelerometer("590d65c7-3a0a-4023-a05a-6aaf2f22441c");
BLECharacteristic accelerometerXBLE("0004", BLERead | BLENotify | BLEBroadcast, 12);

union
 {
  float a[3];
  unsigned char bytes[12];      
 } accData;

void setup()
{
    Serial.begin(115200);
    while(!Serial);
    const unsigned char initializerAcc[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
    if (!BLE.begin())
    {
        while (1);    
    }
    else
    {
        BLE.setDeviceName(BLE_DEVICE_NAME);
        BLE.setLocalName(BLE_LOCAL_NAME);
        BLE.setAdvertisedService(BLEAccelerometer);
        /* A seperate characteristic is used for each X, Y, and Z axis. */
        BLEAccelerometer.addCharacteristic(accelerometerXBLE);
        accelerometerXBLE.setValue( initializerAcc, 12);
        BLE.addService(BLEAccelerometer);
        BLE.advertise();
        Accelerometer.begin();
    }
}
void loop()
{
    BLEDevice central = BLE.central();
    if(central)
    {
        int writeLength;
        while(central.connected())
        {            
            if(Accelerometer.pop(accelerometerData))
            {
                accData.a[0] = accelerometerData.x;
                accData.a[1] = accelerometerData.y;
                accData.a[2] = accelerometerData.z;
                unsigned char *acc = (unsigned char *)&accData;
                accelerometerXBLE.setValue( acc, 12 );

                Serial.printf("%f,%f,%f\r\n", accelerometerData.x, accelerometerData.y, accelerometerData.z);
            }
        }
    }
}

Raspberry pi code :

import binascii
import struct
import time
from bluepy.btle import UUID,Peripheral
temp_uuid = UUID("590d0004-3a0a-4023-a05a-6aaf2f22441c")
p = Peripheral("EE:E3:AF:96:96:96","public")
services = p.getServices()

try:
    ch = p.getCharacteristics(uuid=UUID(0x0004))[0]
    while 1:
        val = ch.read()
        print(struct.unpack_from('e',val))
finally:
    p.disconnect()

My BLE projects all use a UART service, usually the Nordic Uart service, and then just send a stream of data.
See example sketches in Arduino NANO 33 Made Easy for how to set up the nano using ArduinoBLE V2.0.0
I cannot help on the Pi side, but you seem to have a handle on that and the nano side should give you some clues.

I run your code with some slight modifications because I did not know what library your are using for the accelerometer and printf does not work for my environment.

  • Which library are you using?
  • How did you compile the code?

Anyways, I tested the sketch with a Raspberry 4 and gatttool and I did see the characteristic with 12 bytes. So, the issue must come from your python sketch.

I have not used bluepy.

  • How did you install it on your Raspberry Pi? Are there different versions?
  • How did you come up wit the python code? It does not look intuitive. Did you try to modify an example or did you write it from scratch?
  • Can you recommend any documentation or tutorial?

About your code. You must not use 16-bit UUIDs except for services and characteristics defined by the Bluetooth SiG. For your own services and characteristics you must use 128-bit random UUIDs.

Thank you for your reply Klaus

On arduino side we are using the Nano33BleSense library
You can find the documentation here

But we have tried using the Lsm9ds1 library also but getting the same result on the Pi side.

For bluepy installation we followed the steps mentioned in the following link

Ok, We’ll look into changing the UUID to 128-bit random UUID and check if that helps.

I installed bluepy on my Raspberry Pi4 and got it to work.

Your issue is the struct.unpack_from() function. Have a look at the following documentation.

https://docs.python.org/3/library/struct.html

Because Arduino uses 32-bit floating point (4 bytes) you need to use an ‘f’ instead of an ‘e’. Because you have three of them you need to use ‘fff’. And just to make sure we specify little-endian because we use an ARM Cortex processor which uses little-endian byte order.

print( struct.unpack_from( '<fff', value ) )

It will not, but using 16-bit UUIDs for your own services and characteristics is against the Bluetooth rules.

Hey @Klaus_K
Thank you so much for the solution. It worked!
We had been stuck with this error for many months and you solved it in a day. I am so grateful for your efforts and expertise.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.