This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to remotely "check" NRF-51 BLE connectivity?

>I will start by prefacing that I'm not by any means an engineer and my only knowledge with BLE/embedded systems comes from curiosity, side projects and trial/error<

Story:

I live in a small condominium where we have 1 big metal gate to get in/out. In the last few months we've been facing many problems with the garage parking administrator, so I decided to create a side project to fix it. I ended up choosing a Particle Electron plugged to a 4-Channel General Purpose SPDT Relay Shield + 12V & 5V converters, that are placed inside the gate in a circuit box, so I could have remote access via a JS remote opener web app. On the outside, in another circuit box, I put an NRF-51 DK for BLE connection so we could open/close the gate without relying on a cellular or wifi connection (that are quite poor in my area).

Problem:

For a few months, the solution worked great and we were quite satisfied with it, but the last few weeks the NRF-51 is getting on debug mode randomly and to fix it I need to go to the garage and physically restart it, which is bothersome. I couldn't find any explanation or proper solution for it, so I input a watchdog reset file in it and apparently it's fine now, but I still think it's not the ideal solution. I would like to "track" the BLE connectivity or be sure that the NRF-51 is "alive".

Questions:

- There's a way to track the NRF-51 DK BLE connectivity remotely? If yes, is it possible via the particle cloud (I don't know, maybe via a device with BLE too like the Boron being use as a peripheral?)?

- If this is not possible, how could I make sure remotely that the NRF51 is "alive" and responding?

Obs: I searched a few similar issues and always ended up in "mesh" solutions, which I'm not sure if it's what I'm looking for since I would like to rely on Particle and NRF devices since I have a few lying around at home, and Particle's mesh support is being shut down by the end of the year (apparently).

Thank you very much for your help!

  • Hi,

    the NRF-51 is getting on debug mode randomly

    What do you mean by "debug mode" ? You mean that the nRF-51 just becomes unresponsive ? Is the firmware running on the device compiled with "DEBUG" preprocessor symbol defined ?

    - There's a way to track the NRF-51 DK BLE connectivity remotely? If yes, is it possible via the particle cloud (I don't know, maybe via a device with BLE too like the Boron being use as a peripheral?)?

    - If this is not possible, how could I make sure remotely that the NRF51 is "alive" and responding?

     Yes, something like the Boron could possibly be used for this, since if the nRF51-DK loses BLE connection to the Electron, it will likely lose connection to the Boron as well. That said, I don’t know why you would want to do that, what are you trying to achieve by that? If you e.g. want to know how often the device is reset by the WDT, then it's possible to e.g. increment and save some value to flash/RAM at every reboot, and then advertise this value. Overall, the Watchdog timer is a good solution to keep the device, as you say, "alive" and responding, but if you want to eliminate this issue, then you would likely need to try to recreate the issue while debugging in you preferred IDE, and check if there is some functions that returns any error-codes, if code gets stuck somewhere, etc.

  • > What do you mean by "debug mode"? Do you mean that the nRF-51 just becomes unresponsive?

    Yes, the NRF stops working (gets unresponsive), and to fix it I need to go to the garage and turn on/off manually. When I do it I can reach it again.

    > Is the firmware running on the device compiled with "DEBUG" preprocessor symbol defined?

    Yes, it is.

    > That said, I don’t know why you would want to do that, what are you trying to achieve by that?

    My main goal here was to create a gate opener using only cellular connection and Bluetooth to which I could have remote control of both (so I wouldn't need to physically reboot or update any device). The gate would be mainly triggered by BLE connection (open/close) via the NRF-51 and if someone couldn't open the gate for any reason, I could rely on the Boron/Electron for cellular connection and trigger the gate online and remotely.

     

    Thank you for your answer!

  • Hi,

    > Is the firmware running on the device compiled with "DEBUG" preprocessor symbol defined?

    Yes, it is.

    This is likely the reason the device becomes unresponsive then.

    Some function has returned an error-code, or you get an assert somewhere in the code.

    The app_error_fault_handler() will be called. If DEBUG is not defined, the system will reset.

    __WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
        NRF_LOG_ERROR("Fatal\r\n");
        NRF_LOG_FINAL_FLUSH();
        // On assert, the system can only recover with a reset.
    #ifndef DEBUG
        NVIC_SystemReset();
    #else
        app_error_save_and_stop(id, pc, info);
    #endif // DEBUG

    If DEBUG is defined, you will then enter app_error_save_and_stop()

    void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
    {
        /* static error variables - in order to prevent removal by optimizers */
        static volatile struct
        {
            uint32_t        fault_id;
            uint32_t        pc;
            uint32_t        error_info;
            assert_info_t * p_assert_info;
            error_info_t  * p_error_info;
            ret_code_t      err_code;
            uint32_t        line_num;
            const uint8_t * p_file_name;
        } m_error_data = {0};
    
        // The following variable helps Keil keep the call stack visible, in addition, it can be set to
        // 0 in the debugger to continue executing code after the error check.
        volatile bool loop = true;
        UNUSED_VARIABLE(loop);
    
        m_error_data.fault_id   = id;
        m_error_data.pc         = pc;
        m_error_data.error_info = info;
    
        switch (id)
        {
            case NRF_FAULT_ID_SDK_ASSERT:
                m_error_data.p_assert_info = (assert_info_t *)info;
                m_error_data.line_num      = m_error_data.p_assert_info->line_num;
                m_error_data.p_file_name   = m_error_data.p_assert_info->p_file_name;
                break;
    
            case NRF_FAULT_ID_SDK_ERROR:
                m_error_data.p_error_info = (error_info_t *)info;
                m_error_data.err_code     = m_error_data.p_error_info->err_code;
                m_error_data.line_num     = m_error_data.p_error_info->line_num;
                m_error_data.p_file_name  = m_error_data.p_error_info->p_file_name;
                break;
        }
    
        UNUSED_VARIABLE(m_error_data);
    
        // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
        __disable_irq();
        while (loop);
    
        __enable_irq();
    }

    and you will be stuck in the while-loop.

Related