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

NUS Quiescent Power

I'm using the ble_nus_c NUS client code for a custom 1:1 data link between two embedded nodes, just pinging a few bytes of data back and forth every 3 seconds. Bonded connection. Using nrf_pwr_mgmt_run() in main(). Works a treat but the chip draws about 200uA while asleep, I would like to reduce that as client node is battery powered.

I guess this is because it is constantly listening for a value notification from the peer/periph. However in this application I only need it to listen for a specific timeslot. The client sends data once every 3 seconds, and the peer (mains powered) replies immediately, so client only needs to listen for say 10mS after it sends data. Without dropping the bonded connection.

Can anyone suggest how I would modify the NUS client code to do this?

I'm using nRF52840 (PAN1780 module), SDK 17.0.2, Nordic SES 5.34a

Parents Reply Children
  • That's great, many thanks, works very nicely.

    I still don't fully understand how the connection interval affects how each end of the NUS link decides when to send data. I don't suppose there is a tutorial on this, or any suggested reading?

  • OK, my understanding so far, please correct me if I'm wrong. Maybe of use to others. NUS uses normal central/peripheral connections. The MIN/MAX_CONN_INTERVAL is configured in peripheral, which proposes it to central during negotiation. NUS_C appears to use the MIN_CONN_INTERVAL.

    The central/client initiates each connection event, after the interval time from previous event. NUS_C sends any data it has to peripheral, using nus_rx_handle - see ble_nus_c_string_send().

    Central also checks for a notification of NUS TX characteristic from the peer/peripheral (see on_hvx() using nus_tx_handle), and handles it (raises a BLE_NUS_C_EVT_NUS_TX_EVT event).

    So basically every MIN_CONN_INTERVAL the client/central sends and receives any waiting data with the peer/peripheral. If there is no data waiting, it does an "empty" connection event, which keeps the connection alive.

    I found it would not accept a connection interval > 2000mS (this seems common, allows for a missed connection without hitting 4000mS connection timeout and dropping the connection).

    However even with just a 500mS interval my central quiescent dropped from 100uA to around 8uA - perfect

  • Yes, the central and peripheral will agree upon a fixed connection interval at which they can wake up and exchange data with each other (Note: peripherals can only request a preferred connection interval range, see Connection Parameters Negotiation). This is one of the main power saving features of the LE protocol because you only need to keep the radio active during the connection events (Bluetooth Low Energy power profiles).

    The central/client initiates each connection event, after the interval time from previous event. NUS_C sends any data it has to peripheral, using nus_rx_handle - see ble_nus_c_string_send().

    Correct, when you call ble_nus_c_string_send, the packet will become enqueued in the Softdevice's internal transfer queue and sent on the next (or current if called in an ongoing connection event) connection event.

    I found it would not accept a connection interval > 2000mS (this seems common, allows for a missed connection without hitting 4000mS connection timeout and dropping the connection).

    You may have to increase the supervision timeout. Excerpt from core spec. 5.2. , vol 6, Part B, section 4.5.2

    Connection supervision timeout (connSupervisionTimeout) is a parameter that
    defines the maximum time between two received Data Channel PDUs or
    Connected Isochronous PDUs before the connection is considered lost. The
    connSupervisionTimeout shall be a multiple of 10 ms in the range 100 ms to
    32.0 s and it shall be larger than
                      

             (1 + connSlaveLatency) * connInterval * 2.

Related