examples of simple peripheral/central ble transmission nrf52 series

I am very familiar with PICs and some atmega stuff, just graduated university ee and the project I am working on requires transmitting very small amounts of data continuously via ble protocol. Actually transmitting real time gyroscope data. Nrf modules seemed the easiest/cheapest for our purpose and decided we would most likely end up going with someones 52 series module. I have been playing around awhile with the nordic 52 development board however I am finding the learning curve fairly steep with zephyr. I can do basic stuff, gpio, pwm, interrupts etc but am struggling with bluetooth. Would it be possible to get an example of a central device and peripheral device with a custom service and characteristic 128, that simply sends or receives 24 or more bits of data at a time.   I'm really trying to learn this and just feel myself lost, thanks.  I have been through many of the peripheral and central zephyr examples.

Parents
  • Hi,

    Yes, you may keep this ticket open if you would like so for follow up questions which are related to the topic in this ticket. If you have new questions, I will of course try to reply and answer to them, but I would recommend to create new tickets for unique questions and cases.

    And also yes, I would say this type of ticket is something that is perfect as a public ticket as there are very likely more out there with the same questions and in the same situation, so go ahead and convert it if you're comfortable with that!

    Kind regards,
    Andreas

  • after much experimenting I seem to be getting this error from the second example. 

  • #include "remote.h"
    
    #define BT_UUID_MY_SERVICE      BT_UUID_DECLARE_128(MY_SERVICE_UUID)
    #define BT_UUID_MY_SERVICE_RX   BT_UUID_DECLARE_128(RX_CHARACTERISTIC_UUID)
    #define BT_UUID_MY_SERVICE_TX   BT_UUID_DECLARE_128(TX_CHARACTERISTIC_UUID)
    
    #define MAX_TRANSMIT_SIZE 240//TODO figure this out
    
    uint8_t data_rx[MAX_TRANSMIT_SIZE];
    uint8_t data_tx[MAX_TRANSMIT_SIZE];
    
    int my_service_init(void)
    {
        int err = 0;
    
        memset(&data_rx, 0, MAX_TRANSMIT_SIZE);
        memset(&data_tx, 0, MAX_TRANSMIT_SIZE);
    
        return err;
    }
    
    /* This function is called whenever the RX Characteristic has been written to by a Client */
    static ssize_t on_receive(struct bt_conn *conn,
    			  const struct bt_gatt_attr *attr,
    			  const void *buf,
    			  uint16_t len,
    			  uint16_t offset,
    			  uint8_t flags)
    {
        const uint8_t * buffer = buf;
        
    	printk("Received data, handle %d, conn %p, data: 0x", attr->handle, conn);
        for(uint8_t i = 0; i < len; i++){
            printk("%02X", buffer[i]);
        }
        printk("\n");
    
    	return len;
    }
    
    /* This function is called whenever a Notification has been sent by the TX Characteristic */
    static void on_sent(struct bt_conn *conn, void *user_data)
    {
    	ARG_UNUSED(user_data);
    
        const bt_addr_le_t * addr = bt_conn_get_dst(conn);
            
    	printk("Data sent to Address 0x %02X %02X %02X %02X %02X %02X \n", addr->a.val[0]
                                                                        , addr->a.val[1]
                                                                        , addr->a.val[2]
                                                                        , addr->a.val[3]
                                                                        , addr->a.val[4]
                                                                        , addr->a.val[5]);
    }
    
    /* This function is called whenever the CCCD register has been changed by the client*/
    void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value)
    {
        ARG_UNUSED(attr);
        switch(value)
        {
            case BT_GATT_CCC_NOTIFY: 
                // Start sending stuff!
                break;
    
            case BT_GATT_CCC_INDICATE: 
                // Start sending stuff via indications
                break;
    
            case 0: 
                // Stop sending stuff
                break;
            
            default: 
                printk("Error, CCCD has been set to an invalid value");     
        }
    }
                            
    
    /* LED Button Service Declaration and Registration */
    BT_GATT_SERVICE_DEFINE(my_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_MY_SERVICE),
    BT_GATT_CHARACTERISTIC(BT_UUID_MY_SERVICE_RX,
    			       BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
    			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, 
                       NULL, on_receive, NULL),
    BT_GATT_CHARACTERISTIC(BT_UUID_MY_SERVICE_TX,
    			       BT_GATT_CHRC_NOTIFY,
    			       BT_GATT_PERM_READ,
                       NULL, NULL, NULL),
    BT_GATT_CCC(on_cccd_changed,
            BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    );
    
    /* This function sends a notification to a Client with the provided data,
    given that the Client Characteristic Control Descripter has been set to Notify (0x1).
    It also calls the on_sent() callback if successful*/
    void my_service_send(struct bt_conn *conn, const uint8_t *data, uint16_t len)
    {
        /* 
        The attribute for the TX characteristic is used with bt_gatt_is_subscribed 
        to check whether notification has been enabled by the peer or not.
        Attribute table: 0 = Service, 1 = Primary service, 2 = RX, 3 = TX, 4 = CCC.
        */
        const struct bt_gatt_attr *attr = &my_service.attrs[3]; 
    
        struct bt_gatt_notify_params params = 
        {
            .uuid   = BT_UUID_MY_SERVICE_TX,
            .attr   = attr,
            .data   = data,
            .len    = len,
            .func   = on_sent
        };
    
        // Check whether notifications are enabled or not
        if(bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY)) 
        {
            // Send the notification
    	    if(bt_gatt_notify_cb(conn, &params))
            {
                printk("Error, unable to send notification\n");
            }
        }
        else
        {
            printk("Warning, notification not enabled on the selected attribute\n");
        }
    }

  • attached main and header below here is my prj.conf

  • Hi, 

    I will see if I can look into this error before the weekend, but I can not guarantee it as a we're running with a reduced staff in July due to the primary summer vacation period in Norway.

    In the mean while: How far did you go in the hands on exercise? And did you use the same SDK version that the hands on uses? 

    loganmeyer3 said:
    after much experimenting I seem to be getting this error from the second example

    Also for errors like this you can do some investigating with arm-none-eabi-addr2line:

    1. Check if you have arm-none-eabi-addr2line set up by running "where arm-none-eabi-addr2line" in a cmd window.
      1. This should return something like "C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2015q3\bin\arm-none-eabi-addr2line.exe"
      2. If it does not return this, then there might be some issues with the gnuarmemb path configuration
    2. Next step is to investigate what is in the R15/pc and R14/lr addresses
      1. arm-none-eabi-addr2line -e <path to _build\zephyr\zephyr.elf> <0x000211a8> for r15/pc
      2. arm-none-eabi-addr2line -e <path to _build\zephyr\zephyr.elf> <0x00018b3d> for r14/lr

    2. Should give you what function call that causes the kernel panic deep down in the stack. Remember to replace "<path to _build\zephyr\zephyr.elf>" with your actual path

    Kind regards,
    Andreas

  • thanks for the help i seem to have figured out the issue.

  • Hi,

    I am glad to hear that you figured out the issue! 

    If you found any information that might help other developers with the same issue, please feel free to share the answer in this case. Else I would like to know if I can close this ticket? You may always open a new one in case you need an answer to a new question

    Kind regards,
    Andreas

Reply Children
No Data
Related