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

How to add a GPIO (digital input) to ble_app_uart_c example?

Hello,

in our project we have a nRF52840DK as central and a BMD-300 (contains nRF52832 chip) as peripheral. The software on the nRF52840DK is based on the ble_app_uart_c example. The software on the BMD-300 is based on the ble_app_uart example. The BMD-300 module sends data to the nRF52840DK via NUS. The nRF52840DK writes the received data by NUS into the COM-Port. The data from the COM-Port gets proccessed on a pc. This all works fine. We are using SDKv17.

Now we want to add a GPIO(digital input) to the ble_app_uart_c example on the nRF52840DK. If this digital input is high, a short string should be written into the COM-Port in addition to the data which is received by NUS and written into the COM-Port anyways.

We hope that you help us, by answering our questions:

1. How can we add a GPIO as digital input to the ble_app_uart_c example?

2. How can we read out this digital input?

3. How can we write a string into the COM-Port as reaction to a "high" on the digital input?

Thank you very much in advance.

Parents
  • Hi,

    This depends on whether or not you require the GPIO to trigger an interrupt when the pin is set/cleared. If you only want to read the state of the pin in the code, you can use the GPIO abstraction functions:

    1. nrf_gpio_cfg_input (uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
    2. uint32_t pin_state = nrf_gpio_pin_read (uint32_t pin_number)
    3. If you want the string to be written to UART when the pin becomes high, regardless of what happens in the NUS part of the application, you can use GPIOTE to trigger an interrupt, where you can send the string to UART (similar to how it is done in nus_data_handler - by calling app_uart_put). An example of this can be seen in the Pin Change Interrupt Example. If you only want to send the string when nus_data_handler is called and the pin is set high, just do and if where you check if the pin is set and send the data (not tested):
      if(nrf_gpio_pin_read(uint32_t pin_number) == 1)
      {
      	uint8_t pin_string[] = "GPIO is high!\r\n";
      	uint8_t i = 0;
      	do
      	{
      		while(app_uart_put(pin_string[i]) == NRF_ERROR_BUSY);
      		i++;
      	} while(pin_string[i-1] != '\n');
      }

    Best regards,
    Jørgen

Reply
  • Hi,

    This depends on whether or not you require the GPIO to trigger an interrupt when the pin is set/cleared. If you only want to read the state of the pin in the code, you can use the GPIO abstraction functions:

    1. nrf_gpio_cfg_input (uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
    2. uint32_t pin_state = nrf_gpio_pin_read (uint32_t pin_number)
    3. If you want the string to be written to UART when the pin becomes high, regardless of what happens in the NUS part of the application, you can use GPIOTE to trigger an interrupt, where you can send the string to UART (similar to how it is done in nus_data_handler - by calling app_uart_put). An example of this can be seen in the Pin Change Interrupt Example. If you only want to send the string when nus_data_handler is called and the pin is set high, just do and if where you check if the pin is set and send the data (not tested):
      if(nrf_gpio_pin_read(uint32_t pin_number) == 1)
      {
      	uint8_t pin_string[] = "GPIO is high!\r\n";
      	uint8_t i = 0;
      	do
      	{
      		while(app_uart_put(pin_string[i]) == NRF_ERROR_BUSY);
      		i++;
      	} while(pin_string[i-1] != '\n');
      }

    Best regards,
    Jørgen

Children
  • Hello,

    thank you very much for your answer.

    I was able to read out the state of the digital pin and send my string as a response via UART (COM-Port). This works fine.

    We would prefer to read out the rising edge of the digital pin instead of only the state of the digital pin.

    Can you provide us some information, how to do/implement this correctly?

    Thank you very much in advance.

  • As I mentioned, this is shown in the Pin Change Interrupt example.

    If you want to detect the transition from low to high on the GPIO, the simples code would be something like this:

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        //Send UART string here
    }
    /**
     * @brief Function for configuring: PIN_IN pin for input, PIN_OUT pin for output,
     * and configures GPIOTE to give an interrupt on pin change.
     */
    static void gpio_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
        in_config.pull = NRF_GPIO_PIN_PULLDOWN;
    
        err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }

Related