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

Unable to retrieve saved modem response - nrf52840

Hi,

So I am currently trying to connect my nrf52840 DK to aws cloud using an LTE modem. My aim is to be able to store responses from the modem and parse them appropriately to use later in a finite state machine to connect/Pub/Sub AWS IoT services.  I am currently developing on top of the "iot_lwip_mqtt_pub" example found in NRF52 DK

So my first step is to establish effective communication between the modem and the micro controller. Using the serial example in the DK, I am able to send AT commands to the modem and receive timely response using serial communication. 

However, I keep getting a strange issue with my code and I have had no luck resolving it. The function "get_response" is supposed to set an empty pointer to the characters received from the modem. I pass to it a pointer char variable and allocate to it some memory in the function. I am able to print all characters stored in response pointer as characters from the modem are set to it. However , as soon as the function has completed it job, when I try to printf the response stored it always returns (NULL). I have also tried to return from  "get_response" function but when I try and printf whats being returned, gibberish characters printed.

My question is how do I store the response from the modem and access it outside the "get_response" function?

Thanks in advance.

<<<<<<<<<<<<<<<<Debug terminal>>>>>>>>>>>> 

START // start of code

OK // characters received from modem when its stored in response pointer
(null) //   printf("\n%s",res_ptr);
//     printf("\n%s",ptr);


END // end of code

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>

Parents
  • I took a quick look at the code in get_response(unsigned char *response), and it seems like you are increasing the address (which response is pointing at) of one byte after each iteration. At the end of the function call, the pointer response will point to the end of the stored string. 

    • res_ptr is set to NULL initially, then inside the function get_response() the local variable (see hereresponse is changed (not res_ptr in the main() scope), and when trying to access it in main() after the function call it will still be NULL
    • Due to the explanation above, ptr will point to the end of the stored string, and you will just print the values stored after the string when calling printf

    This is how I would go about it:

    • Declare and set the pointer res_ptr (to an actual memory address) before running get_response. You might consider not using malloc, due to the reasons in this ticket.
    • Pass the pointer as an argument to get_response()  as you've done
    • Create a local copy temp_ptr of the pointer in get_response()
    • Store the incoming serial data at the address pointed to by temp_ptr and increase it after each iteration as you've done
    • In the end, don't return anything, since the serial data will be stored at the address which res_ptr is pointing at
    • Run printf("\n%s",res_ptr); in main(), and it should work

    Best regards,

    Simon

  • Thanks for this detailed response Simon.

    Can you please just clarify how to set res_ptr to some memory address without using malloc. I have limited programming experience so any guidance would be greatly appreciated.

    I have made the changes you advise to the function get_response but the printf still shows a NULL output.

    In the debug terminal I am able to see the correct response from the modem but it does not store the response into the memory address given to get_response function.

    If I am missing anything please do let me know.

    CODE:

    void get_response(unsigned char *response){

    ret_code_t err_code;

    uint8_t * temp_ptr = NULL; // init temp ptr

    temp_ptr = response; // set temp ptr to address where serial data should be stored

    //temp_ptr = (uint8_t *)malloc(sizeof(uint8_t)*2400);

    if(temp_ptr=NULL){printf("failed to assign memory");}

    uint8_t c;

    do{
    nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 0);
    nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);

    if(c=='K' || c=='R' ){
    nrf_delay_ms(10);
    *temp_ptr=c;
    printf("%c",*temp_ptr);
    temp_ptr++;
    nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 0);
    nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);
    if(c=='\r'){
    *temp_ptr=c;
    break;
    }
    }

    *temp_ptr=c;
    printf("%c",*temp_ptr);
    temp_ptr++;
    nrf_delay_ms(15);
    bsp_board_led_invert(0);

    } while(1);

    }

    /// main ////

    int main(void)
    {
    ret_code_t err_code;

    // Initialize.
    err_code=nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);

    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);

    nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);

    printf("\nSTART main\n");

    static char tx_message[] = "at+cops?\r";


    err_code = nrf_serial_write(&serial_uart,
    tx_message,
    strlen(tx_message),
    NULL,
    NRF_SERIAL_MAX_TIMEOUT);

    APP_ERROR_CHECK(err_code);

    nrf_delay_ms(100);

    init_modem();

    SendAt_cmd(tx_message);

    uint8_t res_ptr ,i=0,t=0,c;

    get_response(&res_ptr);

    printf("\nptr = %s\n",res_ptr);


    printf("\nEND");
    }

  • I have provided as a simple code snippet that illustrates how this can be done, you should modify it according to your implementation, but the approach should be same.

    void get_response(char *ptr, int len){
        //Remember to check if i is bigger than len - 1
        //swap the for loop with the do-while loop
        int i = 0; 
        for(i; i < 10; i ++){
            ptr[i] = 'a';
        }
        ptr[i++] = NULL;
    
    }
    
    #define STRING_SIZE 100
    int main(void)
    {
        //Initialize NRF_LOG
        .
        .
        char string[STRING_SIZE];
        get_response(string, sizeof(string));
        NRF_LOG_INFO("string: %s", string);
        .
        .
    }

    Best regards,

    Simon

Reply
  • I have provided as a simple code snippet that illustrates how this can be done, you should modify it according to your implementation, but the approach should be same.

    void get_response(char *ptr, int len){
        //Remember to check if i is bigger than len - 1
        //swap the for loop with the do-while loop
        int i = 0; 
        for(i; i < 10; i ++){
            ptr[i] = 'a';
        }
        ptr[i++] = NULL;
    
    }
    
    #define STRING_SIZE 100
    int main(void)
    {
        //Initialize NRF_LOG
        .
        .
        char string[STRING_SIZE];
        get_response(string, sizeof(string));
        NRF_LOG_INFO("string: %s", string);
        .
        .
    }

    Best regards,

    Simon

Children
No Data
Related