1

so im currently trying to do a a project whereby if my sensor is active, it will display my location. but, it seems that when the sensor is active, it only display location of lat: 0.00 , long: 0.00 on my LCD display. help me to solve this problem.

#include <LiquidCrystal.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(9,10);
char msg;

int knockPin = 7;                   // Use Pin 7 as our Input
int knockVal = HIGH;                // This is where we record our shock measurement
boolean bAlarm = false;
int knockValue = digitalRead(6);
unsigned long lastKnockTime;        // Record the time that we measured a shock
int knockAlarmTime = 500;           // Number of milli seconds to keep the knock alarm high

static const int RXPin = 13, TXPin = 8;
static const int GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup ()
{
  mySerial.begin(19200);   // Setting the baud rate of GSM Module  
  delay(20000); 
  ss.begin(GPSBaud); 
  Serial.begin(115200);  
  Serial.println("GSM SIM900A BEGIN");
  pinMode (knockPin, INPUT) ;       // input from the KY-031
  pinMode (6, OUTPUT);   
  lcd.begin(16, 2);
  String latitude = String(gps.location.lat(),6);
  String longitude = String(gps.location.lng(),6);
      lcd.clear();
      lcd.setCursor(2,0);
      lcd.print("VeCAS System");
      lcd.setCursor(3,1);
      lcd.print(">>Begin>>");
      delay (5000);


}

void loop ()
{
  knockVal = digitalRead (knockPin) ; // read KY-031 Value


  if (knockVal == LOW)                // If we see a knock
  {

    lastKnockTime = millis();         // record the time of the shock
                                      // The following is so you don't scroll on the output screen
    if (!bAlarm)
    {

      Serial.println("KNOCK, KNOCK");
      bAlarm = true;
      digitalWrite (6, HIGH);
      Serial.println(knockVal);
      delay(100);

      while (ss.available() > 0)
    gps.encode(ss.read());
    if (gps.location.isUpdated())
       lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("KNOCK!");
      lcd.setCursor(3,1);
      lcd.print("Detected");
      delay (5000);

          lcd.clear();
          Serial.print("Latitude= "); 
          Serial.print(gps.location.lat(), 6);
          Serial.print(" Longitude= "); 
          Serial.println(gps.location.lng(), 6);

          lcd.setCursor(0,0);
          lcd.print("LAT:");
          lcd.setCursor(5,0);
          lcd.print(gps.location.lat());
          lcd.setCursor(0,1);
          lcd.print("LON:");
          lcd.setCursor(5,1);
          lcd.print(gps.location.lng());
          delay(1000);
          lcd.clear(); 

    }
   }


 else
  {
    if( (millis()-lastKnockTime) > knockAlarmTime  &&  bAlarm)
    {
      Serial.println("no knocks");
      bAlarm = false;
      digitalWrite (6, LOW);
      delay(100);
    }
   }
  }

void gpsTrack()
{
      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("KNOCK!");
      lcd.setCursor(3,1);
      lcd.print("Detected");
      delay (5000);

          lcd.clear();
          Serial.print("Latitude= "); 
          Serial.print(gps.location.lat(), 6);
          Serial.print(" Longitude= "); 
          Serial.println(gps.location.lng(), 6);

          lcd.setCursor(0,0);
          lcd.print("LAT:");
          lcd.setCursor(5,0);
          lcd.print(gps.location.lat());
          lcd.setCursor(0,1);
          lcd.print("LON:");
          lcd.setCursor(5,1);
          lcd.print(gps.location.lng());
          delay(1000);
          lcd.clear(); 
}
1

If you put the GPS on Serial (pins 0 & 1) and the GSM on AltSoftSerial (pins 8 & 9), it could work. You will have to disconnect pin 0 to upload new sketches over USB. I assume that you have an UNO or Nano, because you didn't say which Arduino you are using.

Like Majenko said, this will never work with two SoftwareSerial ports. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. This can interfere with other parts of your sketch or with other libraries. And it cannot send and receive at the same time. This answer provides complete details.

You may also want to take a look at my NeoGPS library. It is smaller, faster, more reliable and more accurate than all other GPS libraries. Even if you don't use it, you should read the page about choosing a serial port. There are also many tips on the Troubleshooting page.

NeoGPS, AltSoftSerial and NeoSWSerial are available from the IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

BTW, you can't use delay like that. You must constantly read and decode the GPS characters. The sketch will lose many, many GPS characters, preventing it from ever getting complete GPS information. You have to do something like this:

