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

Setting external GPIO interrupt with the USB dongle

Hi,

I'm very new to c programming and your hardware. Please excuse my novice questions.

I'm making a rotary braille display using nRF52840 dongle (PCA10059) as it's brain. The dongle will take interrupt input from phototransistors to trigger braille dot outputs according to values at index position on an array of braille code in the memory.

My previous prototype is Raspberry Pi-based and runs on Python as in this video

.

I see nRF52840 Dongle can greatly reduce the size of the braille display prototype.

Now I cannot get any external pin other than the on board ones to receive or output some voltage. What am I doing wrong?

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "boards.h"
#include "pca10059.h"
#include "app_timer.h"
#include "app_button.h"
#include "nrf_sdh.h"

// Rotation sensor inputs
// Encoder trigger
#define ENC_IN      NRF_GPIO_PIN_MAP(0,10)
#define ENC_DIR     NRF_GPIO_PIN_DIR_INPUT
#define ENC_PULL    NRF_GPIO_PIN_PULLUP
// Direction detect
#define DIR_IN      NRF_GPIO_PIN_MAP(0,13)
#define DIR_DIR     NRF_GPIO_PIN_DIR_INPUT
#define DIR_PULL    NRF_GPIO_PIN_PULLUP

// Buttons input
//#define BMIDA_IN      NRF_GPIO_PIN_MAP(0,24)
//#define BMIDA_DIR     NRF_GPIO_PIN_DIR_INPUT
//#define BMIDA_PULL    NRF_GPIO_PIN_PULLUP
//#define BMIDB_IN      NRF_GPIO_PIN_MAP(1,00)
//#define BMIDB_DIR     NRF_GPIO_PIN_DIR_INPUT
//#define BMIDB_PULL    NRF_GPIO_PIN_PULLUP
//#define BTHMA_IN      NRF_GPIO_PIN_MAP(0,09)
//#define BTHMA_DIR     NRF_GPIO_PIN_DIR_INPUT
//#define BTHMA_PULL    NRF_GPIO_PIN_PULLUP
//#define BTHMB_IN      NRF_GPIO_PIN_MAP(0,10)
//#define BTHMB_DIR     NRF_GPIO_PIN_DIR_INPUT
//#define BTHMB_PULL    NRF_GPIO_PIN_PULLUP

// Actuator output Right
#define ACT_1       NRF_GPIO_PIN_MAP(0,22)
#define A1_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_2       NRF_GPIO_PIN_MAP(0,20)
#define A2_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_3       NRF_GPIO_PIN_MAP(0,17)
#define A3_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_4       NRF_GPIO_PIN_MAP(0,15)
#define A4_DIR     NRF_GPIO_PIN_DIR_OUTPUT

// Actuator output Left
#define ACT_5       NRF_GPIO_PIN_MAP(0,31)
#define A5_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_6       NRF_GPIO_PIN_MAP(0,29)
#define A6_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_7       NRF_GPIO_PIN_MAP(0,02)
#define A7_DIR     NRF_GPIO_PIN_DIR_OUTPUT
#define ACT_8       NRF_GPIO_PIN_MAP(1,15)
#define A8_DIR     NRF_GPIO_PIN_DIR_OUTPUT

