Sending Cellular Data from Arduino MKR GSM 1400 to Hologram Cloud

Hello,

I have a project where I am using an Arduino MKR GSM 1400 to send remote data to the cloud using a cellular connection and SIM card. The network I am using is called hologram.

I am having some trouble understanding all the code that is used to just to send a simple SMS to the cloud from the device. Below is what I am using to send an SMS with one string value and I have confirmed that it works. But the problem is I don't want to send a string value, I need to send about 4 analog readings that are "float" data type. How can I do this?

#include 


const char PINNUMBER[] = " ";
// APN data
const char GPRS_APN[] = "hologram";
const char GPRS_LOGIN[] = " ";
const char GPRS_PASSWORD[] = " ";
String HOLOGRAM_DEVICE_KEY = "mykey";
String HOLOGRAM_MESSAGE = "custom";
String HOLOGRAM_TOPIC = "TOPIC";


// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;


// Hologram's Embedded API (https://hologram.io/docs/reference/cloud/embedded/) URL and port
char server[] = "cloudsocket.hologram.io";
int port = 9999;


void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.println("Starting Arduino web client.");
  // connection state
  boolean connected = false;


  // After starting the modem with GSM.begin()
  // attach to the GPRS network with the APN, login and password
  while (!connected) {
     Serial.println("Begin gsm Access");
    //Serial.println(gsmAccess.begin()); //Uncomment for testing
    
    if ((gsmAccess.begin() == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
      Serial.println("GSM Access Success");
    } 
    else {
      Serial.println("Not connected");
      delay(1000);
    }
  }


  Serial.println("connecting...");


  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("connected");
    // Send a Message request:
    client.println("{\"k\":\"" + HOLOGRAM_DEVICE_KEY +"\",\"d\":\""+ HOLOGRAM_MESSAGE+ "\",\"t\":\""+HOLOGRAM_TOPIC+"\"}");
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}


void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }


  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();


    // do nothing forevermore:
    for (;;)
      ;
  }
}

One method is to format the numbers to an ASCII character string using dtostrf() or snprintf()

Okay I checked that out and I think I see how to format my variable for a float data type in the setup. But what about when this variable is printed from the client to the host at the very end of the code. Are there any changes that need to be done here? I don't quite understand the reason for all of the characters below. Also how could I add another variable to this syntax?

client.println("{\"k\":\"" + HOLOGRAM_DEVICE_KEY +"\",\"d\":\""+ HOLOGRAM_MESSAGE+ "\",\"t\":\""+HOLOGRAM_TOPIC+"\"}");

That syntax is forming one long character string, so that it can be printed with one client.println() statement.

It is much easier and clearer just to use multiple print statements to do the same thing. For example:

Serial.print("My name is ");
Serial.print("John and my age is ");
int age=36;
Serial.print(age);
Serial.println(".");

Look up escape characters in print statements. Constructions like \" allow printing the " character, which is normally used as a string delimiter.

There is no need to use String objects and for AVR-based Arduinos, they should be avoided because they cause memory problems and program crashes.

I see I wasn't able to find all of these escape characters to completely decipher what will actually print. Could you tell me what will actually show up in a serial monitor if you ran:

Serial.println("{\"k\":\"" + String1 +"\",\"d\":\""+ String2+ "\",\"t\":\""+String3+"\"}");

If not I will try to run this code when I get back to the house.

I will try to run this code when I get back to the house.

Excellent idea.

{"k":"String1","d":"String2","t":"String3"} is what was observed in the serial monitor. I think it would be much clearer to do the code in several serial.print instances instead of just one, as you suggested.

This puts me in the right direction but doesn't really answer my core question, which is how do I send more than one data reading to the cloud? It seems that there is some site specific formatting being done to the client.println() so that hologram's configuration can recognize 3 distinct items: the key (which follows after "k"), the data ("d") and the topic.

How could I send temp1 = 100, temp2 = 200, temp3 = 300 in a way that will be recognized as data (after the "d": and before the "t":

Obviously, you need to understand what the receiving end expects in the way of message format.

Why not tell us the rest of the story? What cloud service will you be using, post a link to the protocol specifications, etc.

I'm new to the game ;). But I reached out to the site to try to get support from them to understand their formatting. Other than that I am not sure what else to do other than trial and error.

As I specified earlier the cloud service I am using is called hologram. As for your other question on protocol I am unsure, just a noob to this.

It is too much trouble to post a link to this service?

Other than that I am not sure what else to do other than trial and error

That will never work. The operators will have posted a description of exactly how they expect the service to be used.

No trouble at all. The link to the site is: Hologram main page

There is a subsection of the site that talks about protocol compatibility: Hologram Protocols

I am not sure if this is exactly what you need let me know if not.

Thanks. Hologram is a messaging service, not a data base.

You can use the approach outlined in replies #1 and #3 to send ASCII characters containing your four values. I would separate the values with commas and add an ID code and a unix time/date stamp.

The process to receive and interpret the data would be a separate issue, although it is very wise to plan both at the same time.

Okay I gotcha, believe I have some idea of how to format the outbound data. I am trying to get the data to mySQL and then query it from a website.

Will I need to write from arduino>hologram cloud>mySQL ?

Or can I write directly from my device to mySQL?

Hologram is a messaging service, which means it sends messages.

You need to determine where those messages go, and how they will be interpreted at the receiving end. Surely there are tutorials to study.