__vfprintf.h: No such file or directory + Radio comms

Good day,

I am learning how to program NRF52832 chips using the NRF52 DK. I am using Segger embeddded v8.2 for the moment as I have not yet learnt how to use the NRF Connect and RSOC.

I have the following questions;

1) When I try to run the existing example file esb_low_power, I am struck with the error of __vfprintf.h: No such file or directory in Compiling 'SEGGER_RTT_Syscalls_SES.c'. I have searched the forums, however these solutions do not help me by removing 'SEGGER_RTT_Syscalls_SES.c' file.

2) I want to eventually communicate 2 development kit boards with one another, transmitting over their radios. For the moment, any random data strings or integers would work. In the future it would be data read from 2 pressure sensors connected to each DK. Would anyone have advice on best procedure for this for a beginner?

Thank you.

Parents
  • Hi anpiri,

    I am using Segger embeddded v8.2 for the moment as I have not yet learnt how to use the NRF Connect and RSOC.

    I have the following questions;

    1) When I try to run the existing example file esb_low_power, I am struck with the error of __vfprintf.h: No such file or directory in Compiling 'SEGGER_RTT_Syscalls_SES.c'. I have searched the forums, however these solutions do not help me by removing 'SEGGER_RTT_Syscalls_SES.c' file.

    This issue is characteristic of using a SEGGER Embedded Studio (SES) that is too new. If you are using the nRF5 SDK, please use SDK v17.1.0 together with SES v5.42a. That's what the SDK version was released and tested with.

    However, even better is to not use the nRF5 SDK and start with the nRF Connect SDK instead. It can be a little hard to get into, but we have online lessons to help you start with it here: Nordic Semiconductor Online Learning Platform - Nordic Developer Academy.

    Meanwhile, the nRF5 SDK is in maintenance mode and will not receive any updates.

    2) I want to eventually communicate 2 development kit boards with one another, transmitting over their radios. For the moment, any random data strings or integers would work. In the future it would be data read from 2 pressure sensors connected to each DK. Would anyone have advice on best procedure for this for a beginner?

    I recommend you visit the Bluetooth Low Energy Fundamentals course from us to get accustomed with BLE concepts first.

    After that, you can explore the standardized services specified by the Bluetooth SIG. You can do so by searching the keyword "service" here: Specifications | BluetoothRegistered Technology Website.

    You most likely will fine a standard service that meets your need. If somehow you don't, you can create your own service to transmit data, following the BLE Fundamentals course above. If you need something even more ready-to-go, you can use the Nordic UART Service, which we provide samples for both Server and Client.

    Hieu

  • Thank you for that, I have completed the steps you mentioned and finished the courses. However I am having a problem with my current test code which should be simple. In theory, I just want to communicate between two DK's but pushing a button on one resulting in an LED on another turning on. I will attach my code for both, and if something looks obviously wrong I would appreciate any advice. I am currently unsuccessful with the part to automatically connect with each other. I can see the peripheral device in the Nordic application on my phone, and they both have the same UUID. WHen my controller is scanning, it cannot find the device.

    Receiver code (acts as peripheral)


    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/gap.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/bluetooth/addr.h>
    #include <zephyr/bluetooth/conn.h>
    #include <bluetooth/services/lbs.h>

    #include <dk_buttons_and_leds.h>

    #define USER_BUTTON DK_BTN1_MSK
    #define RUN_STATUS_LED DK_LED4
    #define CONNECTION_STATUS_LED   DK_LED2
    #define RUN_LED_BLINK_INTERVAL 1000


    struct bt_conn *my_conn = NULL;

    static const struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(
        (BT_LE_ADV_OPT_CONNECTABLE |
         BT_LE_ADV_OPT_USE_IDENTITY), /* Connectable advertising and use identity address */
        BT_GAP_ADV_FAST_INT_MIN_1, /* 0x30 units, 48 units, 30ms */
        BT_GAP_ADV_FAST_INT_MAX_1, /* 0x60 units, 96 units, 60ms */
        NULL); /* Set to NULL for undirected advertising */

    LOG_MODULE_REGISTER(led_receiver, LOG_LEVEL_INF);

    /* Advertising data */
    #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
    #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

    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, DEVICE_NAME, DEVICE_NAME_LEN),
    };

    static const struct bt_data sd[] = {
        BT_DATA_BYTES(BT_DATA_UUID128_ALL,
                  BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123)),
    };

    /* --- LED write callback ---
     */
    static void led_write_cb(uint8_t led_state)
    {
        LOG_INF("LED write callback: led_state = %d", led_state);
        if (led_state) {
            dk_set_led(RUN_STATUS_LED, 1);
        } else {
            dk_set_led(RUN_STATUS_LED, 0);
        }
    }

    /* Callbacks */
    void on_connected(struct bt_conn *conn, uint8_t err)
    {
        if (err) {
            LOG_ERR("Connection error %d", err);
            return;
        }
        LOG_INF("Connected");
        my_conn = bt_conn_ref(conn);
        dk_set_led(CONNECTION_STATUS_LED, 1);
    }

    void on_disconnected(struct bt_conn *conn, uint8_t reason)
    {
        LOG_INF("Disconnected. Reason %d", reason);
        dk_set_led(CONNECTION_STATUS_LED, 0);
        bt_conn_unref(my_conn);
    }

    struct bt_conn_cb connection_callbacks = {
        .connected          = on_connected,
        .disconnected       = on_disconnected,
    };

    void main(void)
    {
        int err;

        LOG_INF("Starting LED Receiver (Peripheral)");

        /* Initialize the DK LEDs */
        err = dk_leds_init();
        if (err) {
            LOG_ERR("LEDs init failed (err %d)", err);
            return;
        }

        /* Initialize the LED Button Service (LBS) with your LED write callback.
         * The LBS service will register a GATT write callback on its LED characteristic.
         */
        err = bt_lbs_init(led_write_cb);
        if (err) {
            LOG_ERR("LBS init failed (err %d)", err);
            return;
        }

        /* Enable Bluetooth */
        err = bt_enable(NULL);
        if (err) {
            LOG_ERR("Bluetooth init failed (err %d)", err);
            return;
        }
        LOG_INF("Bluetooth initialized");

        /* Register connection callbacks */
        err = bt_conn_cb_register(&connection_callbacks);
        if (err) {
            LOG_ERR("Connection callback register failed (err %d)", err);
        }

        /* Start advertising */
        err = bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        if (err) {
            LOG_ERR("Advertising failed to start (err %d)", err);
            return;
        }
        LOG_INF("Advertising successfully started");

        /* Main loop: Optionally blink an LED to indicate the app is running */
        while (1) {
            dk_set_led(RUN_STATUS_LED, 1);
            k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
            dk_set_led(RUN_STATUS_LED, 0);
            k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
        }
    }

    And Controller code acting as central

    //*
     * Button Controller (Central) with Button-Triggered Scanning and Status Messages
     *
     * On button 1 press, the device will begin scanning for peripherals advertising the Nordic
     * LED Button Service (LBS) UUID. If no connection is made, the system will print a message
     * every second indicating that it is still scanning.
     *
     * Once a connection is established, scanning stops.
     */

     #include <zephyr/kernel.h>
     #include <zephyr/logging/log.h>
     #include <zephyr/bluetooth/bluetooth.h>
     #include <zephyr/bluetooth/conn.h>
     #include <zephyr/bluetooth/uuid.h>
     #include <zephyr/bluetooth/gatt.h>
     #include <zephyr/bluetooth/addr.h>  // For bt_addr_le_to_str()
     #include <dk_buttons_and_leds.h>
     #include <bluetooth/services/lbs.h>
     
     LOG_MODULE_REGISTER(button_controller, LOG_LEVEL_INF);
     
     #define USER_BUTTON             DK_BTN1_MSK
     #define RUN_STATUS_LED          DK_LED1
     #define CONNECTION_STATUS_LED   DK_LED2
     #define SCAN_STATUS_LED         DK_LED3  // (optional) you may use another LED for scan status
     #define STATUS_PRINT_INTERVAL   1000     // Print status every 1000ms
     
     static struct bt_conn *default_conn = NULL;
     static bool scanning_active = false;
     
     /* Define the 128-bit UUID for the Nordic LBS service.
      * This must match the UUID used by the Receiver.
      */
     static const struct bt_uuid_128 lbs_uuid =
         BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123));
     
     /* Callback for parsing advertisement data.
      * If a 128-bit UUID matching our LBS service is found, set *found to true.
      */
     static bool adv_data_cb(struct bt_data *data, void *user_data)
     {
         bool *found = user_data;
     
         if ((data->type == BT_DATA_UUID128_ALL) ||
             (data->type == BT_DATA_UUID128_SOME)) {
             if (data->data_len == 16) {
                 if (!memcmp(data->data, lbs_uuid.val, 16)) {
                     *found = true;
                     return false;  // Stop parsing further fields.
                 }
             }
         }
         return true;  // Continue parsing.
     }
     
     /* Scanning callback: called for every advertisement packet received.
      * We filter for connectable advertisements (using the HCI-defined types)
      * and check if they contain the LBS service UUID.
      */
     static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
                  struct net_buf_simple *ad)
     {
         /* If already connected, ignore further advertisements */
         if (default_conn != NULL) {
             return;
         }
     
         /* Only accept connectable advertisements.
          * In the current SDK, use BT_HCI_ADV_IND and BT_HCI_ADV_DIRECT_IND.
          */
         if ((adv_type != BT_HCI_ADV_IND) &&
             (adv_type != BT_HCI_ADV_DIRECT_IND)) {
             return;
         }
     
         bool found = false;
         bt_data_parse(ad, adv_data_cb, &found);
         if (found) {
             char addr_str[BT_ADDR_LE_STR_LEN];
             bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
             LOG_INF("Found LBS peripheral: %s, RSSI %d", addr_str, rssi);
     
             /* Stop scanning since we found a match */
             int err = bt_le_scan_stop();
             if (err) {
                 LOG_ERR("Failed to stop scanning (err %d)", err);
                 return;
             }
             scanning_active = false;

             
     
             /* Create connection parameters.
              */
             const struct bt_conn_le_create_param *create_param =
                 BT_CONN_LE_CREATE_PARAM(BT_CONN_LE_CREATE_CONN,
                                       BT_GAP_SCAN_FAST_INTERVAL,
                                       BT_GAP_SCAN_FAST_WINDOW);
             const struct bt_le_conn_param *conn_param = BT_LE_CONN_PARAM_DEFAULT;
             err = bt_conn_le_create(addr, create_param, conn_param, &default_conn);
             if (err) {
                 LOG_ERR("Failed to create connection (err %d)", err);
                 /* Restart scanning if connection creation failed */
                //  err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
                 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
                 if (err) {
                     LOG_ERR("Failed to restart scanning (err %d)", err);
                 } else {
                     scanning_active = true;
                     LOG_INF("Scanning restarted");
                 }
             } else {
                 LOG_INF("Connection initiated successfully");
             }
         }
     }

     
     /* Connection callback: called when a connection is established. */
     static void on_connected(struct bt_conn *conn, uint8_t err)
     {
         if (err) {
             LOG_ERR("Connection error (err %u)", err);
             return;
         }
     
         LOG_INF("Connected");
         default_conn = bt_conn_ref(conn);
         dk_set_led(CONNECTION_STATUS_LED, 1);
         scanning_active = false;  // Stop status printing once connected.
     }
     
     /* Connection callback: called when a connection is terminated.
      * In this version, scanning is not automatically restarted.
      */
     static void on_disconnected(struct bt_conn *conn, uint8_t reason)
     {
         LOG_INF("Disconnected (reason %u)", reason);
         dk_set_led(CONNECTION_STATUS_LED, 0);
         if (default_conn) {
             bt_conn_unref(default_conn);
             default_conn = NULL;
         }
         /* Optionally, you could automatically restart scanning here,
          * but for this example, we wait for another button press.
          */
     }
     
     static struct bt_conn_cb connection_callbacks = {
         .connected = on_connected,
         .disconnected = on_disconnected,
     };
     
     /* Button callback:
      * When button 1 is pressed, start scanning if not already scanning.
      */
     static void button_changed(uint32_t button_state, uint32_t has_changed)
     {
         int err;
         bool button_event = (has_changed & USER_BUTTON) ? true : false;
         bool button_pressed = (button_state & USER_BUTTON) ? true : false;
     
         if (button_event && button_pressed) {
             if (!scanning_active) {
                 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
                //  err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);

                 if (err) {
                     LOG_ERR("Scanning failed to start (err %d)", err);
                 } else {
                     scanning_active = true;
                     LOG_INF("Scanning started by button press");
                 }
             } else {
                 LOG_INF("Already scanning");
             }
         }
     }
     
     static int init_button(void)
     {
         int err = dk_buttons_init(button_changed);
         if (err) {
             LOG_ERR("Buttons init failed (err %d)", err);
         }
         return err;
     }
     
     int main(void)
     {
         int err;
     
         LOG_INF("Starting Button Controller (Central)");
     
         /* Initialize LEDs for status indication */
         err = dk_leds_init();
         if (err) {
             LOG_ERR("LEDs init failed (err %d)", err);
             return err;
         }
     
         /* Initialize buttons */
         err = init_button();
         if (err) {
             LOG_ERR("Button init failed (err %d)", err);
             return err;
         }
     
         /* Enable Bluetooth */
         err = bt_enable(NULL);
         if (err) {
             LOG_ERR("Bluetooth init failed (err %d)", err);
             return err;
         }
         LOG_INF("Bluetooth initialized");
     
         /* Register connection callbacks */
         err = bt_conn_cb_register(&connection_callbacks);
         if (err) {
             LOG_ERR("Failed to register connection callbacks (err %d)", err);
         }
     
         /* Do not start scanning automatically.
          * Scanning will start when the user presses button 1.
          */
     
         /* Main loop: while scanning is active and no connection is established, print a status message every second */
         while (1) {
             if (scanning_active && (default_conn == NULL)) {
                 LOG_INF("Still scanning for a connection...");
             }
             /* Blink a status LED (optional) */
             dk_set_led(RUN_STATUS_LED, 1);
             k_sleep(K_MSEC(STATUS_PRINT_INTERVAL));
             dk_set_led(RUN_STATUS_LED, 0);
             k_sleep(K_MSEC(STATUS_PRINT_INTERVAL));
         }
     
         return 0;
     }
     
