-1

I've got an Arduino Uno, SIM900 GPRS, and the Adafruit Breakout GPS.

Can this code be optimized?

#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <Ubidots_Arduino_GPRS.h>
//Serial Relay - Arduino will patch a 
//serial link between the computer and the GPRS Shield
//at 19200 bps 8-N-1
//Computer is connected to Hardware UART
//GPRS Shield is connected to the Software UART 
#define APN "myapn" 
#define USER ""  // If your apn doesnt have username just put ""
#define PASS ""  // If your apn doesnt have password just put ""
#define TOKEN "ubidotsToken"  // Replace it with your Ubidots token
#define ID "Your_id_here" // Replace it with your Ubidots' variable ID
// You can send 1 to 10 variable at the same time
#define ID1 "idHere" // Replace it with your variable ID
//#define ID2 "" // Replace it with your variable ID
//#define ID3 "Your_id_here" // Replace it with your variable ID

TinyGPSPlus gps; // The TinyGPS++ object for interfacing with the GPS
//Declare indexes, and strings
char latitude[12];
char longitude[12];
float value_1 = 1;
char var[18] = "Lat: ";
char var2[18] = "Long: ";
Ubidots client(TOKEN);  
SoftwareSerial ss(2,3);
void setup() {

// the Serial port of Arduino baud rate.
  Serial.begin(9600);               

  client.powerUpOrDown();
  client.setApn(APN,USER,PASS);
//.endC is for _client.end() in Ubidots_GPRS.cpp
  client.endC();
  ss.begin(9600);
}

void loop() {

  //handling GPS data parsing
  while (ss.available() > 0) {
    gps.encode(ss.read());}
  //Once a valid location comes up it updates Lat/Long variables
   if (gps.location.isUpdated())
{
    strcpy(var, "Lat: ");
    strcpy(var2,"Long: ");

    dtostrf(gps.location.lat(),10,6,latitude);
    strcat(var, latitude);

    dtostrf(gps.location.lng(),10,6,longitude);
    strcat(var2, longitude);
  //Added ss.flush();
    ss.flush();
    ss.end();
    Serial.flush()
  //Added client.beginC() for _client.begin(9600) is Ubidots_GPRS.cpp
    client.beginC();
    client.add(ID1, value_1, var, var2);
    client.sendAll();
    client.endC();
    ss.begin(9600);
  }
 Serial.println(var);
 Serial.println(var2);
}

From this link, I moved the println from inside .isUpdated() to outside the if statement. I was able to get GPS data sent from the unit to my Ubidots account while driving around town. Afterwards I was able to input the data into Google Maps and the route produced was accurate. Do I need flush()?

  • A simple test: comment all the code concerned with sending the data over GPRS and run the sketch again. Are the GPS values printed without errors to the monitor? – TisteAndii Mar 20 '16 at 19:27
  • I commented out .add() and .sendAll(), and the GPS values are being updated without error. – roe-el Mar 20 '16 at 19:38
  • I have edited my post again. – roe-el Mar 21 '16 at 1:21
  • From what you say, everything works. I was going to add a few listen()s in your code but this approach is also alright. If all you want to do is optimize the code, you could save the APN settings permanently to the sim900. Just add client.println("AT&W") at the end of setApn() and use readData() to ensure OK was received. Run the sketch and then you can comment out the setApn() call in setup(). Also provide a link to your updated library with its new functions. – TisteAndii Mar 21 '16 at 5:42
  • Yes, it does work. Here is the link to my forked repository with the changes I have made so far. The code is in examples/SaveValuesGPS – roe-el Mar 21 '16 at 14:53
0

It seems you're using the same hardware Serial port for both your PC and the GPS module. This will result in the GPS module receiving everything you send to the PC with Serial.print() and this may be the cause of your problem, as it could confuse the module and either make it send an endless stream of gibberish and/or making isValid() to always be false. You should instead create a SoftwareSerial instance attached to any 2 digital pins (maybe 2 and 3) like this:

SoftwareSerial ss(2, 3);

and in setup():

ss.begin(9600);  // use your module baud rate

Then at the top of loop(), use this instead:

while (ss.available() > 0)
    gps.encode(ss.read());

Get rid of the recursive call of loop() within loop() since it will cause your stack to rapidly overflow.

If you want data to only be sent when the location values are updated based on recent received data (but not necessarily changed, since you may still be at the same location), you should use if (gps.location.isUpdated()) instead.

Your call of dtostrf() is also wrong. The second argument should be the length of the string to be created (including decimal point) and the 3rd argument should be the number of digits after the decimal point. Something like this should be okay:

dtostrf(gps.location.lat(), 10, 6, latitude); 

You can also put this at the end of loop() to check if data is actually being received from the module and processed by the library:

if (millis() > 5000 && gps.charsProcessed() < 10)
  Serial.println(F("WARNING: No GPS data.  Check wiring."));
  while (1){ // infinite loop
    if (ss.available())
      Serial.print(ss.read());
  }
}    

This site may provide additional details.

  • Thank you for your input. I have made the changes you suggested. I'm getting errors from serial monitor, but it may be I made a mistake in the one of the changes. void setup() { // the Serial port of Arduino baud rate. Serial.begin(9600); ss.begin(9600); client.powerUpOrDown(); client.setApn(APN,USER,PASS); } – roe-el Mar 19 '16 at 0:10
  • What errors exactly? did you connect the RX of the gps module to pin 3 of the arduino and its TX to pin 2? – TisteAndii Mar 19 '16 at 0:17
  • Yes. If I run it with Serial.begin() first in setup() it will work, and with ss.begin() last it will parse data. But within .isUpdated() it will display error when trying to run .add(). – roe-el Mar 19 '16 at 0:19
  • What error are you getting exactly? How do you know it parses data? is the gps data changing (as you change your location) and being displayed by the Serial.print()s? – TisteAndii Mar 19 '16 at 0:30
  • It will get a fix and show the coordinates in the serial monitor. I know there is an error because the .add() is displaying the error string "Error with AT+CSQ" on the serial monitor. It only seems to be working depending on where Serial.begin() and ss.begin() are located in setup(). void setup() { // the Serial port of Arduino baud rate. Serial.begin(9600); client.powerUpOrDown(); client.setApn(APN,USER,PASS); ss.begin(9600); } – roe-el Mar 19 '16 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.