这是我的代码,包括GSM和GPS代码。我打算在向GSM模块打电话后发送GPS坐标作为短信。两者都分开工作,但当我结合GSM和GPS代码时,它不会打印GPS坐标。
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "call.h"
#include "sms.h"
#include "TinyGPS++.h"
long lat,lon; // create variable for latitude and longitude object
SoftwareSerial gpsSerial(10, 11); // create gps sensor connection
TinyGPSPlus gps;
SMSGSM sms;
CallGSM call;
boolean started=false;
char sms_text[160];
char message[160];
char latitude[12]; char longitude[12];
void setup()
{
Serial.begin(9600);
gpsSerial.begin(9600);
if (gsm.begin(9600))
{
Serial.println("\nstatus=READY");
started=true;
}
else
Serial.println("\nstatus=IDLE");
}
void loop()
{
switch (call.CallStatus())
{
case CALL_NONE: // Nothing is happening
break;
case CALL_INCOM_VOICE : // Yes! Someone is calling us
Serial.println("RECEIVING CALL");
call.HangUp();
while(gpsSerial.available()){ // check for gps data
if(gps.encode(gpsSerial.read())){ // encode gps data
Serial.println("Latitude= ");
Serial.print(gps.location.lat(), 6);
Serial.println("Longitude= ");
Serial.print(gps.location.lng(), 6);
}
}// The gps data doesnt seem to be printed on the serial monitor
break;
case CALL_COMM_LINE_BUSY: // In this case the call would be established
Serial.println("TALKING. Line busy.");
break;
}
delay(1000);
}
答案 0 :(得分:1)
如果要处理GPS字符,则无法使用延迟。您必须每次都通过loop
不断阅读GPS字符并进行处理。
检查GPS字符后,您可以检查通话状态,但仅偶尔查看。检查呼叫状态需要一些时间,这会使GPS丢失。 GPS数据每秒完全解析一次,因此这是检查呼叫状态的好时机。
这是您的草图,修改为始终检查GPS字符,然后检查通话状态:
#include <SIM900.h>
#include <call.h>
#include <sms.h>
SMSGSM sms;
CallGSM call;
boolean started=false;
#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix; // create variable that holds latitude and longitude
// BEST:
//#include <AltSoftSerial.h>
//AltSoftSerial gpsSerial; // GPS TX to UNO pin 8 (optional: GPS RX to UNO pin 9)
// 2nd BEST:
#include <NeoSWSerial.h>
NeoSWSerial gpsSerial( 10, 11 );
void setup()
{
Serial.begin(9600);
if (gsm.begin(9600))
{
Serial.println( F("\nstatus=READY") ); // F macro saves RAM
started=true;
}
else
Serial.println( F("\nstatus=IDLE") );
gpsSerial.begin(9600);
}
void loop()
{
// Always check for GPS characters. A GPS fix will become available
// ONCE PER SECOND. After the fix comes in, the GPS device will
// be quiet for a while. That's a good time to check the phone status.
if (gps.available( gpsSerial )){
fix = gps.read(); // get latest PARSED gps data
// Display what was received
Serial.print( F("Latitude= ") );
Serial.println( fix.latitude(), 6 );
Serial.print( F("Longitude= ") );
Serial.println( fix.longitude(), 6 );
// Then check the current GSM status, ONLY ONCE PER SECOND
CheckCall();
}
//delay(1000); NEVER use delay! You will lose GPS characters.
}
void CheckCall()
{
// You can use the 'fix' structure in here, if you want.
switch (call.CallStatus())
{
case CALL_NONE: // Nothing is happening
break;
case CALL_INCOM_VOICE : // Yes! Someone is calling us
Serial.println("RECEIVING CALL");
call.HangUp();
break;
case CALL_COMM_LINE_BUSY: // In this case the call would be established
Serial.println("TALKING. Line busy.");
break;
}
}
请注意,它使用的是我的NeoGPS和NeoSWSerial库。 NeoGPS比所有其他库更小,更快,更可靠,更准确。
您应该避免使用SoftwareSerial
,因为效率非常低。当发送或接收字符时,它会长时间禁用中断。对于16MHz的Arduino,禁用1ms的中断是永恒的。除了等待角色完成之外,它无法做任何其他事情。它可能在那段时间内执行了10,000条指令。
AltSoftSerial
和NeoSWSerial
效率更高,可以同时发送和接收。
如果你可以将GPS连接到8针和8针。 9,改用AltSoftSerial
。它可以在19200年之间可靠地使用,然后在115200之间可靠地使用,具体取决于正在处理的中断数量。
如果您无法将其移至这些引脚,请改用NeoSWSerial
。它几乎和AltSoftSerial一样高效,但仍然比SoftwareSerial好多了。它可以使用任意两个引脚,但仅限波特率9600,19200和38400。
要在这两个引脚上使用NeoSWSerial
,您必须修改SIM900库中的文件(可能在Libraries / GSM-GPRS-GPS-Shield-GSMSHIELD目录中)。您必须搜索并替换所有出现的&#34; SoftwareSerial&#34;使用&#34; NeoSWSerial&#34;。必须更改这4个文件:
GSM.h
SIM900.h
WideTextFinder.h and cpp
NeoGPS和NeoSWSerial可从Arduino IDE库管理器中获得,菜单为Sketch - &gt;包含图书馆 - &gt;管理图书馆。示例NMEAsimple.ino和NMEAloc.ino是一个很好的起点。 Tabular.ino显示默认配置中的所有部分。