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

How to receive SMS message in standby mode in nRF9160?

I want to wake up nRF9160 by SMS.

What I want to do:

The nRF9160 usually sleeps to reduce power consumption, and only when it receives SMS it wakes up and send some data by UDP or so.

I succeeded in implementing MQTT(+TLS), but have no experience to implement SMS function.

Any advice?

Parents
  • I've already checked the link below, but I don't really get what each line means.
    devzone.nordicsemi.com/.../sending-sms-using-at_client-example

    This is my understanding.

    ----------------
    AT+CFUN=1
    => Turn on the modem. The modem can receive SMS at any time.

    AT+CPIN="1234"
    => Set Pin number, which is a password of SIM.

    AT+CNMI=3,2,0,1
    => Configure the process of receving SMS.
    ----------------

    After this setting, MCU can go to sleep to wait until SMS is received. When SMS is received, MCU wakes up.

    Is this correct? I'm not familiar with SMS function. Sorry for poor skill.

  • The sample you link to is for sending sms. For receiving sms, you need to poll the AT socket. Try to use at_client, and see if you are able to get a sms successfully received. Note that you need a SIM card which has a phone number in order to send/receive sms.

     

    Kind regards,

    Håkon

  • AT+CEDRXRDP=4,"0110","0110","0000"
    +CEDRXRDP: 0
    OK

    When I run the above AT command with at_client program, I received "+CEDRXRDP: 0."

    But, studying the current consumption(floor: 40uA) and receiving interval, eDRX seems to be working in mqtt_simple + edrx, not at_client.

    I guess something is missing.

    What should I add? Any help?

  • oops! That's wrong.

    This is correct.

    AT+CEDRXS=2,4,"0110"

  • Hi, Hakon.

    I managed to receive SMS during eDRX on at_client and LTE Link Monitor.

    AT+CFUN=4
    AT%XBANDLOCK=1,"10000000" // Some carriers don't support SMS during eDRX
    AT+CEDRXS=2,4,"0110" // enable eDRX
    AT%XPTW=4,"0111"
    AT+CNMI=3,2,0,1
    AT%XSYSTEMMODE=1,0,0,0
    AT+CFUN=1
    Wait for a while
    AT+CFUN? // Make sure LTE conection is established
    AT+CEDRXRDP
    AT+CNMI?
    SMS from server
    wait until unsolicited message shows up on LLM
    

    When I implement this code in usual project and check if SMS notification shows up on LTE Link Monitor, I can't receive SMS notification even though I set "AT+CNMI=3,2,0,1." SMS seems to be received, but SMS notification is not generated.

    <main>
    .
    .
    .
    void send_at_commands(void)
    {
    
        char recv_buf[1024 + 1];
    	const char *at_commands[] = { "AT+CEDRXRDP", "AT+CNMI?" };
    
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
    
    	if (at_socket_fd < 0) {
    		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
    	}
    	for (int i = 0; i < ARRAY_SIZE(at_commands); i++) {
            printk("%s\n", at_commands[i]);
    		int bytes_written = send(at_socket_fd, at_commands[i],
    					 strlen(at_commands[i]), 0);
    		if (bytes_written > 0) {
    			int r_bytes = blocking_recv(at_socket_fd, recv_buf, sizeof(recv_buf), MSG_DONTWAIT);
    			if (r_bytes > 0) {
    				printk("%s", recv_buf);
    			}
    		}
    	}
    	printk("Closing socket\n\r");
    	(void)close(at_socket_fd);
    }
    
    void main(void)
    {
    	printk("The AT client program started\n");
    	modem_configure();
        send_at_commands();
    }
    

    <lte_lc.c>
    .
    .
    #if defined(CONFIG_LTE_LOCK_BANDS)
    /* Lock LTE bands 8 (volatile setting) */
    static const char lock_bands[] = "AT%XBANDLOCK=2,\"10000000\"";
    #endif
    /* Request eDRX settings to be used */
    static const char edrx_req[] = "AT+CEDRXS=1,"CONFIG_LTE_EDRX_REQ_ACTT_TYPE",\""CONFIG_LTE_EDRX_REQ_VALUE"\"";
    static const char edrx_ptw[] = "AT%XPTW=4,\"0111\"";
    .
    .
    static int w_lte_lc_init_and_connect(struct device *unused)
    {
    /* ADD HERE */
    	if (at_cmd_write(offline, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    	if (at_cmd_write("AT+CNMI=3,2,0,1", NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    /* ADD HERE */
    
    #if defined(CONFIG_LTE_EDRX_REQ)
    	/* Request configured eDRX settings to save power */
    	if (at_cmd_write(edrx_req, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    	if (at_cmd_write(edrx_ptw, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    #endif
    	if (at_cmd_write(subscribe, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    #if defined(CONFIG_LTE_LOCK_BANDS)
    	/* Set LTE band lock (volatile setting).
    	 * Has to be done every time before activating the modem.
    	 */
    	if (at_cmd_write(lock_bands, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    #endif
    #if defined(CONFIG_LTE_LEGACY_PCO_MODE)
    	if (at_cmd_write(legacy_pco, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    	LOG_INF("Using legacy LTE PCO mode...");
    #endif
    #if defined(CONFIG_LTE_PDP_CMD)
    	if (at_cmd_write(cgdcont, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    	LOG_INF("PDP Context: %s", cgdcont);
    #endif
    	if (at_cmd_write(network_mode, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    	k_sem_init(&link, 0, 1);
    
    	at_cmd_set_notification_handler(at_handler);
    
    	if (at_cmd_write(normal, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    	k_sem_take(&link, K_FOREVER);
    
    	at_cmd_set_notification_handler(NULL);
    
    	return 0;
    }


    *Without SMS notification, AT+CNMI was reset and probably SMS is received. 

    /ncs/nrf/drivers/lte_link_control/lte_lc.c

    In this lte_lc.c, I think at_cmd_set_notification_handler is related to this issue. Can you check this?

    Another question:

    Every time SMS is received, SMS notification is reset and you need to run "AT+CNMI=3,2,0,1" again. Why does this happen? Is this possible to set SMS notification permanently?

  • I'm pretty sure that "at_cmd_set_notification_handler"  causes this issue.

    When I comment out the two lines, SMS notification shows up, but when I don't, it doesn't show up.

    Could you help me fix this issue?

    Thank you so much for helping me a lot!

    <lte_lc.c>
    
    static int w_lte_lc_init_and_connect(struct device *unused)
    {
    .
    .
    .
    	if (at_cmd_write(network_mode, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    	k_sem_init(&link, 0, 1);
    
    //	at_cmd_set_notification_handler(at_handler);
    
    	if (at_cmd_write(normal, NULL, 0, NULL) != 0) {
    		return -EIO;
    	}
    
    	k_sem_take(&link, K_FOREVER);
    
    //	at_cmd_set_notification_handler(NULL);
    
    	return 0;
    }

  • Hi,

     

    I am sorry for the late reply.

    When registering a request from AT+CNMI, you should use AT+CNMA to ACK the received message.

    If the ACK is not delivered before the timeout, the CNMI is released, as per this specification:

    https://infocenter.nordicsemi.com/topic/ref_at_commands/REF/at_commands/text_mode/cnma_set.html?cp=2_1_8_5_0

     

    I do not see how commenting out the at_cmd_set_notification_handler() should influence this procedure. Could you see if the same behavior is observed if you ACK the SMS using CNMA?

     

    Kind regards,

    Håkon

Reply Children
  • Hi, Hakon. Thank you for your reply!

    So these steps should be correct

    1. run "AT+CNMI=3,2,0,1"
    2. polling for an incoming SMS
    3. send SMS from a server
    4. SMS notification shows up once the SMS is received
    5. run "AT+CNMA" right after the notification
    *If I don't run "AT+CNMA"  when SMS is received, SMS notification is disabled.

    OK, I got this.

    However, when I don't comment out at_cmd_set_notification_handler(), no SMS receiving notification shows up, so MCU doesn't know the timing of sending "AT+CNMA" command. I guess at_cmd_set_notification_handler() needs some fix.

    I will try to find a way of polling an incoming SMS. 

Related