这是我的代码,包括GSM和GPS代码。我试图将呼叫后的SMS作为SMS发送到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);
}
如果要处理GPS字符,则不能使用延迟。您必须每次通过loop
。
检查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
,因为它效率很低。在发送或接收角色时,它会长时间中断。对于1ms,禁用中断是16MHz Arduino的永恒。除了等待角色完成外,它无能为力。它本可以在此期间执行10,000条说明。
AltSoftSerial
和NeoSWSerial
都更有效,它们可以同时发送和接收。
如果您可以将GPS连接到Pins 8&amp;9,改用AltSoftSerial
。它可以可靠地使用到19200年,然后越来越少到115200,具体取决于处理多少中断。
如果您无法将其移至这些引脚,请改用我的NeoSWSerial
。它几乎与AltsoftSerial一样有效,但仍然比软件要好得多。它可以使用任何两个引脚,但只有波特率9600、19200和38400。
注意:
要在这两个引脚上使用NeoSWSerial
,您必须在SIM900库中修改文件(可能在库/GSM-GPRS-GPS-Shield-Shield-GSMShield目录中(。您必须用" neoswserial"搜索和替换所有"软焊接"的出现。这4个文件必须更改:
GSM.h
SIM900.h
WideTextFinder.h and cpp
neogps和neoswserial可从菜单草图下的Arduino IDE库Manager获得 -> Include Library->管理库。示例nmeasimple.ino和nmealoc.ino是一个不错的起点。tabular.ino在默认配置中显示所有零件。