Vodafone connection Netherlands for NB IoT

Im trying to connect my SARA R410 with Vodafone to Allthingstalk with some custom sensors attached to it. Messages are sent by UDP. However I face some issues with maintaining the connection. I took at all posts regarding NB IoT connection issues but it still does not seem to fix the issues. Before coming to the actual problems, I seem to be confused now with the correct library to use for connecting the device.

Is it Sodaq_R4X or Sodaq_nbIOT, the library I should use to set up my board?

is the library you should use.

Best regards,
Jan

Thanks for your response @Jan, that removed some confusion already.

I am trying to send some sensor values through UDP to AllThingsTalk through my Vodafone NB IoT network using R410 AFF. Following is the code. I have commented out some of the project related info.

const char* provider = "NL VODAFONE NB-IoT";
const char* apn = "nb.inetd.gdsp";
const char* forceOperator = "20404"; // optional - depends on SIM / network
const char* urat = "8";

#define CURRENT_APN      "nb.inetd.gdsp"
#define CURRENT_OPERATOR AUTOMATIC_OPERATOR
#define CURRENT_URAT     SODAQ_R4X_NBIOT_URAT
#define CURRENT_MNO_PROFILE MNOProfiles::VODAFONE
#define NBIOT_BANDMASK "524420"

/* SODAQ SARA AFF*/
#define DEBUG_STREAM SerialUSB
#define MODEM_STREAM Serial1
#define powerPin SARA_ENABLE
#define enablePin SARA_TX_ENABLE
#warning "ARDUINO_SODAQ_SARA selected"

static Sodaq_SARA_R4XX_OnOff saraR4xxOnOff;

void  configureSODAQPins() {
#ifdef powerPin
  // Put voltage on the nb-iot module
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, HIGH);
#endif

#ifdef R4XX
  // Switch module voltage
  pinMode(voltagePin, OUTPUT);
  digitalWrite(voltagePin, LOW);
#endif

#ifdef enablePin
  // Set state to active
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin, HIGH);
#endif // enablePin
}


void sendMessageThroughUDP()
{
  sodaq_wdt_safe_delay(1000);

  int localPort = 16666;

  int socketID = r4x.socketCreate(localPort);

  if (socketID >= 7 || socketID < 0) {
    DEBUG_STREAM.println("Failed to create socket");
    DEBUG_STREAM.print("Socket ID"); DEBUG_STREAM.println(socketID);
  }
  else{
    String deviceId = <<deviceID-Allthingstalk>>;
    String token =  <<deviceToken-Allthingstalk>>;

    // create JSON values
    String value =  "{\"asset_1\":{\"value\":" + <<VALUE>> + "}}";

    String reading = deviceId + '\n' + token + '\n' + value;

    uint8_t rsize = reading.length();
    int lengthSent = r4x.socketSend(socketID, ALLTHINGSTALK_IP, ALLTHINGSTALK_PORT, (uint8_t*)reading.c_str(), rsize);

    socketClosed = r4x.socketClose(socketID);
}

return;  
}

void setup() {

  configureSODAQPins();

  DEBUG_STREAM.begin(115200);

// InitSodaq();
  MODEM_STREAM.begin(r4x.getDefaultBaudrate());   // set to 115200 in r4x.h
  if (SODAQ_DEBUG) r4x.setDiag(DEBUG_STREAM);
  r4x.init(&saraR4xxOnOff, MODEM_STREAM);

// Other init functions for sensors
...
...
...

  startMillis = millis();           // Saves the initial millis value
}

void loop() {

  sodaq_wdt_safe_delay(200);

  unsigned long ElapseCnt;

  ElapseCnt = millis() - startMillis;

  ....
  // read all sensor values
  .....

// send every hour
  if (ElapseCnt >= SENDINTERVAL) {  //


    //  if (!r4x.connect(CURRENT_APN, CURRENT_URAT, CURRENT_MNO_PROFILE, CURRENT_OPERATOR, BAND_MASK_UNCHANGED, NBIOT_BANDMASK)){
    if (!r4x.connect(apn, urat, NBIOT_BANDMASK)) {
    //  if (!r4x.connect(apn, urat)){
      DEBUG_STREAM.println("########FAILED TO CONNECT TO MODEM########");
      return;
    }
    else {
      DEBUG_STREAM.println("########MODEM CONNECTED SUCCESSFULLY########");
    }

    sendMessageThroughUDP();

    ElapseCnt = 0;

    if (!r4x.disconnect()) {
      DEBUG_STREAM.println("########FAILED TO DISCONNECT FROM MODEM########");
    }
    else {
      DEBUG_STREAM.println("########MODEM DISCONNECTED SUCCESSFULLY########");
    }
  }

// wait for some time (10 minutes) for next measurement
  sodaq_wdt_safe_delay(MEASUREINTERVAL);

}


I edited the code to remove some sensitive information, but kept all the ones with the pinModes and connections and message sending. This edit might have caused some formatiing errors.

