Vincent Münze
Created October 16, 2022

Plant health monitoring system

various measurements are taken on plants to measure and subsequently evaluate the health status of the plants.

80

Things used in this project

Hardware components

Nordic Thingy:53
Nordic Semiconductor Nordic Thingy:53
×1
Grove - Capacitive Soil Moisture Sensor
Seeed Studio Grove - Capacitive Soil Moisture Sensor
or any other capacitive soil moisture sensor
×1
nRF51822 Bluetooth Low Energy and 2.4 GHz SoC
Nordic Semiconductor nRF51822 Bluetooth Low Energy and 2.4 GHz SoC
Preferably on a certified module
×1
Adafruit HUZZAH32 – ESP32 Feather Board
Adafruit HUZZAH32 – ESP32 Feather Board
or any other ESP32 development board, which supports BLE and WiFi
×1

Story

Read more

Schematics

basic schematic of standalone solar device

used to measure soil moisture and report it via BLE to base station

Code

main.c

C/C++
main file for Thingy:53
onboard color sensor BH1749 data will be reported via BLE advertising message
#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>

static uint8_t adv_service_uuid[] = {0xAA,0x55,0xAA,0x55};
static uint8_t adv_service_data[] = {0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static const struct bt_data ad[] = {
	BT_DATA(BT_DATA_UUID32_ALL, adv_service_uuid, sizeof(adv_service_uuid)),
	BT_DATA(BT_DATA_SVC_DATA32, adv_service_data, sizeof(adv_service_data)),
};

struct device *dev = NULL;
void Sensor_init(void)
{
	dev = DEVICE_DT_GET_ONE(rohm_bh1749);

	if (!device_is_ready(dev)) {
		printk("Sensor device not ready\n");
		return;
	}
}

void Sensor_Process(void)
{
	int ret;
	struct sensor_value red, green, blue, ir;

	ret = sensor_sample_fetch_chan(dev, SENSOR_CHAN_ALL);
	/* The sensor does only support fetching SENSOR_CHAN_ALL */
	if (ret) {
		printk("sensor_sample_fetch failed ret %d\n", ret);
	return;
	}

	ret = sensor_channel_get(dev, SENSOR_CHAN_RED, &red);
	if (ret) {
		printk("sensor_channel_get failed ret %d\n", ret);
	return;
	}
	printk("BH1749 RED: %d\n", red.val1);

	ret = sensor_channel_get(dev, SENSOR_CHAN_GREEN, &green);
	if (ret) {
		printk("sensor_channel_get failed ret %d\n", ret);
	return;
	}
	printk("BH1749 GREEN: %d\n", green.val1);

	ret = sensor_channel_get(dev, SENSOR_CHAN_BLUE, &blue);
	if (ret) {
		printk("sensor_channel_get failed ret %d\n", ret);
	return;
	}
	printk("BH1749 BLUE: %d\n", blue.val1);

	ret = sensor_channel_get(dev, SENSOR_CHAN_IR, &ir);
	if (ret) {
		printk("sensor_channel_get failed ret %d\n", ret);
	return;
	}
	printk("BH1749 IR: %d\n", ir.val1);

	adv_service_data[0] = red.val1 >> 8;
	adv_service_data[1] = red.val1 & 0xFF;

	adv_service_data[2] = green.val1 >> 8;
	adv_service_data[3] = green.val1 & 0xFF;

	adv_service_data[4] = blue.val1 >> 8;
	adv_service_data[5] = blue.val1 & 0xFF;

	adv_service_data[6] = ir.val1 >> 8;
	adv_service_data[7] = ir.val1 & 0xFF;
}

void main(void)
{
	int err;

	printk("Starting Sensor Advertiser\n");

	/* 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 */
	struct bt_le_adv_param adv_params = *(BT_LE_ADV_NCONN_NAME);
	adv_params.interval_min = 100;
	adv_params.interval_max = 100;

	err = bt_le_adv_start(&adv_params, ad, ARRAY_SIZE(ad),
					NULL, 0);
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}

	Sensor_init();

	while(1) {
		k_sleep(K_MSEC(100));
		Sensor_Process();
		err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), NULL, 0);
		if (err) {
			printk("Update Advertising failed (err %d)\n", err);
		}
	}
}

prj.conf

Plain text
nRF Connect SDK 2.1.0 prj.conf
CONFIG_BT=y
CONFIG_BT_BROADCASTER=y
#CONFIG_BT_OBSERVER=y
CONFIG_BT_DEBUG_LOG=y

CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_BH1749=y
CONFIG_BH1749_TRIGGER=y

Credits

Vincent Münze

Vincent Münze

2 projects • 1 follower

Comments