Reply
  • Thank you for that, I have completed the steps you mentioned and finished the courses. However I am having a problem with my current test code which should be simple. In theory, I just want to communicate between two DK's but pushing a button on one resulting in an LED on another turning on. I will attach my code for both, and if something looks obviously wrong I would appreciate any advice. I am currently unsuccessful with the part to automatically connect with each other. I can see the peripheral device in the Nordic application on my phone, and they both have the same UUID. WHen my controller is scanning, it cannot find the device.

    Receiver code (acts as peripheral)


    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/gap.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/bluetooth/addr.h>
    #include <zephyr/bluetooth/conn.h>
    #include <bluetooth/services/lbs.h>

    #include <dk_buttons_and_leds.h>

    #define USER_BUTTON DK_BTN1_MSK
    #define RUN_STATUS_LED DK_LED4
    #define CONNECTION_STATUS_LED   DK_LED2
    #define RUN_LED_BLINK_INTERVAL 1000


    struct bt_conn *my_conn = NULL;

    static const struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(
        (BT_LE_ADV_OPT_CONNECTABLE |
         BT_LE_ADV_OPT_USE_IDENTITY), /* Connectable advertising and use identity address */
        BT_GAP_ADV_FAST_INT_MIN_1, /* 0x30 units, 48 units, 30ms */
        BT_GAP_ADV_FAST_INT_MAX_1, /* 0x60 units, 96 units, 60ms */
        NULL); /* Set to NULL for undirected advertising */

    LOG_MODULE_REGISTER(led_receiver, LOG_LEVEL_INF);

    /* Advertising data */
    #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
    #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

    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, DEVICE_NAME, DEVICE_NAME_LEN),
    };

    static const struct bt_data sd[] = {
        BT_DATA_BYTES(BT_DATA_UUID128_ALL,
                  BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123)),
    };

    /* --- LED write callback ---
     */
    static void led_write_cb(uint8_t led_state)
    {
        LOG_INF("LED write callback: led_state = %d", led_state);
        if (led_state) {
            dk_set_led(RUN_STATUS_LED, 1);
        } else {
            dk_set_led(RUN_STATUS_LED, 0);
        }
    }

    /* Callbacks */
    void on_connected(struct bt_conn *conn, uint8_t err)
    {
        if (err) {
            LOG_ERR("Connection error %d", err);
            return;
        }
        LOG_INF("Connected");
        my_conn = bt_conn_ref(conn);
        dk_set_led(CONNECTION_STATUS_LED, 1);
    }

    void on_disconnected(struct bt_conn *conn, uint8_t reason)
    {
        LOG_INF("Disconnected. Reason %d", reason);
        dk_set_led(CONNECTION_STATUS_LED, 0);
        bt_conn_unref(my_conn);
    }

    struct bt_conn_cb connection_callbacks = {
        .connected          = on_connected,
        .disconnected       = on_disconnected,
    };

    void main(void)
    {
        int err;

        LOG_INF("Starting LED Receiver (Peripheral)");

        /* Initialize the DK LEDs */
        err = dk_leds_init();
        if (err) {
            LOG_ERR("LEDs init failed (err %d)", err);
            return;
        }

        /* Initialize the LED Button Service (LBS) with your LED write callback.
         * The LBS service will register a GATT write callback on its LED characteristic.
         */
        err = bt_lbs_init(led_write_cb);
        if (err) {
            LOG_ERR("LBS init failed (err %d)", err);
            return;
        }

        /* Enable Bluetooth */
        err = bt_enable(NULL);
        if (err) {
            LOG_ERR("Bluetooth init failed (err %d)", err);
            return;
        }
        LOG_INF("Bluetooth initialized");

        /* Register connection callbacks */
        err = bt_conn_cb_register(&connection_callbacks);
        if (err) {
            LOG_ERR("Connection callback register failed (err %d)", err);
        }

        /* Start advertising */
        err = bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        if (err) {
            LOG_ERR("Advertising failed to start (err %d)", err);
            return;
        }
        LOG_INF("Advertising successfully started");

        /* Main loop: Optionally blink an LED to indicate the app is running */
        while (1) {
            dk_set_led(RUN_STATUS_LED, 1);
            k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
            dk_set_led(RUN_STATUS_LED, 0);
            k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
        }
    }

    And Controller code acting as central

    //*
     * Button Controller (Central) with Button-Triggered Scanning and Status Messages
     *
     * On button 1 press, the device will begin scanning for peripherals advertising the Nordic
     * LED Button Service (LBS) UUID. If no connection is made, the system will print a message
     * every second indicating that it is still scanning.
     *
     * Once a connection is established, scanning stops.
     */

     #include <zephyr/kernel.h>
     #include <zephyr/logging/log.h>
     #include <zephyr/bluetooth/bluetooth.h>
     #include <zephyr/bluetooth/conn.h>
     #include <zephyr/bluetooth/uuid.h>
     #include <zephyr/bluetooth/gatt.h>
     #include <zephyr/bluetooth/addr.h>  // For bt_addr_le_to_str()
     #include <dk_buttons_and_leds.h>
     #include <bluetooth/services/lbs.h>
     
     LOG_MODULE_REGISTER(button_controller, LOG_LEVEL_INF);
     
     #define USER_BUTTON             DK_BTN1_MSK
     #define RUN_STATUS_LED          DK_LED1
     #define CONNECTION_STATUS_LED   DK_LED2
     #define SCAN_STATUS_LED         DK_LED3  // (optional) you may use another LED for scan status
     #define STATUS_PRINT_INTERVAL   1000     // Print status every 1000ms
     
     static struct bt_conn *default_conn = NULL;
     static bool scanning_active = false;
     
     /* Define the 128-bit UUID for the Nordic LBS service.
      * This must match the UUID used by the Receiver.
      */
     static const struct bt_uuid_128 lbs_uuid =
         BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123));
     
     /* Callback for parsing advertisement data.
      * If a 128-bit UUID matching our LBS service is found, set *found to true.
      */
     static bool adv_data_cb(struct bt_data *data, void *user_data)
     {
         bool *found = user_data;
     
         if ((data->type == BT_DATA_UUID128_ALL) ||
             (data->type == BT_DATA_UUID128_SOME)) {
             if (data->data_len == 16) {
                 if (!memcmp(data->data, lbs_uuid.val, 16)) {
                     *found = true;
                     return false;  // Stop parsing further fields.
                 }
             }
         }
         return true;  // Continue parsing.
     }
     
     /* Scanning callback: called for every advertisement packet received.
      * We filter for connectable advertisements (using the HCI-defined types)
      * and check if they contain the LBS service UUID.
      */
     static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
                  struct net_buf_simple *ad)
     {
         /* If already connected, ignore further advertisements */
         if (default_conn != NULL) {
             return;
         }
     
         /* Only accept connectable advertisements.
          * In the current SDK, use BT_HCI_ADV_IND and BT_HCI_ADV_DIRECT_IND.
          */
         if ((adv_type != BT_HCI_ADV_IND) &&
             (adv_type != BT_HCI_ADV_DIRECT_IND)) {
             return;
         }
     
         bool found = false;
         bt_data_parse(ad, adv_data_cb, &found);
         if (found) {
             char addr_str[BT_ADDR_LE_STR_LEN];
             bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
             LOG_INF("Found LBS peripheral: %s, RSSI %d", addr_str, rssi);
     
             /* Stop scanning since we found a match */
             int err = bt_le_scan_stop();
             if (err) {
                 LOG_ERR("Failed to stop scanning (err %d)", err);
                 return;
             }
             scanning_active = false;

             
     
             /* Create connection parameters.
              */
             const struct bt_conn_le_create_param *create_param =
                 BT_CONN_LE_CREATE_PARAM(BT_CONN_LE_CREATE_CONN,
                                       BT_GAP_SCAN_FAST_INTERVAL,
                                       BT_GAP_SCAN_FAST_WINDOW);
             const struct bt_le_conn_param *conn_param = BT_LE_CONN_PARAM_DEFAULT;
             err = bt_conn_le_create(addr, create_param, conn_param, &default_conn);
             if (err) {
                 LOG_ERR("Failed to create connection (err %d)", err);
                 /* Restart scanning if connection creation failed */
                //  err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
                 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
                 if (err) {
                     LOG_ERR("Failed to restart scanning (err %d)", err);
                 } else {
                     scanning_active = true;
                     LOG_INF("Scanning restarted");
                 }
             } else {
                 LOG_INF("Connection initiated successfully");
             }
         }
     }

     
     /* Connection callback: called when a connection is established. */
     static void on_connected(struct bt_conn *conn, uint8_t err)
     {
         if (err) {
             LOG_ERR("Connection error (err %u)", err);
             return;
         }
     
         LOG_INF("Connected");
         default_conn = bt_conn_ref(conn);
         dk_set_led(CONNECTION_STATUS_LED, 1);
         scanning_active = false;  // Stop status printing once connected.
     }
     
     /* Connection callback: called when a connection is terminated.
      * In this version, scanning is not automatically restarted.
      */
     static void on_disconnected(struct bt_conn *conn, uint8_t reason)
     {
         LOG_INF("Disconnected (reason %u)", reason);
         dk_set_led(CONNECTION_STATUS_LED, 0);
         if (default_conn) {
             bt_conn_unref(default_conn);
             default_conn = NULL;
         }
         /* Optionally, you could automatically restart scanning here,
          * but for this example, we wait for another button press.
          */
     }
     
     static struct bt_conn_cb connection_callbacks = {
         .connected = on_connected,
         .disconnected = on_disconnected,
     };
     
     /* Button callback:
      * When button 1 is pressed, start scanning if not already scanning.
      */
     static void button_changed(uint32_t button_state, uint32_t has_changed)
     {
         int err;
         bool button_event = (has_changed & USER_BUTTON) ? true : false;
         bool button_pressed = (button_state & USER_BUTTON) ? true : false;
     
         if (button_event && button_pressed) {
             if (!scanning_active) {
                 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
                //  err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);

                 if (err) {
                     LOG_ERR("Scanning failed to start (err %d)", err);
                 } else {
                     scanning_active = true;
                     LOG_INF("Scanning started by button press");
                 }
             } else {
                 LOG_INF("Already scanning");
             }
         }
     }
     
     static int init_button(void)
     {
         int err = dk_buttons_init(button_changed);
         if (err) {
             LOG_ERR("Buttons init failed (err %d)", err);
         }
         return err;
     }
     
     int main(void)
     {
         int err;
     
         LOG_INF("Starting Button Controller (Central)");
     
         /* Initialize LEDs for status indication */
         err = dk_leds_init();
         if (err) {
             LOG_ERR("LEDs init failed (err %d)", err);
             return err;
         }
     
         /* Initialize buttons */
         err = init_button();
         if (err) {
             LOG_ERR("Button init failed (err %d)", err);
             return err;
         }
     
         /* Enable Bluetooth */
         err = bt_enable(NULL);
         if (err) {
             LOG_ERR("Bluetooth init failed (err %d)", err);
             return err;
         }
         LOG_INF("Bluetooth initialized");
     
         /* Register connection callbacks */
         err = bt_conn_cb_register(&connection_callbacks);
         if (err) {
             LOG_ERR("Failed to register connection callbacks (err %d)", err);
         }
     
         /* Do not start scanning automatically.
          * Scanning will start when the user presses button 1.
          */
     
         /* Main loop: while scanning is active and no connection is established, print a status message every second */
         while (1) {
             if (scanning_active && (default_conn == NULL)) {
                 LOG_INF("Still scanning for a connection...");
             }
             /* Blink a status LED (optional) */
             dk_set_led(RUN_STATUS_LED, 1);
             k_sleep(K_MSEC(STATUS_PRINT_INTERVAL));
             dk_set_led(RUN_STATUS_LED, 0);
             k_sleep(K_MSEC(STATUS_PRINT_INTERVAL));
         }
     
         return 0;
     }
     
Children
Related