max30102 sensor with NUS Service using zephyr

Hi all,

Could anyone share a code example for sending sensor data  over BLE using the NUS Service in Zephyr RTOS? I'm new to this field and struggling to get data from the MAX30102 sensor over BLE.
If you could provide any samples, I would greatly appreciate it.

Thank you,

Fernando

Parents
  • Hi Fernando,

    Have you checked that the sensor data you have here is good, and if bt_nus_send returns any error? I am talking about the code between line 594 and 597.

    Hieu


    Please be informed that due to a short holiday, there will be some delays in our responses in the coming days. Our apologies for the inconvenience.

  • Hi Hieu,

    Thank you for your reply

    No there is no error showing its  "Starting Nordic UART service example"  and I can connect the peripheral through the nrf connect mobile app.
    But it I could not get the sensor data here my max.c and max.h file
    Please help for get the sensor data thank you again.

    Best regards,
    Madusha Fernando

    #ifndef MAX_H
    #define MAX_H
    
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/i2c.h>
    #include <zephyr/sys/printk.h>
    
    /* Device-specific register addresses and settings */
    #define MAX30102_ADDRESS     0x57
    #define INT_ENABLE_1         0xC0
    #define INT_ENABLE_2         0x00
    #define FIFO_WR_PTR          0x00
    #define OVERFLOW_CTR         0x00
    #define FIFO_RD_PTR          0x00        
    #define FIFO_CONF            0x4F
    #define SPO2_CONF            0x27
    #define MODE_CONF            0x40
    #define INT_STATUS_1         0x00
    #define INT_STATUS_2         0x01
    #define MAX30102_REG_FIFO_DATA  0x07 
    #define MAX30102_REG_LED1_PA 0x0C
    #define MAX30102_REG_LED2_PA 0x0D
    #define MAX30102_REG_MODE_CONFIGURATION 0x09
    #define MAX30102_RESET 0x40
    
    /* Node identifier for the sensor */
    #define I2C_NODE DT_NODELABEL(mysensor)
    
    /* Function prototypes */
    int max30102_init(const struct device *dev);
    int max30102_read_fifo(const struct device *dev, uint32_t *red_led, uint32_t *ir_led);
    
    int ble_init(void);
    
    struct sensor_data_t {
        uint32_t red_led;
        uint32_t ir_led;
    } __packed;
    
    #endif /* MAX_H */
    



    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/i2c.h>
    #include <zephyr/sys/printk.h>
    
    #include "max.h"
    
    /* Define a variable to hold the NUS instance */
    static struct bt_nus_cb nus_cb;
    
    /* Define a variable to hold BLE data */
    static struct ble_data_t ble_data;
    
    /* Callback function to handle BLE data received event */
    static ssize_t ble_data_received(struct bt_conn *conn, const struct bt_gatt_attr *attr,
    				  const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
    {
    	/* Handle received data if needed */
    	return len;
    }
    
    /* BLE initialization function */
    int ble_init(void)
    {
    	int err;
    
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return err;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	bt_nus_init(&nus_cb);
    
    	/* Register callback for data received event */
    	nus_cb.received = ble_data_received;
    
    	return 0;
    }
    
    /* Initialize the MAX30102 sensor */
    int max30102_init(const struct device *dev)
    {
        int ret;
        
        if (!device_is_ready(dev)) {
            printk("I2C bus %s is not ready!\n", dev->name);
            return -1;
        }
    
        uint8_t config[4] = {MAX30102_RESET, MAX30102_REG_MODE_CONFIGURATION, MODE_CONF, 0x40};
        ret = i2c_write(dev, config, sizeof(config), MAX30102_ADDRESS);
        if (ret != 0) {
            printk("Failed to write to I2C device address %x at Reg. %x \n", MAX30102_ADDRESS, config[0]);
            return -1;
        }
    
        k_msleep(100);
    
        uint8_t setup_registers[] = {
            INT_ENABLE_1, 0xC0,
            INT_ENABLE_2, 0x00,
            FIFO_WR_PTR, 0x00,
            OVERFLOW_CTR, 0x00,
            FIFO_RD_PTR, 0x00,
            FIFO_CONF, 0x5F,
            SPO2_CONF, 0x27,
            MAX30102_REG_LED1_PA, 0x1F,
            MAX30102_REG_LED2_PA, 0x1F,
            MAX30102_REG_MODE_CONFIGURATION, 0x03
        };
    
        ret = i2c_write(dev, setup_registers, sizeof(setup_registers), MAX30102_ADDRESS);
        if (ret != 0) {
            printk("Failed to write setup registers to MAX30102\n");
            return -1;
        }
    
        /* Initialize BLE */
        ble_init();
    
        return 0;
    }
    
    /* Read sensor data from MAX30102 sensor and transmit over BLE */
    int max30102_read_fifo(const struct device *dev, uint32_t *red_led, uint32_t *ir_led)
    {
        int ret;
        uint8_t data_array[6];
    
        ret = i2c_burst_read(dev, MAX30102_ADDRESS, MAX30102_REG_FIFO_DATA, data_array, sizeof(data_array));
        if (ret != 0) {
            printk("Failed to read FIFO data from I2C device address %x\n", MAX30102_ADDRESS);
            return -1;
        }
    
        *red_led = (data_array[0] << 16) | (data_array[1] << 8) | data_array[2];
        *ir_led = (data_array[3] << 16) | (data_array[4] << 8) | data_array[5];
    
        /* Populate BLE data */
        ble_data.red_led = *red_led;
        ble_data.ir_led = *ir_led;
    
        /* Transmit BLE data using NUS */
        bt_nus_send(NULL, &ble_data, sizeof(ble_data));
    
        return 0;
    }
    


  • Hi Fernando,

    Which sensor you are using and how you are connecting to the hardware?

    How does your overlay file look like. Also indicate about the prj.conf.

    I see in your main file you are calling "max_init()", but I don't see it in your "max.c" file.

    Can you send your minimal project, that as you have said would compile. Also indicate details about your sensor and the connections.

    Mention the NCS version and the DK / board that you are using.

    Regards,

Reply
  • Hi Fernando,

    Which sensor you are using and how you are connecting to the hardware?

    How does your overlay file look like. Also indicate about the prj.conf.

    I see in your main file you are calling "max_init()", but I don't see it in your "max.c" file.

    Can you send your minimal project, that as you have said would compile. Also indicate details about your sensor and the connections.

    Mention the NCS version and the DK / board that you are using.

    Regards,

Children
No Data
Related