SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4

I have the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 connected to a Sparkfun Redboard UNO.

The library has a few examples.

I have been trying to do something with the shield other than send and SMS. That is the only example that works.

It is connected to AT&T hologram. I have used m-center to get information from the shield and it all looks good and things operate as expected.

I have tried to write programs to send data to thingspeak.com using HTTP and/or MQTT with no success.

The sparkfun library example is supposed to send a TCP message to hologram but it does not work either. It tries to open the socket and immediately fails.

// Plug in your Hologram device key here:
String HOLOGRAM_DEVICE_KEY = “JxxxxxOL”;

// These values should remain the same:
const char HOLOGRAM_URL[] = “cloudsocket(dot)hologram(dot)io”;
const unsigned int HOLOGRAM_PORT = 9999;

My goal is to send weather data to thingspeak(dot)com for our RC flying field.

Thanks.

You probably need to create a route in the Hologram data-routes page in your dashboard. That URL is a hologram endpoint that can take many different types of messages and buffer / forward them as you desire (with configuration).

Log in to https://dashboard.hologram.io Click on “Routes” in the left sidebar and then at the bottom click on “All activity” You should see some entries here from your devices attempts. To forward these along to thingspeak or another cloud service checkout: https://hologram.io/docs/guide/cloud/data-router/ Note you may need to research additional configuration for Thingspeak as it doesnt seem to be discussed in the Hologram documentation.

Thanks for the feedback and I will look at all that again. I believe my first issue is when the shield tries to open a TCP port and fails immediately. I can’t push a message to Hologram until that is working correct?

When I try to run the 2 way Data Feed example from the Arduino library…

This looks like you are trying to query the device through a listening port. This is pretty “advanced” for debugging, step back and just try to send data from device to hologram cloud, ignore thingspeak all together.

In your original post when you say

The sparkfun library example is supposed to send a TCP message to hologram but it does not work either. It tries to open the socket and immediately fails.

What do you mean it immediately fails? how do you know it failed? what message did it say?

Also you mention you can use mcenter to send AT commands, run through https://help.hologram.io/en/articles/1944384-modem-sim-annotated-diagnostic-test and post the results. That will help debug.

The way the example was written, it did not say anything, just tried to open the socket and no more messages. I added some serial debug statements to the library routine and it looks like it gets to “connecting to socket” and never returns form SocketConnect.

The link to the Sparkfun library is here:

void setup() {
  Serial.begin(9600);

  if ( lte.begin(lteSerial, 9600) ) {
    Serial.println(F("LTE Shield connected!"));
  }

  Serial.println(F("Type a message. Send a Newline (\\n) to send it..."));
}

void loop() {
  static String message = "";
  if (Serial.available())
  {
    char c = Serial.read();
    // Read a message until a \n (newline) is received
    if (c == '\n') {
      // Once we receive a newline. send the text.
      Serial.println("Sending: " + String(message));
      // Call lte.sendSMS(String number, String message) to send an SMS
      // message.
      sendHologramMessage(message);
      message = ""; // Clear message string
    } else {
      message += c; // Add last character to message
    }
  }
  lte.poll();
}

void sendHologramMessage(String message)
{
  int socket = -1;
  String hologramMessage;

  // New lines are not handled well
  message.replace('\r', ' ');
  message.replace('\n', ' ');

  // Construct a JSON-encoded Hologram message string:
  hologramMessage = "{\"k\":\"" + HOLOGRAM_DEVICE_KEY + "\",\"d\":\"" +
    message + "\"}";
  
  // Open a socket
  socket = lte.socketOpen(LTE_SHIELD_TCP);
  // On success, socketOpen will return a value between 0-5. On fail -1.
  if (socket >= 0) {
    // Use the socket to connec to the Hologram server
    Serial.println("Connecting to socket: " + String(socket));
    if (lte.socketConnect(socket, HOLOGRAM_URL, HOLOGRAM_PORT) == LTE_SHIELD_SUCCESS) {
      // Send our message to the server:
      Serial.println("Sending: " + String(hologramMessage));
      if (lte.socketWrite(socket, hologramMessage) == LTE_SHIELD_SUCCESS)
      {
        // On succesful write, close the socket.
        if (lte.socketClose(socket) == LTE_SHIELD_SUCCESS) {
          Serial.println("Socket " + String(socket) + " closed");
        }
      } else {
        Serial.println(F("Failed to write"));
      }
    }
  }
}

It likely returns with failure, looks like you dont have any print statement if socket returns <0. Add the last else statement (also for reference use the “</>” key in the forum post above to allow your code to maintain formatting, makes it much much much easier to help)