As you can see, I do regular measurements (maybe around every 10 minutes) and the data is sent every hour. The current approach is where I connect to the service and disconnects every time I send a message. Also, I have different options to connect to the service using r4x.connect(), I have multiple examples that work currently.

The problem I have is the unstability of the network. After sending messages for a few hours( 4 or 5), the modem does not respond to any AT commands. I even wrote a procedure to reset the modem when that happens with the following.

//1
  digitalWrite(powerPin, LOW);
  digitalWrite(powerPin, HIGH);
//2
  sodaq_wdt_reset();

They did not restore the connection, however a hard reset with the physical button reconnects my modem.

Perhaps something that I missed caught your eye? I have seen many discussions in the forum and tried multiple solutions. The whole code is based on multiple examples I found in the forum, but this connectivity is something I cannot solve yet.

I am also quite new to SODAQ and also NB IoT services, so any help is appreciated.!

Hi kchand,

There should be no need for your sendMessageThroughUDP() function, please check what the Sodaq_SARA_R4XX_OnOff class does.

I also recommend you actually turn the modem off instead of disconnecting (only) from the network, there’s no reason to leave it on.

If you don’t change the configuration (connect configures and waits for connection) you can just turn the modem on after the first time and periodically check for CGATT and CSQ and continue once you got those.

Regards,
Thom

Hi @Thom

Thanks for the reply.

Where do I see more about Sodaq_SARA_R4XX_OnOff class?
At the moment, my only reference is the the cpp and .h files in the libraries folder. Also, I only see three functions: Sodaq_SARA_R4XX_OnOff::on(), Sodaq_SARA_R4XX_OnOff::off(), Sodaq_SARA_R4XX_OnOff::isOn(). How do they replace my sendMessageThroughUDP() function, it does not seem to have any function related to that?

Thanks for your suggestion on the modem connection. I guess Sodaq_SARA_R4XX_OnOff::off() can turn off and disconnect the modem while waiting. CSQ and CGATT seem to be implemented in the functions isConnected() and isAttached() in Sodaq_R4X class.

What is the preferred way to go if I keep the modem connected and but after some time, isConnected() and isAttached() returns false? I see AT commands timed out after a while while testing the program.

Kiran

Hi kiran,

The Sodaq_SARA_R4XX_OnOff contains the implementation of turning the modem on and off, it should be at the bottom of the R4X library .cpp file. I see I made a mistake, I meant the configureSODAQPins() function, not the sendMessageThroughUDP(). Your sendMessageThroughUDP() is fine as is, no need to change that. Sorry about that.

If the AT commands time out it could be that the modem went to sleep, look for the UPSV and CPSMS commands (and maybe CEDRXS).

Regards,
Thom

Thank you for the quick response @Thom!

Regarding the above qoute, I do not see its implementation in any functions in the R4X cpp file. I am not a network engineer (#noobalert), do not know all AT commands.

Do you think you can suggest some way to use it, or another library with this implementation. I also notice that the R4X has an Sodaq_R4X::execCommand() function. I could possibly use that one? A short example would be very helpful.

Also, how do you usually send or test quickly AT commands through SODAQ? At the moment, only option I see to implement a code that reads from the serial (then I can type into the Arduino serial monitor) and runs it with the execCommand(). Perhaps I am missing a simpler approach.

Hi kiran,

The execCommand is the right one to use. To disable all power saving use the following commands:

execCommand(“AT+CEDRXS=0”);
execCommand(“AT+CPSMS=0”);
execCommand(“AT+UPSV=0”);

Your suggestion is fine. You can have your own program and then have a while loop that continually delays but if it sees input over the USB it forwards it to the modem and vice versa.

Regards,
Thom

Thank @Thom, I will try these suggestions. I will update the progress of the device over some hours and post the results here.

Can you tell me the relevance of voltagePin? There is a part in the code,

#ifdef R4XX
  // Switch module voltage
  pinMode(voltagePin, OUTPUT);
  digitalWrite(voltagePin, LOW);
#endif

I noticed that R4XX was not defined and I am wondering what change will that bring to the program.

Hi Kiran,

At a quick glance it appears that the AFF R410M does not have this pin. You can try defining it in the .ino (#define R4XX) but it will probably not build.

The relevant pins for you as far as I can tell are:

SARA_ENABLE
SARA_RESET
SARA_TX_ENABLE
SARA_R4XX_TOGGLE

Regards,
Thom

1 Like

Hi @Thom

Your solution to disable power saving mode really worked. I have a device working over 24 hours now which is an achievement.

Sorry for the delayed response, I needed to get my hands on a new SIM.

Perhaps you can direct me to somewhere where I could get a clearer picture on what these powersaving commands are for and what these do and how it will impact the design of a device when I keep it running as disabled.

Thank you very much for your support so far!

K

Hi kchand,

You can refer to the R410M AT commands manual.

Regards,
Thom

1 Like