ble_bouton.c
The board becomes a BLE peripheral: service 0xFFF0 exposes a notify characteristic whose value tracks button sw0. A phone (nRF Connect app) sees each press live. The base of any wireless remote or sensor.
Hardware
An nRF52833-DK board (Nordic, nRF52833 Cortex-M4F SoC, BLE 5) powered over USB: 4 LEDs on P0.13-P0.16 (active-low) and 4 buttons on P0.11, P0.12, P0.24, P0.25 (active-low, internal pull-up must be enabled). The board alone on the hardware side; a smartphone with nRF Connect or LightBlue on the client side.
Wiring
No wiring, the antenna is on-board (the MDK has its ceramic antenna; the DK has the module antenna).
How it works
BT_GATT_SERVICE_DEFINE declares the GATT statically; bt_le_adv_start broadcasts the name; bt_gatt_notify pushes the value to subscribed clients through the CCC. Kconfig BT=y required.
Running it
Zephyr project: west build -b nrf52833dk/nrf52833 then west flash (on-board J-Link); 115200 serial console on the USB UART connector.
Variants
Add pairing/bonding (CONFIG_BT_SMP), send periodic sensor readings, or switch to the standard NUS service for a BLE serial terminal.
ble_bouton.c
/* Périphérique BLE : service custom avec caractéristique notify.
* Kconfig : CONFIG_BT=y, CONFIG_BT_PERIPHERAL=y (nRF Connect SDK). */
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/drivers/gpio.h>
static const struct gpio_dt_spec btn =
GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);
static uint8_t etat_btn;
/* Service 0xFFF0, caractéristique notify 0xFFF1 (UUID 16 bits maison) */
BT_GATT_SERVICE_DEFINE(svc_bouton,
BT_GATT_PRIMARY_SERVICE(BT_UUID16_DECLARE(0xFFF0)),
BT_GATT_CHARACTERISTIC(BT_UUID16_DECLARE(0xFFF1),
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ,
NULL, NULL, &etat_btn),
BT_GATT_CCC(NULL, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME,
sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};
int main(void)
{
gpio_pin_configure_dt(&btn, GPIO_PULL_UP);
bt_enable(NULL);
bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
int dernier = -1;
while (1) {
int e = gpio_pin_get_dt(&btn);
if (e != dernier) {
dernier = e;
etat_btn = e;
bt_gatt_notify(NULL, &svc_bouton.attrs[1],
&etat_btn, sizeof(etat_btn));
}
k_msleep(50);
}
return 0;
}