我想做的项目将使用GPS& GSM模块,使用Arduino,从GPS(GY-GPS/NEO6MV2)
获取数据并通过GSM(SIM900 GSM/GPRS Module )
发送到我的手机。我正在使用单独的GPS模块
我尝试这段代码但仍有问题。
#include <SoftwareSerial.h>
#include "SIM900.h"
#include <TinyGPS.h>
#include "sms.h"
SMSGSM sms;
TinyGPS gps;
SoftwareSerial ss(4, 3);
SoftwareSerial SIM900(7, 8);
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
String strL, strN, message, textForSMS;
char charL[10], charN[10], text[200];
int m = 1;
boolean started = false;
void setup()
{
Serial.begin(9600);
ss.begin(9600);
gsm.begin(9600);
}
void loop()
{
float flat, flon;
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
gps.f_get_position(&flat, &flon, &age);
textForSMS = "Moosa Home"; //testing gps from here
Serial.println(textForSMS);
Serial.println(flat, 6);
Serial.println(flon, 6);
Serial.print("longitude: ");
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
Serial.println("");
Serial.print("latitude : ");
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
smartdelay(1000);
Serial.println(""); //till here
delay(1000);
if (m == 5) //send sms on third reading
{
Serial.println("XXXXXXXXX"); //to check whether 'if' works
dtostrf(flat, 4, 6, charL);
for (int i = 0; i < 10; i++)
{
strL += charL[i];
}
dtostrf(flon, 4, 6, charN);
for (int i = 0; i < 10; i++)
{
strN += charN[i];
}
message = "Home";
message = message + "/nLat: ";
message = message + strL;
message = message + "/nLon: ";
message = message + strN;
message.toCharArray(text, 250);
Serial.println(text);
if (sms.SendSMS("+999999999999999", text))
{
Serial.println("\nSMS sent OK.");
}
else
{
Serial.println("\nError sending SMS.");
}
do {} while (1);
}
m++;
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs( val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_str(const char *str, int len)
{
int slen = strlen(str);
for (int i = 0; i < len; ++i)
Serial.print(i < slen ? str[i] : ' ');
smartdelay(0);
}
我收到短信
Home/nLat:1000.00000/nLon:1000.00000`
我在这段代码中的错误在哪里? 我相信Gps&amp; gsm正常工作
答案 0 :(得分:0)
使用SoftwareSerial
+ loop()
delay(1000)
结构使用TinyGPS,工作的几率非常低。 m
计数器在这里真的没用,因为loop()
将在GPS角色到达时执行1000次。做一个get_position
是没用的,因为你可能还没有任何GPS数据。
基本上,loop()
应该不断延迟运行。当一些重要的事情发生时(比如获得GPS句子的所有,或者已经过了足够的时间),那就是当你做其他工作时(比如发送短信)。 TinyGPS smartDelay
并不聪明。
您应该重新构建循环,使其看起来更像this example库中的NeoGPS。应该在该示例中digitalWrite
所在的地方执行所有非GPS工作(第62行)。那是您花时间发送短信的地方。
TinyGPS示例需要完全重写才能执行您想要的操作。它们本身很好,但很难扩展它们来做其他事情,比如发送短信。正如我所说,循环结构必须改变。
我建议看看我写的NeoGPS库,因为这些例子更加健壮。该库也使用了更少的RAM和CPU时间,但如果您只需要发送SMS消息,那么这不是一个大问题。如果您确实想尝试,请务必查看默认的SoftwareSerial
选项。
如果您使用简单的NMEAblink.ino示例,我建议您尝试使用NMEA.ino。然后将代码插入doSomeWork
函数。 loop
中的大多数内容需要进入doSomeWork
函数,当收到完整的RMC句子时,该函数仅称为 。
无论您使用哪个库,还需要检查数据是否有效。如果您的GPS没有接收任何卫星怎么办?它仍然可以发送RMC句子,但不会有任何lat / lon数据。如果位置字段无效,您可能不应该发送短信。