Hi There,
New to the Forum and I have started to use the Zephyr RTOS in Visual Studio Code:
I am trying to get an Eddystone Beacon based off the nRF528323 and I am transmitting the URL Frame and the TLM frame.
I have the URL Eddystone Beacon working sending Data to the nRF Connect AP but somehow I can't seem to see the TLM Data and i just need to display the battery data. I have tried this plenty of different ways but i simply cannot see the TLM data. Any help would be great appreciated!, below is the code I am using and the prj.conf file as well as the overlay file
#include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> #include <drivers/adc.h> #include <hal/nrf_saadc.h> #include <drivers/gpio.h> #include <zephyr.h> #include <nrf.h> #include <logging/log.h> #include <sys/byteorder.h> #define ADC_RESOLUTION 10 #define ADC_GAIN ADC_GAIN_1_4 #define BATTERY_CHANNEL_ID 0 #define BATTERY_INPUT NRF_SAADC_INPUT_AIN0 #define LED_PORT DT_LABEL(DT_NODELABEL(gpio0)) // Assuming LEDs are connected to GPIO0 #define LED_PIN 15 // Pin number for the first LED #define LED_PIN_2 18 // Pin number for the second LED static uint16_t adc_sample_buffer; static const struct device *led_dev; static const struct device *adc_dev; static const struct adc_channel_cfg my_channel_cfg = { .gain = ADC_GAIN, .reference = ADC_REF_INTERNAL, .acquisition_time = ADC_ACQ_TIME_DEFAULT, .channel_id = BATTERY_CHANNEL_ID, .input_positive = BATTERY_INPUT, }; static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xAA, 0xFE), // Eddystone service UUID BT_DATA_BYTES(BT_DATA_SVC_DATA16, 0xAA, 0xFE, // Eddystone service UUID 0x10, // Eddystone-URL frame type 0xF8, // Calibrated Tx power at 0m 0x01, // URL Scheme 'http://www.' 's', 't', 'r', 'a', 't', 'a', '.', 'c', 'o', 'm'), // URL }; static int led_init(void) { led_dev = device_get_binding(LED_PORT); if (!led_dev) { printk("LED device not found\n"); return -ENODEV; } int err = gpio_pin_configure(led_dev, LED_PIN, GPIO_OUTPUT_ACTIVE); if (err) { printk("Failed to configure LED pin (err %d)\n", err); return err; } err = gpio_pin_configure(led_dev, LED_PIN_2, GPIO_OUTPUT_ACTIVE); if (err) { printk("Failed to configure LED pin 2 (err %d)\n", err); return err; } return 0; } static int adc_init(void) { adc_dev = device_get_binding(DT_LABEL(DT_NODELABEL(adc))); if (!adc_dev) { printk("ADC device not found\n"); return -ENODEV; } int err = adc_channel_setup(adc_dev, &my_channel_cfg); if (err) { printk("Failed to set up ADC channel (err %d)\n", err); return err; } return 0; } static uint16_t read_battery_voltage(void) { if (!adc_dev) { printk("ADC device not found\n"); return 0; } const struct adc_sequence sequence = { .channels = BIT(my_channel_cfg.channel_id), .buffer = &adc_sample_buffer, .buffer_size = sizeof(adc_sample_buffer), .resolution = ADC_RESOLUTION, }; int err = adc_read(adc_dev, &sequence); if (err) { printk("Failed to read ADC (err %d)\n", err); return 0; } return (adc_sample_buffer * 3300) / (1 << ADC_RESOLUTION)* (2.979 / 3.296); // return (adc_sample_buffer * 3300 * 4) / (1 << ADC_RESOLUTION); // Convert to millivolts } static void update_tlm_data(uint16_t battery_voltage) { uint8_t tlm_data[] = { // Eddystone TLM header 0xAA, 0xFE, // Eddystone UUID 0x20, // TLM frame type 0x00, // Version 0x00, 0x00, // Battery voltage (placeholder) 0x00, 0x00, // Temperature (placeholder) 0x00, 0x00, 0x00, 0x00, // PDU count (placeholder) 0x00, 0x00, 0x00, 0x00 // Time since boot (placeholder) }; // Convert battery voltage to fixed point format and place in advertising packet sys_put_be16(battery_voltage, &tlm_data[4]); // Update the advertising data const struct bt_data ad_tlm[] = { BT_DATA(BT_DATA_MANUFACTURER_DATA, tlm_data, sizeof(tlm_data)), }; int err = bt_le_adv_update_data(ad_tlm, ARRAY_SIZE(ad_tlm), NULL, 0); if (err) { printk("Failed to update advertising data (err %d)\n", err); } } void print_advertising_data(const struct bt_data *ad, size_t ad_len) { printk("Advertising Data:\n"); for (size_t i = 0; i < ad_len; i++) { printk("Type: %d, Data: ", ad[i].type); for (size_t j = 0; j < ad[i].data_len; j++) { printk("%02X ", ad[i].data[j]); } printk("\n"); } } void bt_ready(int err) { if (err) { printk("Bluetooth init failed (err %d)\n", err); return; } printk("Bluetooth initialized\n"); if (led_init()) { printk("LED init failed\n"); return; } if (adc_init()) { printk("ADC init failed\n"); return; } const struct bt_le_adv_param adv_params = { .options = BT_LE_ADV_OPT_CONNECTABLE, .interval_min = BT_GAP_ADV_FAST_INT_MIN_2, .interval_max = BT_GAP_ADV_FAST_INT_MAX_2, }; // Print advertising data for debugging print_advertising_data(ad, ARRAY_SIZE(ad)); // Start advertising err = bt_le_adv_start(&adv_params, ad, ARRAY_SIZE(ad), NULL, 0); if (err) { printk("Failed to start advertising (err %d)\n", err); return; } printk("Advertising started\n"); while (1) { // Read battery voltage and update TLM data uint16_t battery_voltage = read_battery_voltage(); printk("Battery Voltage: %d mV\n", battery_voltage); update_tlm_data(battery_voltage); // Stop advertising bt_le_adv_stop(); printk("Advertising stopped\n"); // Wait a bit to ensure advertising has stopped k_sleep(K_SECONDS(1)); // Set LED and start advertising Eddystone-URL gpio_pin_set(led_dev, LED_PIN, 1); // Turn on LED err = bt_le_adv_start(&adv_params, ad, ARRAY_SIZE(ad), NULL, 0); if (err) { printk("Advertising Eddystone-URL failed to start (err %d)\n", err); gpio_pin_set(led_dev, LED_PIN, 0); // Turn off LED if advertising fails } else { printk("Eddystone URL Advertising started\n"); k_sleep(K_SECONDS(10)); // Adjust as needed } // Ensure LED is turned off gpio_pin_set(led_dev, LED_PIN, 0); // Wait a bit before next iteration k_sleep(K_SECONDS(10)); } } void main(void) { int err = bt_enable(bt_ready); if (err) { printk("Bluetooth init failed (err %d)\n", err); return; } }
Below is my prj.conf file:
# General Bluetooth options
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_BROADCASTER=y
CONFIG_BT_DEVICE_NAME_MAX=30
CONFIG_BT_DEVICE_NAME="GAVO"
CONFIG_ADC=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y
CONFIG_LOG=y
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_BT_RX_STACK_SIZE=2048
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_SETTINGS=y
CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_GATT_SERVICE_CHANGED=y
# Security Manager Protocol (SMP) for Bluetooth
CONFIG_BT_SMP=y # Ensure this is set if BT_L2CAP_DYNAMIC_CHANNEL is used
# Logging options
CONFIG_LOG=y
# Bluetooth stack sizes
CONFIG_BT_RX_STACK_SIZE=2048
CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y
and my overlay file is also below:
&uart0 {
current-speed = <115200>;
status = "okay";
tx-pin = <6>;
rx-pin = <8>;
};