nRF52DK with BME280 Sensor

Hi All,

I have been trying to get the BME280 to work with the nRF52 Development Kit using the Zephyr Framework,

I can't seem to get the firmware to pick-up the BME280 sensor, although I have define the correct I2C address, below is the code Main.c code and the bme.c and the bme.h as well as my prj.conf and the overlay file.

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/printk.h>
#include <sys/util.h>
#include <zephyr/types.h>
#include "bme280.h"
#include <logging/log.h>

#define ADV_PARAM \
BT_LE_ADV_PARAM(0, BT_GAP_ADV_SLOW_INT_MIN, \
BT_GAP_ADV_SLOW_INT_MAX, NULL)

static struct bt_data ad[] = {
		BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
		BT_DATA_BYTES(
		BT_DATA_MANUFACTURER_DATA, 0xff, 0xff, /* Test company ID */
		0x00, 0x00, /* Temperature, int16, little-endian */
		0x00, 0x00, /* Pressure - 50000, uint16, little-endian */
		0x00, 0x00) /* Humidity, uint16, little-endian */
		};


void update_ad_bme280(const struct device *dev) {

	int16_t temperature;
	uint16_t pressure, humidity;
	bme280_fetch_sample(dev);
	temperature = bme280_get_temperature(dev);
	memcpy(&(ad[1].data[2]), &temperature, 2);
	pressure = bme280_get_pressure(dev);
	memcpy(&(ad[1].data[4]), &pressure, 2);
	humidity = bme280_get_humidity(dev);
	memcpy(&(ad[1].data[6]), &humidity, 2);

}

void main(void) {

	int err;
	printk("Starting firmware...\n");
	// Initialize BME280
	const struct device *bme280 = bme280_get_device();

		if (bme280 == NULL) {
		return;
		}

		// Initialize the Bluetooth subsystem
		err = bt_enable(NULL);

		if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
			return;
		}

		printk("Bluetooth initialized\n");
		// Start advertising sensor values
		update_ad_bme280(bme280);
		err = bt_le_adv_start(ADV_PARAM, ad, ARRAY_SIZE(ad), NULL, 0);

		if (err) {
			printk("Advertising failed to start (err %d)\n", err);
			return;
		}

			while (1) {

		k_sleep(K_MSEC(980));
		// Update advertised sensor values
		update_ad_bme280(bme280);
		err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), NULL, 0);
		
		if (err) {
			printk("Advertising update failed (err %d)\n", err);
			return;
		}
	}
}

Here is the bme.c code

#include <device.h>
#include <devicetree.h>
#include <drivers/sensor.h>
#include <sys/printk.h>
#include <zephyr/types.h>

/*
 * Get a device structure from a devicetree node with compatible
 * "bosch,bme280". (If there are multiple, just pick one.)
 */
const struct device *bme280_get_device(void) {
  const struct device *dev = DEVICE_DT_GET_ANY(bosch_bme280);

  if (dev == NULL) {
    /* No such node, or the node does not have status "okay". */
    printk("\nError: no device found.\n");
    return NULL;
  }

  if (!device_is_ready(dev)) {
    printk("\nError: Device \"%s\" is not ready; "
           "check the driver initialization logs for errors.\n",
           dev->name);
    return NULL;
  }

  printk("Found device \"%s\", getting sensor data\n", dev->name);
  return dev;
}

void bme280_fetch_sample(const struct device *dev) {
  sensor_sample_fetch(dev);
}

int16_t bme280_get_temperature(const struct device *dev) {
  struct sensor_value temperature;

  sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
  return (int16_t)(temperature.val1 * 100 + temperature.val2 / 10000);
}

uint16_t bme280_get_pressure(const struct device *dev) {
  struct sensor_value pressure;
  uint32_t p; // Pressure without offset

  sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
  p = (uint32_t)(pressure.val1 * 1000 + pressure.val2 / 10000);
  return (uint16_t)(p - 50000);
}

uint16_t bme280_get_humidity(const struct device *dev) {
  struct sensor_value humidity;

  sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);
  return (uint16_t)(humidity.val1 * 100 + humidity.val2 / 10000);
}

here is the bme.h code

#ifndef BME280_H_
#define BME280_H_

const struct device *bme280_get_device(void);
void bme280_fetch_sample(const struct device *dev);
int16_t bme280_get_temperature(const struct device *dev);
uint16_t bme280_get_pressure(const struct device *dev);
uint16_t bme280_get_humidity(const struct device *dev);

#endif /* BME280_H_ */

here is the overlay file

 &i2c0 {
  status = "okay";
  sda-pin = <26>;
  scl-pin = <27>;
  bme280@77 {
    compatible = "bosch,bme280";
    reg = <0x77>;
    label = "BME280_I2C";
  };
};
  &uart0 {
    current-speed = <115200>;
    status = "okay";
    tx-pin = <6>;
    rx-pin = <8>;
};

here is the prj.conf

CONFIG_BT=y
# Enable BME280 sensor
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_BME280=y

#CONFIG_BT_DEVICE_NAME="GAVO_IV"
CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y
CONFIG_LOG=y

and the cmake:

cmake_minimum_required(VERSION 3.13.1)
#include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(ZEPHYR_BME280)

FILE(GLOB app_sources ../src/*.c*)
target_sources(app PRIVATE ${app_sources})
#target_sources(app PRIVATE src/bme280.c src/main.c)

message(STATUS "Current source directory: ${CMAKE_CURRENT_SOURCE_DIR}")

Any help would be greatly appreciated!

Related