#include <LiquidCrystal.h>
#include <NMEAGPS.h>
#include <AltSoftSerial.h>

AltSoftSerial gsmPort; // receive pin 8 to GSM TX, transmit pin 9 to GSM RX

char msg;

int knockPin = 7;                   // Use Pin 7 as our Input
int knockVal = HIGH;                // This is where we record our shock measurement
boolean bAlarm = false;
int knockValue = digitalRead(6);
unsigned long lastKnockTime;        // Record the time that we measured a shock
int knockAlarmTime = 500;           // Number of milli seconds to keep the knock alarm high

static const int GPSBaud = 9600;
NMEAGPS gps;
gps_fix fix;
#define gpsPort Serial // RX pin 0 to GPS TX, TX pin 1 to GPS RX


const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup ()
{
  gsmPort.begin(19200);   // Setting the baud rate of GSM Module  

  gpsPort.begin(GPSBaud); 
  //Serial.begin(115200);  // gpsPort *is* serial
  //  Serial Monitor has to be set at 9600 (lower right 
  //    corner of Serial Monitor window)
  Serial.println("GSM SIM900A BEGIN");
  pinMode (knockPin, INPUT) ;       // input from the KY-031
  pinMode (6, OUTPUT);   

  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(2,0);
  lcd.print("VeCAS System");
  lcd.setCursor(3,1);
  lcd.print(">>Begin>>");
  delay( 1000 );
}

void loop ()
{
  // Check for GPS characters (always!)
  if (gps.available( gpsPort )) {
    fix = gps.read(); // save the latest GPS fields in one structure
    gpsTrack();       // show the latest GPS fields
  }

  // Check for knocks

  knockVal = digitalRead (knockPin) ; // read KY-031 Value

  if (knockVal == LOW)                // If we see a knock
  {

    lastKnockTime = millis();         // record the time of the shock
                                      // The following is so you don't scroll on the output screen
    if (!bAlarm)
    {

      bAlarm = true;
      digitalWrite (6, HIGH);

      Serial.println("KNOCK, KNOCK");
      Serial.println(knockVal);

      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("KNOCK!");
      lcd.setCursor(3,1);
      lcd.print("Detected");
    }
  }
  else
  {
    if( (millis()-lastKnockTime) > knockAlarmTime  &&  bAlarm)
    {
      Serial.println("no knocks");
      bAlarm = false;
      digitalWrite (6, LOW);
    }
  }
}

void gpsTrack()
{
  Serial.print("Latitude= "); 
  if (fix.valid.location)
    Serial.print( fix.latitude(), 6);
  Serial.print(" Longitude= "); 
  if (fix.valid.location)
    Serial.println( fix.longitude(), 6);

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("LAT:");
  lcd.setCursor(5,0);
  if (fix.valid.location)
    lcd.print( fix.latitude() );
  lcd.setCursor(0,1);
  lcd.print("LON:");
  lcd.setCursor(5,1);
  if (fix.valid.location)
    lcd.print( fix.longitude() );
}

Notice that it also checks the location validity flag before using the lat/lon values. Your GPS may not know the location, perhaps due to bad satellite reception.

  • Thank you for ur answer. i am using board Uno. so i try to use ur code, but it wont work since it is board Uno. – eric May 11 '18 at 15:24
  • Oh, yes, you must run your Serial Monitor at 9600, not 115200 (I edited that line above). Then it will work on an UNO IF you connect the GPS to pins 0 & 1, as described. It does not send/receive anything to the GSM, so that doesn't matter. Read the link on "choosing a serial port". – slash-dev May 11 '18 at 19:48
  • I get this error message. Error compiling for board Arduino/Genuino Uno. why ? huhu – eric May 12 '18 at 14:18
  • haha sorry i forgot to download the library. – eric May 12 '18 at 14:38
0

You have two SoftwareSerial ports. You can't reliably use two of them at once. Only one can be set to receive data, and that one is the first one you define. You can switch between them with the listen() function, but it's not recommended. If you never want to receive on one of them then it's (almost) fine, but when sending on any of them nothing can be received anywhere (not even on the hardware Serial port).

Adding to setup() after ss.begin(GPSBaud):

ss.listen();

may make it work for the time being, but as soon as you start doing anything more with mySerial you could run into trouble.

If you need more than one serial port in your design then you really should be looking at using a more capable board with more hardware UART ports.

  • yeah i try to put ss.listen(); after ss.begin(GPSBaud) but it error. – eric May 10 '18 at 10:41

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.