I am getting the string length value Zero, when I want to check the length.
Longitude and Latitude are showing as expected. But the string length not showing correctly and always showing as Zero.
The below is the sketch
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define DEBUG true
#define PIN_TX 4
#define PIN_RX 5
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);
String strlat;
String strlon;
void setup(){
mySerial.begin(9600);
Serial.begin(9600);
mySerial.println("AT+CIPSHUT");
ShowSerialdata();
mySerial.println("AT+CIPMUX=0");
ShowSerialdata();
mySerial.println("AT+CGATT=1");
ShowSerialdata();
delay(1000);
mySerial.println("AT+CIPMODE=1");
ShowSerialdata();
delay(1000);
mySerial.println("AT+CSTT=\"airtelgprs.com\",\"\",\"\"");
ShowSerialdata();
delay(1000);
mySerial.println("AT+CIICR");
ShowSerialdata();
delay(2000);
mySerial.println("AT+CIFSR");
ShowSerialdata();
delay(1000);
mySerial.println( "AT+CGNSPWR=1");
ShowSerialdata();
delay(2000);
//mySerial.println( "AT+CGNSSEQ=GGA");
mySerial.println("AT+CIPSPRT=1");
//mySerial.println("AT+CIPSTART=\"TCP\",\"xx.xx.xx.xx\",\"4001\"");
//ShowSerialdata();
delay(2000);
}
void loop(){
if (sim808.getGPS()) {
//Serial.print("latitude :");
Serial.println(sim808.GPSdata.lat);
read_String_lat();
Serial.println(strlat); // Value is coming as expected
Serial.println(strlen(strlat)); /// Here I am getting Zero length
//Serial.print("longitude :");
Serial.print(sim808.GPSdata.lon);
read_String_lon();
Serial.println(strlon); // Value is coming as expected
Serial.println(strlon.length()); /// Here I am getting Zero length
}
}
void ShowSerialdata()
{
if (mySerial.available())
{
while (mySerial.available() != 0)
{
Serial.write(mySerial.read());
}
}
if (Serial.available())
{
while (Serial.available() != 0)
{
mySerial.write(Serial.read());
}
}
}
void read_String_lat()
{
if (Serial.available() > 0)
{
strlat = Serial.readStringUntil('\n');
}
}
void read_String_lon()
{
if (Serial.available() > 0)
{
strlon = Serial.readStringUntil('\n');
}
}
If Serial.println(strlat); is really the line of code displaying the Value in the console (and not an echo mode that you used to empty buffers with ShowSerialdata() then it’s 100% sure - if the next line in code is Serial.println(strlat.length()); - that you’ll see proper length.
I would be tempted to think that if this is what you have done then your first print is not the one displaying the string and your strlat = Serial.readStringUntil('\n'); never executed or timed out because you emptied the buffer elsewhere
To find out you can print something else in the loop like
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.
while (Serial.available())
{
for (byte i=0; i<19; i++)
strlat[i] = Serial.read();
Serial.println(strlen(strlat));
}
You can’t expect to read super fast 19 bytes when you only tested for the availability of possibly only 1 being there (especially at 9600 bauds your for loop spins so much faster than bytes are coming in so you exit the for loop, go back to the while and if by “luck” a ext byte has arrived then you start over for another 19 bytes... won’t work)
Also Don’t forget that a c-string needs to be null (’\0’) terminated to be well formed and to use it with c-string functions like strlen()
Study Serial Input Basics to understand how to correctly handle the serial port and the fact it is asynchronous and study also some of the typical c-string functions from stdlib.h and string.h
while (Serial.available())
{
for (byte i=0; i<19; i++) strlat[i] = Serial.read();
...
as you still read 19 bytes without any guarantee that they are available
You can't second guess what's going to happen on the Serial port by adding random delays ... dealing with the Serial port is not black magic, wait for a byte to be available, read it, deal with it. if your response is complete, proceed to next stage in your code, if response is not complete, keep listening for new bytes to come in - best done in a non active wait way for the sake of your program responsiveness.
Better go for actual sketch. It will give you the clear picture, as what I am trying to do.
The below is my new sketch. All the values are coming at serial monitor. When I am trying to store values at variable it is fails. Can you please help me to write the sketch to store values at variables please?
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define PIN_TX 4
#define PIN_RX 5
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);
char buffer[512];
char strlat[7]= {'\0'}; //char terminator
char strlon[7]= {'\0'}; //char terminator
void setup(){
mySerial.begin(9600);
Serial.begin(9600);
mySerial.println("AT");
ShowSerialdata();
delay(2000);
while(!sim808.init()) {
delay(3000);
Serial.print("Sim808 init error\r\n");
}
if( sim808.attachGPS())
Serial.println("Open the GPS power success");
else
Serial.println("Open the GPS power failure");
}
void loop(){
read_String_lat();
read_String_lon();
}
void ShowSerialdata()
{
if (mySerial.available())
{
while (mySerial.available() != 0)
{
Serial.write(mySerial.read());
}
}
if (Serial.available())
{
while (Serial.available() != 0)
{
mySerial.write(Serial.read());
}
}
}
void read_String_lat()
{
if (sim808.getGPS()) {
Serial.println(sim808.GPSdata.lat); //Here Longitude value prints at Serial Monitor properly
while (Serial.available() > 0)
{
for (byte i=0; i<6; i++)
strlat[i] = Serial.read();
// Serial.println(strlat); //No Value is coming at Serial Monitor.
}
}
}
void read_String_lon()
{
if (sim808.getGPS()) {
Serial.println(sim808.GPSdata.lon); //Here Longitude value prints at Serial Monitor properly
while (Serial.available() > 0)
{
for (byte j=0; j<6; j++)
strlon[j] = Serial.read();
//Serial.println(strlat); //No Value is coming at Serial Monitor.
}
}
}