// Sample Braille Code, one array for each dot out of 8
// Left column
bool BST_L1[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
bool BST_L2[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
bool BST_L3[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
bool BST_L4[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };

// Right column
bool BST_R1[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
bool BST_R2[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
bool BST_R3[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
bool BST_R4[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };

// Define size of braille
size_t bst_len = ARRAY_SIZE(BST_L1);
size_t i = 0;

// Interrupt handler
static void button_handler(uint8_t pin, uint8_t action) {
    // When encoder input is detected rotating to the right
    if (pin == ENC_IN) {
        if (ENC_IN == 0 && DIR_IN == 0) {
            // Output braille left column
            nrf_gpio_pin_write(ACT_1,BST_L1[i]);
            nrf_gpio_pin_write(ACT_2,BST_L2[i]);
            nrf_gpio_pin_write(ACT_3,BST_L3[i]);
            nrf_gpio_pin_write(ACT_4,BST_L4[i]);
            nrf_gpio_pin_write(ACT_5,0);
            nrf_gpio_pin_write(ACT_6,0);
            nrf_gpio_pin_write(ACT_7,0);
            nrf_gpio_pin_write(ACT_8,0);
            // Direction light Green
            nrf_gpio_pin_write(LED2_G,0);
            nrf_gpio_pin_write(LED2_R,1);
        } else if (ENC_IN == 1 && DIR_IN == 1) {
            // Output braille right column
            nrf_gpio_pin_write(ACT_1,BST_R1[i]);
            nrf_gpio_pin_write(ACT_2,BST_R2[i]);
            nrf_gpio_pin_write(ACT_3,BST_R3[i]);
            nrf_gpio_pin_write(ACT_4,BST_R4[i]);
            nrf_gpio_pin_write(ACT_5,0);
            nrf_gpio_pin_write(ACT_6,0);
            nrf_gpio_pin_write(ACT_7,0);
            nrf_gpio_pin_write(ACT_8,0);
            // Direction light Red
            nrf_gpio_pin_write(LED2_G,1);
            nrf_gpio_pin_write(LED2_R,0);
            // Index increment, reset if end of string
            i++;
            if (i == bst_len) {
                i = 0;
            }
        }
    }
    // When white button is pushed
    if (pin == BUTTON_1) {
        nrf_gpio_pin_toggle(LED1_G);
    }
}

/**
 * @brief Function for application main entry.
 */
int main() {
    /* Configure board. */
    
    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
    app_timer_init();
    nrf_sdh_enable_request();
    static app_button_cfg_t buttons[] = {
        {ENC_IN, false, ENC_PULL, button_handler},
        {BUTTON_1, false, ENC_PULL, button_handler}
    };
    app_button_init(buttons, ARRAY_SIZE(buttons), 50);
    app_button_enable();
    // Blink an LED just to check if the program is running
    while (true) {
        nrf_gpio_pin_toggle(LED2_B);
        nrf_delay_ms(1000);
    }

}

/**
 *@}
 **/

Thank you,

Song

  • Hi,

    I see you haven't configure the pins as output or input pins using nrf_gpio_cfg_input() or nrf_gpio_cfg_output(), this may be the issue. 

    Best regards,

    Marjeris

  • Thank you Marjeris,

    I put it in main() and then I could measure some changing voltages.

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf_delay.h"
    #include "boards.h"
    #include "pca10059.h"
    #include "app_timer.h"
    #include "app_button.h"
    #include "nrf_sdh.h"
    
    // Rotation sensor inputs
    // Encoder trigger
    #define ENC_IN      NRF_GPIO_PIN_MAP(0,10)
    #define ENC_PULL    NRF_GPIO_PIN_PULLUP
    // Direction detect
    #define DIR_IN      NRF_GPIO_PIN_MAP(0,13)
    #define DIR_PULL    NRF_GPIO_PIN_PULLUP
    
    // Buttons input
    //#define BMIDA_IN      NRF_GPIO_PIN_MAP(0,24)
    //#define BMIDA_DIR     NRF_GPIO_PIN_DIR_INPUT
    //#define BMIDA_PULL    NRF_GPIO_PIN_PULLUP
    //#define BMIDB_IN      NRF_GPIO_PIN_MAP(1,00)
    //#define BMIDB_DIR     NRF_GPIO_PIN_DIR_INPUT
    //#define BMIDB_PULL    NRF_GPIO_PIN_PULLUP
    //#define BTHMA_IN      NRF_GPIO_PIN_MAP(0,09)
    //#define BTHMA_DIR     NRF_GPIO_PIN_DIR_INPUT
    //#define BTHMA_PULL    NRF_GPIO_PIN_PULLUP
    //#define BTHMB_IN      NRF_GPIO_PIN_MAP(0,10)
    //#define BTHMB_DIR     NRF_GPIO_PIN_DIR_INPUT
    //#define BTHMB_PULL    NRF_GPIO_PIN_PULLUP
    
    // Actuator output Right
    #define ACT_5       NRF_GPIO_PIN_MAP(0,22)
    #define ACT_6       NRF_GPIO_PIN_MAP(0,20)
    #define ACT_7       NRF_GPIO_PIN_MAP(0,17)
    #define ACT_8       NRF_GPIO_PIN_MAP(0,15)
    
    // Actuator output Left
    #define ACT_1       NRF_GPIO_PIN_MAP(0,31)
    #define ACT_2       NRF_GPIO_PIN_MAP(0,29)
    #define ACT_3       NRF_GPIO_PIN_MAP(0,02)
    #define ACT_4       NRF_GPIO_PIN_MAP(1,15)
    
    // Sample Braille Code
    // Left column
    bool BST_L1[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
    bool BST_L2[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
    bool BST_L3[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
    bool BST_L4[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
    
    // Right column
    bool BST_R1[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
    bool BST_R2[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
    bool BST_R3[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
    bool BST_R4[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
    
    // Define size of braille
    size_t bst_len = ARRAY_SIZE(BST_L1);
    size_t i = 0;
    
    // Interrupt handler
    static void button_handler(uint8_t pin, uint8_t action) {
        // When encoder input is detected rotating to the right
        if (pin == ENC_IN) {
            if (ENC_IN == 0 && DIR_IN == 0) {
                // Output braille left column
                nrf_gpio_pin_write(ACT_1,BST_L1[i]);
                nrf_gpio_pin_write(ACT_2,BST_L2[i]);
                nrf_gpio_pin_write(ACT_3,BST_L3[i]);
                nrf_gpio_pin_write(ACT_4,BST_L4[i]);
                nrf_gpio_pin_write(ACT_5,0);
                nrf_gpio_pin_write(ACT_6,0);
                nrf_gpio_pin_write(ACT_7,0);
                nrf_gpio_pin_write(ACT_8,0);
                // Direction light Green
                nrf_gpio_pin_write(LED2_G,0);
                nrf_gpio_pin_write(LED2_R,1);
            } else if (ENC_IN == 1 && DIR_IN == 1) {
                // Output braille right column
                nrf_gpio_pin_write(ACT_1,BST_R1[i]);
                nrf_gpio_pin_write(ACT_2,BST_R2[i]);
                nrf_gpio_pin_write(ACT_3,BST_R3[i]);
                nrf_gpio_pin_write(ACT_4,BST_R4[i]);
                nrf_gpio_pin_write(ACT_5,0);
                nrf_gpio_pin_write(ACT_6,0);
                nrf_gpio_pin_write(ACT_7,0);
                nrf_gpio_pin_write(ACT_8,0);
                // Direction light Red
                nrf_gpio_pin_write(LED2_G,1);
                nrf_gpio_pin_write(LED2_R,0);
                // Index increment, reset if end of string
                i++;
                if (i == bst_len) {
                    i = 0;
                }
            }
        }
        // When white button is pushed
        if (pin == BUTTON_1) {
            nrf_gpio_pin_toggle(LED1_G);
        }
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main() {
        /* Configure board. */
        
        bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
        nrf_gpio_cfg_input(ENC_IN, ENC_PULL);
        nrf_gpio_cfg_input(DIR_IN, DIR_PULL);
        nrf_gpio_cfg_output(ACT_1);
        nrf_gpio_cfg_output(ACT_2);
        nrf_gpio_cfg_output(ACT_3);
        nrf_gpio_cfg_output(ACT_4);
        nrf_gpio_cfg_output(ACT_5);
        nrf_gpio_cfg_output(ACT_6);
        nrf_gpio_cfg_output(ACT_7);
        nrf_gpio_cfg_output(ACT_8);
        app_timer_init();
        nrf_sdh_enable_request();
        static app_button_cfg_t buttons[] = {
            {ENC_IN, false, ENC_PULL, button_handler},
            {BUTTON_1, false, ENC_PULL, button_handler}
        };
        app_button_init(buttons, ARRAY_SIZE(buttons), 50);
        app_button_enable();
        // Blink the Blue LED if the program is running
        while (true) {
            nrf_gpio_pin_toggle(LED2_B);
            nrf_delay_ms(1000);
        }
    
    }
    
    /**
     *@}
     **/

    Yours,

    Song

  • Some more questions.

    I used the wrong encoder input port in the first question they should be 1.10 and 1.13, not 0.10 and 0.13.

    Now even after I corrected the port and enabled pull-up to test pin-to-ground switch, input voltage is always 0. What is wrong now?

    The encoder input from phototransistor is measured between 1.9 to 2.1 V when no-block and blocked respectively. How can I set the pin to detect voltage change event? Which example should I look at?

    Thank you,

Related