How to get data from gsm.WhileSimpleRead();

Hello arduino forum,

I saw an exisiting thread about this:
https://forum.arduino.cc/index.php?topic=193381.0
But no one was able to solve the problem.

I want reopen the thread discussion above as it would be a great help for me and maybe the guy who posted the thread.

This code is already on the thread above.

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
SMSGSM sms;

void setup()
{
 Serial.begin(9600);
 Serial.println("Initialising");
 if (gsm.begin(9600)){
   Serial.println("\nstatus=READY");
 }
 else Serial.println("\nstatus=IDLE");
};
void loop()
{
 gsm.SimpleWriteln("AT+CSQ");
   delay(1000);
   //Read until serial buffer is empty.
   gsm.WhileSimpleRead();
   delay(2000);
};

and also the sample output

Initialising

status=READY

OK

+CSQ: 19,0

OK

+CSQ: 19,0

OK

I want to find a way on how to get the value from gsm.WhileSimpleRead(). I tried to search on the library's documentation and what I found is that it is a void function so it returns nothing(am I right?)

From: libraries\GSMSHIELD\doc\List

void SimpleRead();
To read, and print on hardware serial, the first byte of the software serial buffer.

void WhileSimpleRead();
As SimpleRead() but read until the buffer is empty.

Thank you very much for your time.

GSMSHIELD.zip (56.3 KB)

I want to find a way on how to get the value from gsm.WhileSimpleRead().

I would start by looking at the library source. Post the function here and you may get some help.

Sorry, I attached the file a while ago in rar. I reattached it with a zip file. Thank you

Here is the function as in SIM900.cpp in the library

void SIMCOM900::WhileSimpleRead(const char* read)
{
	char datain;
	while(_cell.available()>0){
		datain=_cell.read();
		if(datain>0){
			Serial.print(datain);

		}
	}
}

It looks like it would be relatively easy to modify it to return a value but it looks like you would be better off modifying (or copying and modifying) the SimpleRead() function to return the data rather than print it.

void SIMCOM900::SimpleRead()
{
	char datain;
	if(_cell.available()>0){
		datain=_cell.read();
		if(datain>0){
			Serial.print(datain);
		}
	}
}

I am sorry but I haven't really tried to modify a library. Can you help me make another function that would perform the same function but would return a value?

Thanks in advance

Oh and I already tried to edit the library, this part of the code is not really included in the library

void SIMCOM900::WhileSimpleRead(/*const char* read*/) //const char* read is not part of the code
{
	char datain;
	while(_cell.available()>0){
		datain=_cell.read();
		if(datain>0){
			Serial.print(datain);

		}
	}
}

I'll reattach the original library later

this part of the code is not really included in the library

It is in SIM900.cpp which is one of the files in the .zip that you posted.

If you want to use the WhileSimpleRead() function as the basis for a new one then the first thing to do is to copy it to a new name in the same file and add the function definition to SIM900.h

I think that it would be easier for you to use the SimpleRead() function as the basis for the new one and deal with building the array of chars needed to hold what it reads, in your main program. In order to prove that the principle of adding a new function to the .cpp and .h files is working try printing some fixed text, even if it is only a full stop, from your new function as well as datain. If you see the text that you added then you know that you are on the right track. If not, then you can investigate why not before doing anything more complicated.

Thank you sir. I'll try it out tomorrow.

Okay, so I tried to edit the library.
First I copied SimpleRead() function and modified it to store char datain in the variable signal, but I had difficulties in retrieving all the data (by looping) in my main program.

So I tried to modify the WhileSimpleRead() and stored all the data in an array and return it to my main program.

Here is the code I added to SIM900.cpp

void SIMCOM900::SimpleRead1(char* signal)
{
	char datain;
	int i=0;
	while(_cell.available()>0){
		datain=_cell.read();
		if(datain>0){
			 //Serial.print(datain);
			 signal[i] = datain;
			 i++;
		}
	}
}

And to SIM900.h

void SimpleRead1(char* signal);

Here is the part of my program to retrieve the values in the array

gsm.SimpleWriteln("AT+CSQ");
delay(1000);
char x[12];
gsm.SimpleRead1(x);
Serial.print("Signal Strength:");
Serial.print(x[8]);
Serial.print(x[9]);
Serial.println();
Serial.print("Bit Error Rate:");
Serial.print(x[11]);
Serial.print(x[12]);

Thank you very much for your help. :slight_smile:

Hello,

I also tried this code and it works great. Thank you for it.

But I need further help. How can I put the whole data from "gsm.SimpleRead1(x);" in one variable to work with it?

Kind regards
Dieter

I also tried this code and it works great. Thank you for it.
But I need further help. How can I put the whole data from "gsm.SimpleRead1(x);" in one variable to work with it?

The "whole data" is in the 12 bytes of the char array x[12].

How big is the message being read? If it is more than 12 bytes there is a major problem with the code as it will write values into unreserved memory.

As it is the code you say works great has a major problem in that is uses the values x[11] and x[12] for "bit rate error". x[12] is not an element of the array, as array indexes begin at 0, so the char x[12] has elements which run from x[0] to x[11].

In my case there are 32 byte, but I only need from 9 to 30. It is the date and time from "AT+CCLK?".
The whole data is: "20/07/31,12:07:27+08"

After hundreds of tries and errors I found a solution that works.

Code:

{
  gsm.SimpleWriteln("AT+CCLK?");
  delay(1000);
  char x[31];
  for(int i=0; i <= 31; i++)
  {
   x[i] = (char)gsm.read();
  }
String y(x);
y.remove(0,10);
y.remove(17);

"x" is the length of the returned modem string.
"String y(x)" converts char to string
"y.remove()" removes needless characters
After that, "y" is the needed string.

Diddi68:
In my case there are 32 byte, but I only need from 9 to 30. It is the date and time from "AT+CCLK?".
The whole data is: "20/07/31,12:07:27+08"

I guess you mean 20, not 30. Avoid the String class, it can crash your machine. It's really so simple, except for the "remove 17" which you didn't explain. Otherwise, if you:

char *timeString = x + 10;

Then timeString will always consist of the characters in x[], beginning at character number 10. You can use it the same way you would use 'x', for example Serial.print(timeString). It creates a different "view" of the same array, 'x[]'.

Always avoid meaningless, single letter variables unless they are temporary variables or index variables that have limited scope, and are only used in a few lines of local code.

When you have an issue, don't look for an existing post from three years ago and add on to it. Start a new one of your own. What you have done is, "hijacking a thread" and "necro'ing a thread". Both frowned upon here.