Why isn't my Arduino Nano 33 BLE Sense transmitting pulse and SpO2 data via BLE?

Hello, I am working on a health monitoring system using an Arduino Nano 33 BLE Sense and a Pulse Oximeter (MAX30102) sensor. The objective is to measure and transmit pulse and oxygen saturation data using Bluetooth Low Energy (BLE). The system is running on MicroPython. I have checked that the I2C connection and initialization for the MAX30102 sensor is okay, confirmed the BLE initialization and advertising settings, tested BLE connection with a mobile app to ensure proper pairing. But am getting the error 
The BLE connection is not successfully transmitting the pulse and SpO2 data. While the sensor readings are correctly displayed in the serial monitor, the BLE notifications are not received on the connected device.
The BLE connection is not successfully transmitting the pulse and SpO2 data. While the sensor readings are correctly displayed in the serial monitor, the BLE notifications are not received on the connected device.
This is my MicroPython Code for Arduino Nano 33 BLE Sense
9 Replies
Enthernet Code
Enthernet Code5mo ago
import time

from machine import I2C, Pin

from max30102 import MAX30102

from ubluetooth import BLE, UUID, FLAG_READ, FLAG_WRITE


# Initialize I2C

i2c = I2C(1, scl=Pin(19), sda=Pin(18))


# Initialize MAX30102

max30102 = MAX30102(i2c)


# Initialize BLE

ble = BLE()

ble.active(True)


# Define BLE Service and Characteristics

pulse_ox_service = UUID(0x1810)

pulse_char = (UUID(0x2A37), FLAG_READ | FLAG_WRITE)

spo2_char = (UUID(0x2A5F), FLAG_READ | FLAG_WRITE)


# Define BLE Services

pulse_ox_service = (pulse_ox_service, (pulse_char, spo2_char))

services = (pulse_ox_service, )


# Start advertising

ble.config(gap_name='HealthMonitor')

ble.gatts_register_services(services)

ble.gap_advertise(100, b'\x02\x01\x06\x03\x03\x10\x18')


def read_sensor():

    red, ir = max30102.read_sequential()

    pulse = calculate_pulse(ir)

    spo2 = calculate_spo2(red, ir)

    return pulse, spo2


def calculate_pulse(ir_data):

    # Placeholder for pulse calculation algorithm

    return sum(ir_data) / len(ir_data)


def calculate_spo2(red_data, ir_data):

    # Placeholder for SpO2 calculation algorithm

    return (sum(red_data) / sum(ir_data)) * 100


while True:

    pulse, spo2 = read_sensor()

    print("Pulse:", pulse, "SpO2:", spo2)

    ble.gatts_notify(0, pulse_char[0], str(pulse))

    ble.gatts_notify(0, spo2_char[0], str(spo2))

    time.sleep(1)
import time

from machine import I2C, Pin

from max30102 import MAX30102

from ubluetooth import BLE, UUID, FLAG_READ, FLAG_WRITE


# Initialize I2C

i2c = I2C(1, scl=Pin(19), sda=Pin(18))


# Initialize MAX30102

max30102 = MAX30102(i2c)


# Initialize BLE

ble = BLE()

ble.active(True)


# Define BLE Service and Characteristics

pulse_ox_service = UUID(0x1810)

pulse_char = (UUID(0x2A37), FLAG_READ | FLAG_WRITE)

spo2_char = (UUID(0x2A5F), FLAG_READ | FLAG_WRITE)


# Define BLE Services

pulse_ox_service = (pulse_ox_service, (pulse_char, spo2_char))

services = (pulse_ox_service, )


# Start advertising

ble.config(gap_name='HealthMonitor')

ble.gatts_register_services(services)

ble.gap_advertise(100, b'\x02\x01\x06\x03\x03\x10\x18')


def read_sensor():

    red, ir = max30102.read_sequential()

    pulse = calculate_pulse(ir)

    spo2 = calculate_spo2(red, ir)

    return pulse, spo2


def calculate_pulse(ir_data):

    # Placeholder for pulse calculation algorithm

    return sum(ir_data) / len(ir_data)


def calculate_spo2(red_data, ir_data):

    # Placeholder for SpO2 calculation algorithm

    return (sum(red_data) / sum(ir_data)) * 100


while True:

    pulse, spo2 = read_sensor()

    print("Pulse:", pulse, "SpO2:", spo2)

    ble.gatts_notify(0, pulse_char[0], str(pulse))

    ble.gatts_notify(0, spo2_char[0], str(spo2))

    time.sleep(1)
@Middleware & OS
Marvee Amasi
Marvee Amasi5mo ago
Why are you sending the pulse and SpO2 data as strings (str(pulse)) in the ble.gatts_notify calls , BLE expect raw byte data
Marvee Amasi
Marvee Amasi5mo ago
Use bytes([pulse]) and bytes([spo2]) instead of str(pulse) and str(spo2) . Cus you should convert the integer values to a single byte format
Enthernet Code
Enthernet Code5mo ago
Would that result in an error @Marvee Amasi, I just wanted to send print it as strings on screen
Marvee Amasi
Marvee Amasi5mo ago
No no you won't get an error by sending the data as strings to the serial monitor for display purposes. My suggestion focused on sending the data correctly over BLE for the mobile app
Enthernet Code
Enthernet Code5mo ago
Okay, now I understand it fails because it expects bytes value and am supplying it a string right
Enthernet Code
Enthernet Code5mo ago
Is it okay if I do it this way str(pulse).encode('utf-8')
Marvee Amasi
Marvee Amasi5mo ago
Only one way to find out , check let's see if you will get the error message again
Enthernet Code
Enthernet Code5mo ago
Okay, testing it now
Want results from more Discord servers?
Add your server