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

Thingy91: Changing the Network Mode during runtime

Hello, I am writing a Program where I use GPS and NBIoT.
Recently, I wanted to combine the default GPS example code with an NBIoT Code, that connects to a TCP Server and when I tested it, either the Server Connection or the GPS failed. So I looked up and find an answer: https://devzone.nordicsemi.com/f/nordic-q-a/48636/nrf9160-localization-lte-nb

NBIoT and GPS can only run seperately. I tried now to switch between the to modes, but it didn't really work: I tried to run some AT Command during the runtime to switch from 
AT%XSYSTEMMODE=0,1,0,0 
to
AT%XSYSTEMMODE=0,0,1,0
and back within the code:

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include <zephyr.h>
#include <stdio.h>
#include <uart.h>
#include <string.h>
#include <net/socket.h>

void ATCFUN4(){
      static int at_command_socket;
      int bytes_sent, bytes_read;
      static u8_t at_command[256] = "AT+CFUN=4\r\n";
      static char result[256];
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      int bytes_to_send = strlen(at_command);
      bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
      bytes_read = recv(at_command_socket, result, sizeof(result), 0);
      printk("RECEIVED FROM recv(): %s\n", result);
}
void ATCFUN1(){
      static int at_command_socket;
      int bytes_sent, bytes_read;
      static u8_t at_command[256] = "AT+CFUN=1\r\n";
      static char result[256];
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      int bytes_to_send = strlen(at_command);
      bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
      bytes_read = recv(at_command_socket, result, sizeof(result), 0);
      printk("RECEIVED FROM recv(): %s\n", result);
}

void NBIoT_Mode(){
      static int at_command_socket;
      int bytes_sent, bytes_read;
      static u8_t at_command[256] = "AT%XSYSTEMMODE=0,0,1,0\r\n";
      static char result[256];
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      int bytes_to_send = strlen(at_command);
      bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
      bytes_read = recv(at_command_socket, result, sizeof(result), 0);
      printk("RECEIVED FROM recv(): %s\n", result);
}

void GPS_Mode(){
      static int at_command_socket;
      int bytes_sent, bytes_read;
      static u8_t at_command[256] = "AT%XSYSTEMMODE=0,1,0,0\r\n";
      static char result[256];
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      int bytes_to_send = strlen(at_command);
      bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
      bytes_read = recv(at_command_socket, result, sizeof(result), 0);
      printk("RECEIVED FROM recv(): %s\n", result);
}

void read_mode(){
      static int at_command_socket;
      int bytes_sent, bytes_read;
      static u8_t at_command[256] = "AT%XSYSTEMMODE?\r\n";
      static char result[256];
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      int bytes_to_send = strlen(at_command);
      bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
      bytes_read = recv(at_command_socket, result, sizeof(result), 0);
      printk("RECEIVED FROM recv(): %s\n", result);
}


void main(void)
{

while (1)
  {
    ATCFUN4();
  k_sleep(1000);
  NBIoT_Mode();
  k_sleep(1000);
  ATCFUN1();
  k_sleep(1000);
  read_mode();
  k_sleep(1000);
  ATCFUN4();
  k_sleep(1000);
  GPS_Mode();
  k_sleep(1000);
  ATCFUN1();
  k_sleep(1000);
  read_mode();
  k_sleep(1000);

  }
}

I wrote this code as a test to see, if I can switch between the two modes properly.

And I get this result in the LTE Monitor:

It only jumps one time and then it don't jumps back.

Is this the write way to change the network mode? Or do you have any idea how this could work properly?

Thanks for your answers!

  • Hello, 

    I am able to run your code, but it does not change system mode. What version of NCS and modem FW are you running? Have you tried with the AT Client, to verify that it can change state? 

    Kind regards, 
    Øyvind

  • Hi, I updated the modem FW to 1.1.0 and am in the master branch of NCS

    If I try to do it manually in the LTE Monitor, I can change it with no problem:

    Is there maybe another way to run AT commands during runtime? I tried to run the code from above again and then I saw that I get no OKs each time, I want to change the system mode:

    I have done it with this code in the example above:

          static int at_command_socket;
          int bytes_sent, bytes_read;
          static u8_t at_command[256] = "AT+CFUN=4\r\n";
          static char result[256];
          at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
          int bytes_to_send = strlen(at_command);
          bytes_sent = send(at_command_socket, at_command, bytes_to_send, 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
          printk("RECEIVED FROM recv(): %s\n", result);

    And I am not sure if this is the write way to do it for my case. 
    Do you maybe have another code example, that runs AT Commands during a program?

    Thanks for your for your answers and your help!

  • One of the non-official examples might be more appealing to you.

    https://github.com/Rallare/fw-nrfconnect-nrf/blob/nrf9160_samples/samples/nrf9160/simple_at/src/main.c

    See the above non-official sample for an application that simply runs a list of at commands (defined in 'at_commands[]').

  • Ok, i found the solution by myself:

    #include <zephyr.h>
    #include <stdio.h>
    #include <uart.h>
    #include <string.h>
    #include <net/socket.h>
    static int at_command_socket;
    int bytes_sent, bytes_read;
    static u8_t at_command1[256] = "AT+CFUN=4\r\n";
    static u8_t at_command2[256] = "AT+CFUN=1\r\n";
    static u8_t at_command3[256] = "AT%XSYSTEMMODE=0,1,0,0\r\n";
    static u8_t at_command4[256] = "AT%XSYSTEMMODE=0,0,1,0\r\n";
    static u8_t at_command5[256] = "AT%XSYSTEMMODE?\r\n";
    static char result[256];
    
    void ATCFUN4(){
          bytes_sent = send(at_command_socket, at_command1, strlen(at_command1), 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
    }
    void ATCFUN1(){      
          bytes_sent = send(at_command_socket, at_command2, strlen(at_command2), 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
    }
    
    void NBIoT_Mode(){      
          bytes_sent = send(at_command_socket, at_command3, strlen(at_command3), 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
    }
    
    
    void GPS_Mode(){    
          bytes_sent = send(at_command_socket, at_command4, strlen(at_command4), 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
    }
    
    
    void read_mode(){
          bytes_sent = send(at_command_socket, at_command5, strlen(at_command5), 0);
          bytes_read = recv(at_command_socket, result, sizeof(result), 0);
          printk("RECEIVED FROM recv(): %s\n", result);
    }
    
    
    void main(void)
    {
      at_command_socket = socket(AF_LTE, 0, NPROTO_AT);
      while (1)
        {
          ATCFUN4();
          k_sleep(100);
          GPS_Mode();
          k_sleep(200);
          ATCFUN1();
          k_sleep(100);
          read_mode();
          k_sleep(100);
          ATCFUN4();
          k_sleep(100);
          NBIoT_Mode();
          k_sleep(200);
          ATCFUN1();
          k_sleep(100);
          read_mode();
          k_sleep(100);
      }
    }

    I only have to declarate the variables and the socket once at the beginning of the code. Now I works:

Related