Using the internal MQTT functionality of the SARA 410 modem

I came here from a search on SerialSARA(). I notice you hit the 64 byte limit as well at one point. Where is the SerialSARA code? I did a search in the libraries and could not find it.

How did you get the 64 byte buffer to adjust? In my case, I read a response from the ublox and it quickly fills up 64 bytes and thereafter no more data can be read from the ublox.

I don't understand what you mean with the 64 byte limit.
With the tcp socket? With the AT console?
Can you explain a little deeper?

Hello instarep,

I appreciate your quick reply. Many thanks.

This link here describing the Serial.available() routine mentions a 64 byte buffer. I'm familiar with a 16-byte buffer on a 8250 uart. But, I believe in this case, the Serial class maintains a 64 byte buffer in software.

I don't know where the SerialSARA class is defined so I can't look at its code, but I imagine its derived from Serial. With that said, I've noticed that in the "SerialSARA Pass through" example it uses the loop() function to read a byte from sara and pass the byte to console. Likewise a byte read from serial is passed to Sara. SARA is the name of the u-blox module. SARA-R4 (for release 4)10 (10 being the model). The MKRNB has various classes for talking IP over a UBLox NB/Cat M1 GSM device. The SerialSARA is the basis for the AT commands used to implement a socket, send receive TCP packets, etc.

Using the SerialSARAPassThrough example, I can issue AT commands to get results. One of these commands in particular generates multiple lines of output with each line being around 100 characters. I would like to capture the lines and parse the results.

So, my problem is that as I use the SerialSARA.available() routine, I notice the number of bytes available do not adjust as I read the buffer. ie, if 64 bytes are available and I read them all (either in total or in pieces) the buffer never adjusts upward.

This code here demonstrates how to read the response two different ways.

Here is some sample output:

This particular bit of output shows the intial avaiable as 64. Then it shows reading the entire buffer gets almost a full line of output.
Afterwards, I attempt to read multiple times with varying/increasing delay between the reads. Each time no new info is added.

XXXXXXXXXXXXXXXXXXXXXXXXXXX
Response len:  64
Response:  AT+USECMNG=3
"CA","GTS_Root_R2","GTS Root R2","2036/06/22 00:0
Response:  
Response:  
Response:  
END STEP 0 --------------------
Halt

Here I am showing the results using the SerialSARAPassThru example output.

AT+USECMNG=3
"CA","GTS_Root_R2","GTS Root R2","2036/06/22 00:00:00"
"CA","GTS_CA_101","GTS CA 1O1","2021/12/15 00:00:42"
OK

Here is the entire response concatenated to show how a buffer would
compare against offsets. To be honest, i thought if I read blindly I would get the responses with a /r/n or /n after each line. Didn't matter though because it appears the buffer does not adjust as bytes are read.

                                                                                   1
0         1         2         3         4         5         6         7         8         9         0
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
"CA","GTS_Root_R2","GTS Root R2","2036/06/22 00:00:00""CA","GTS_CA_101","GTS CA 1O1","2021/12/15 00:00:42"OK

If your suspicion is correct and SerialSARA derives from Serial, when available is showing 64, it's too late to read your multiline input. Once the buffer is full, anything else that arrives at the UART is thrown away, at least on normal Arduino stuff - there's no handshake. You will need to read (and buffer) as it arrives without letting the Serial buffer fill up.

Hmm. That is not good. I'm not delaying after I write.

int read_resp2(char *resp) {

char result;
int num_read=0;
int num_avail;

// truncate string to start fresh
resp[0]=0;

num_avail = SerialSARA.available();
Serial.print("how much is available? ");
Serial.println(num_avail);

num_read = SerialSARA.readBytesUntil('\n', resp, num_avail);

return num_read;
}

loop() {

if (first_time) {
// List all the certs and delete them
strcpy(pchBuffer,"AT+USECMNG=3\r\n");
write_cmd(pchBuffer);
//delay(20*milliseconds);
first_time = false;
}

iRC = read_resp2(pchBuffer);
Serial.print("Response len: ");
Serial.println(iRC);
Serial.print("Response: ");
Serial.println(pchBuffer);

}

What baud rates are you using? I can see potential for problems if Serial isn't faster than SARA.

I'm using 115200. I am seeing that the loop initially sees nothing and then later does see it all. I've got some adjustments to make. Many thanks for helping me out WildBill!

WildBill said it right. SerialSARA is just a MODEM instance, you can find it in modem.cpp, 392:

ModemClass MODEM(SerialSARA, 115200, SARA_RESETN, SARA_PWR_ON, SARA_VINT);

So, you see 115200 should be ok.

I use MODEM directly to "talk" to the AT console, example:

 MODEM.send("AT+UMQTTER");
  if (MODEM.waitForResponse(1000, &response) == 1)
{do something}

My experience is you can NOT trust the output data from the AT console. Sometimes (as WildBill) mentioned the data get lost, sometimes its a timing problem (the sketch AND the AT console are writing at the same time, etc). I see no suitable way to solve this, the MODEM code must be faster?

Anyway, why do you want to achieve this?

PS: I still looking for contributors for the lib that belongs to this post...