MKR NB 1500 cannot receive/send any data

Hello,

I am trying to connect to the Blynk server with my MKR NB 1500 Arduino.
I was able to connect by using the example from the Blynk library called Arduino_MKRNB.

Now I want to exchange data, i.e. send values from the Arduino to the Blynk app.
For what I understand, I must use the HTTPs API, is that correct?

There is no example with NB-IoT and HTTPs API in the Blynk library, but there is one that uses the HTTPs with GSM, and I am trying to follow that one. The code is exacly the same except that I changed the connectNetwork() function to connect to NB-IoT instead of GSM (see code below).

Problem: in the Blynk app, the device is offline, even though the Arduino says it connects successfully. Thus, we cannot send nor receive data.

Please let me know if there is something that I am misunderstanding.

Features of the project:
• MKR NB 1500 with NB-IoT communication
• Android 12
• Blynk server
• Blynk Library 1.0.1

Code:

#include <MKRNB.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
const char auth[] = "YourAuthToken";

// Blynk cloud server
const char* host = "blynk-cloud.com";
unsigned int port = 8080;

// Network settings
#define PINNUMBER ""

NBClient client;
GPRS gprs;
NB nbAccess;

// Start the GSM connection
void connectNetwork()
{
  Serial.println("Connecting to NB...");
  bool status = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (status == false) {
    if ((nbAccess.begin(PINNUMBER) == NB_READY) &
        (gprs.attachGPRS() == GPRS_READY)) {
      status = true;
    } else {
      Serial.print(".");
      delay(1000);
    }
  }

  Serial.println();
  Serial.println("NB connected");
}

bool httpRequest(const String& method,
                 const String& request,
                 String&       response)
{
  Serial.print(F("Connecting to "));
  Serial.print(host);
  Serial.print(":");
  Serial.print(port);
  Serial.print("... ");
  if (client.connect(host, port)) {
    Serial.println("OK");
  } else {
    Serial.println("failed");
    return false;
  }

  client.print(method); client.println(F(" HTTP/1.1"));
  client.print(F("Host: ")); client.println(host);
  client.println(F("Connection: close"));
  if (request.length()) {
    client.println(F("Content-Type: application/json"));
    client.print(F("Content-Length: ")); client.println(request.length());
    client.println();
    client.print(request);
  } else {
    client.println();
  }

  //Serial.println("Waiting response");
  int timeout = millis() + 5000;
  while (client.available() == 0) {
    if (timeout - millis() < 0) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return false;
    }
  }

  //Serial.println("Reading response");
  int contentLength = -1;
  while (client.available()) {
    String line = client.readStringUntil('\n');
    line.trim();
    line.toLowerCase();
    if (line.startsWith("content-length:")) {
      contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
    } else if (line.length() == 0) {
      break;
    }
  }

  //Serial.println("Reading response body");
  response = "";
  response.reserve(contentLength + 1);
  while (response.length() < contentLength && client.connected()) {
    while (client.available()) {
      char c = client.read();
      response += c;
    }
  }
  client.stop();
  return true;
}

void setup()
{
  Serial.begin(9600);
  delay(10);
  Serial.println();
  Serial.println();

  connectNetwork();
}

void loop() {
  String response;

  unsigned long value = millis();

  // Send value to the cloud
  // similar to Blynk.virtualWrite()

  Serial.print("Sending value: ");
  Serial.println(value);

  String putData = String("[\"") + value + "\"]";
  if (httpRequest(String("PUT /") + auth + "/update/V2", putData, response)) {
    if (response.length() != 0) {
      Serial.print("WARNING: ");
      Serial.println(response);
    }
  }

  // Read the value back
  // similar to Blynk.syncVirtual()

  Serial.println("Reading value");

  if (httpRequest(String("GET /") + auth + "/get/V2", "", response)) {
    Serial.print("Value from server: ");
    Serial.println(response);
  }

  // Set Property
  Serial.println("Setting property");

  if (httpRequest(String("GET /") + auth + "/update/V2?label=" + value, "", response)) {
    if (response.length() != 0) {
      Serial.print("WARNING: ");
      Serial.println(response);
    }
  }

  // For more HTTP API, see http://docs.blynkapi.apiary.io

  // Wait
  delay(30000L);
}

are you using blynk IOT or legacy ?

I’ve never used this board before but I guess no, you don’t have to use https to send or receive data.

You can try this very simple example

 ​/*​ Fill-in your Template ID (only if using Blynk.Cloud) ​*/ 
 ​//​#define BLYNK_TEMPLATE_ID   "YourTemplateID" 
  
  
 ​#​include​ ​<​MKRNB.h​> 
 ​#​include​ ​<​BlynkSimpleMKRNB.h​> 
  
 ​NBClient client; 
 ​GPRS gprs; 
 ​NB nbAccess; 
 ​//​ You should get Auth Token in the Blynk App. 
 ​//​ Go to the Project Settings (nut icon). 
 ​char​ auth[] = ​"​YourAuthToken​"​; 
 ​//​ Your SIM credential 
 ​//​ Leave empty, if missing pin 
 ​char​ pin[]  = ​"​"​; 
  
 ​void​ ​setup​() 
 ​{ 
 ​  ​//​ Debug console 
 ​  Serial.​begin​(​9600​); 
 ​  Blynk.​begin​(auth, nbAccess, gprs, client , pin); 
 ​} 
 ​void​ ​loop​() 
 ​{ 
 ​  Blynk.​run​(); 
 ​}
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1
BLYNK_WRITE(V1)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("V1 Slider value is: ");
  Serial.println(pinValue);
}

Hello @John93 ,
Yes, we are using Blynk IoT.

In Blynk’s Getting Started section → Send Data From Hardware To Blynk, it says the following:

This is why I was not sure, because we are using a cellular network (NB-IoT). However, we can stay connected, we don’t need to open a new connection everytime we want to exchange data (let me know if I am misunderstanding).

I will try your suggestion and then I let you know if it worked! Thank you.

Hello,

We tested with the virtual pins, as you suggested, and it works!

Thank you for you help, but can you explain to me the meaning of what is written in the documentation (as I posted in the last comment)? We can be connected all the time, and using the virtual pins we will be connected all the time, but we are using a cellular network, not WiFi nor Ethernet. For me the documentation is a bit misleading.

Virtual pins have nothing to do with how you connect.

You can use the Blynk library, which creates a constant connection.
If you wish, you can suspend this connection, using a disconnect command, and re-connect again when you need to send or receive data from the server, but for this you would need to change your sketch so that it manages the GPRS connection manually and uses Blynk.config and Blynk.connect/disconnect.

Obviously, when the device is disconnected it won’t respond to widget changes on the app or web console.

Alternatively, you can manually manage your GPRS connection then use the HTTP(S) API to upload/download data from the Blynk server.
Once again, it won’t know about widget changes while disconnected, and won’t know about them until you query the server using the API.

Pete.