Antony J.
Created September 28, 2025

Sentient Canopy

Sentry Canopy sends instant AI alerts to your phone, preventing dangerous wildlife encounters while also optimizing farm harvests.

10

Things used in this project

Story

Read more

Code

Main.c

C Header File
This code outputs the BME688 readings to the app
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/byteorder.h>

// 1. Define custom UUIDs for our service and characteristic
// These are like the "addresses" for our sensor data. The Android app will need these exact same values.
#define UUID_BME_SERVICE BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123)
#define UUID_BME_CHAR      BT_UUID_128_ENCODE(0x00001524, 0x1212, 0xefde, 0x1523, 0x785feabcd123)

static const struct bt_uuid_128 bme_service_uuid = BT_UUID_INIT_128(UUID_BME_SERVICE);
static const struct bt_uuid_128 bme_char_uuid = BT_UUID_INIT_128(UUID_BME_CHAR);

// 2. Data structure to hold our sensor values
// We will send 12 bytes in total over BLE.
static uint8_t sensor_data[12];

// 3. Define the BLE service and its characteristic
BT_GATT_SERVICE_DEFINE(bme_svc,
    BT_GATT_PRIMARY_SERVICE(&bme_service_uuid),
    BT_GATT_CHARACTERISTIC(&bme_char_uuid.uuid,
                           BT_GATT_CHRC_NOTIFY, // The characteristic supports notifications
                           BT_GATT_PERM_READ,   // Permissions
                           NULL, NULL, NULL)
);

// 4. Advertising data - what the Thingy:53 broadcasts to the world
static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA_BYTES(BT_DATA_UUID128_ALL, UUID_BME_SERVICE),
};


void main(void)
{
    printk("Thingy:53 BME688 BLE Sensor Example\n");

    // Initialize Bluetooth
    int err = bt_enable(NULL);
    if (err) {
        printk("Bluetooth init failed (err %d)\n", err);
        return;
    }
    printk("Bluetooth initialized\n");

    // Start advertising
    err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
    if (err) {
        printk("Advertising failed to start (err %d)\n", err);
        return;
    }
    printk("Started advertising\n");

    // Get the BME688 sensor device
    const struct device *bme_dev = DEVICE_DT_GET_ONE(bosch_bme680);
    if (!device_is_ready(bme_dev)) {
        printk("Sensor: device not ready.\n");
        return;
    }

    struct sensor_value temp, press, humidity, gas_res;

    while (1) {
        // Fetch all sensor channels
        sensor_sample_fetch(bme_dev);
        sensor_channel_get(bme_dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
        sensor_channel_get(bme_dev, SENSOR_CHAN_PRESS, &press);
        sensor_channel_get(bme_dev, SENSOR_CHAN_HUMIDITY, &humidity);
        sensor_channel_get(bme_dev, SENSOR_CHAN_GAS_RES, &gas_res);

        // --- Pack the data for BLE transmission ---
        // To send floats efficiently, we multiply by 100 and send as integers.
        int16_t temp_val = (int16_t)( (temp.val1 * 100) + (temp.val2 / 10000) );
        int32_t press_val = (int32_t)( (press.val1 * 100) + (press.val2 / 10000) );
        int16_t hum_val = (int16_t)( (humidity.val1 * 100) + (humidity.val2 / 10000) );
        int32_t gas_val = gas_res.val1; // Gas resistance is already an integer

        // Use sys_put_le to ensure little-endian byte order, which is standard for BLE
        sys_put_le16(temp_val, &sensor_data[0]); // Bytes 0-1: Temperature
        sys_put_le32(press_val, &sensor_data[2]); // Bytes 2-5: Pressure
        sys_put_le16(hum_val, &sensor_data[6]); // Bytes 6-7: Humidity
        sys_put_le32(gas_val, &sensor_data[8]); // Bytes 8-11: Gas Resistance

        // Send the data as a notification to the connected app
        bt_gatt_notify(NULL, &bme_svc.attrs[1], sensor_data, sizeof(sensor_data));

        printk("T: %d.%06d | P: %d.%06d | H: %d.%06d | G: %d\n",
               temp.val1, temp.val2, press.val1, press.val2,
               humidity.val1, humidity.val2, gas_res.val1);
        
        k_sleep(K_SECONDS(2));
    }
}

Sentient-canopy-code

Detailed Bluetooth mesh network implementation with android apk

Credits

Antony J.
5 projects • 1 follower
I operate where hardware, software, and security intersect.

Comments