void sendHologramMessage(String message)
{
	int socket = -1;
	String hologramMessage;

	// New lines are not handled well
	message.replace(’\r’, ’ ‘);
	message.replace(’\n’, ’ ');

	// Construct a JSON-encoded Hologram message string:
	hologramMessage = “{“k”:”" + HOLOGRAM_DEVICE_KEY + “”,“d”:"" +
	message + “”}";

	// Open a socket
	socket = lte.socketOpen(LTE_SHIELD_TCP);
	// On success, socketOpen will return a value between 0-5. On fail -1.
	if (socket >= 0) {
		// Use the socket to connec to the Hologram server
		Serial.println("Connecting to socket: " + String(socket));
		if (lte.socketConnect(socket, HOLOGRAM_URL, HOLOGRAM_PORT) == LTE_SHIELD_SUCCESS) {
			// Send our message to the server:
			Serial.println("Sending: " + String(hologramMessage));
			if (lte.socketWrite(socket, hologramMessage) == LTE_SHIELD_SUCCESS)
			{
				// On succesful write, close the socket.
				if (lte.socketClose(socket) == LTE_SHIELD_SUCCESS) {
					Serial.println(“Socket " + String(socket) + " closed”);
				}
			} else {
				Serial.println(F(“Failed to write”));
			}
		}
	}
	//you need to add this:
	else {
		Serial.println(F(“Failed to create socket"));
	}
}

I haven’t looked at this library but in general these libraries provided with shields are crap and have little to no error handling or reporting. There are rarely an retries / etc. programmed in. If you want this to be reliable I suggest writing your own or heavily modifying the provided library and make sure you handle every possible return value both from the modem and from the provided function calls.

I would also recommend you post on the Sparkfun forum related to this shield or the GitHub as I bet this is more of a Sparkfun library issue than a Hologram network issue. I can help alot at the AT command level but this is about all I can do for playing around with a 3rd party library.

I worked a little over the weekend and turned on all the serial print statements in the library and it looks like the socket opens but no response after the command is sent to Hologram.

Command: +UGPIOC=16,2
Response: 
OK

Command: +UGPIOC=23,3
Response: 
OK

Command: +CMGF=1
Response: 
OK

Command: +CTZU=1
Response: 
OK

Command: +USOCL=0
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=0
4
Command: +USOCL=1
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=1
4
Command: +USOCL=2
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=2
4
Command: +USOCL=3
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=3
4
Command: +USOCL=4
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=4
4
Command: +USOCL=5
Response: 
+CME ERROR: Operation not allowed


Closing Socket
+USOCL=5
4
LTE Shield connected!
Type a message. Send a Newline (\n) to send it...
Sending: hello

+USOCR=6,0

Command: +USOCR=6,0
Response: 
+USOCR: 0

OK

0
+USOCR: 0

OK

+USOCR: 0

OK

0
Connecting to socket: 0
0
cloudsocket.hologram.io

+USOCO=0,"cloudsocket.hologram.io",9999
Command: +USOCO=0,"cloudsocket.hologram.io",9999
Response: ⸮⸮⸮⸮⸮⸮⸮⸮?⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

Hmmm, So the command it errored out on is when it attempting to create the TCP channel, no actual data / command is sent yet. The response, I am guessing, is gibberish likely due to either a baud rate switch or some electrical issue. What power supply are you using, I would suggest using the 5V usb input on the Redboard UNO plugged in to a 2A wall plug. Its possible the modem is browning out when it is trying to send data (that TCP connect command is the first time the modem is actually trying to send where it will use peak power).

If you have an oscilloscope you can connect it to the power input at see if it sags. I would also recommend sending the modem a few “AT” commands and looking for the “OK” after to see if the modem is still communicating after that connection request.

You can also try other endpoints, checkout https://www.u-blox.com/sites/default/files/AT-CommandsExamples_AppNote_(UBX-13001820).pdf section 10 for some examples.

Thank you for your help BTW!
I played with power supplies and even connected a 5v switching regulator so I don’t think it’s power. All power sources do the same thing.

Just going through some of the examples in the link above and typing into the Sara R4 using a serial passthrough program:

Creating a socket works:

AT+USOCR=6

+USOCR: 0

OK

Any socket connect command causes jibberish back on the serial:

AT+USOCO=0,"3.210.32.221",7
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮{⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮W⸮ŷ⸮⸮⸮⸮⸮⸮⸮;⸮⸮⸮⸮⸮⸮⸮⸮⸮߯⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
+CME ERROR: Operation not allowed

....long time goes by.....

+UUSOCL: 0

or

+USOCO=0,"cloudsocket.hologram.io",9999
Command: +USOCO=0,"cloudsocket.hologram.io",9999
Response: ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮o⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
4
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

....long time goes by.....


+CME ERROR: Operation not allowed


+UUSOCL: 0
⸮⸮⸮

Looking at HTTP examples, I noticed that I get an error after any command such as:

AT+UDNSRN=0,"ftp.u-blox.com"
ERROR