2017-01-01 82 views
2

我一直在尝试这样做2天。我可以将GPS lat,lang作为短信发送到接收号码。然而,我现在想要的是使用GPRS发送这个。我正在使用SIM900A GSM/GPRS模块。我是软件工程专业的学生,​​我对Arduino颇为陌生。这是我使用GSM的代码。与Arduino uno一起使用SIM900a将GPS位置发送到使用GPRS的服务器

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

TinyGPS gps; 
SoftwareSerial ss(5, 6); 

static void smartdelay(unsigned long ms); 

void setup() 
{ 
    Serial.begin(115200); 
    ss.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); 
    sendLatLang(flat, flon); 

    gps.stats(&chars, &sentences, &failed); 
    Serial.println(); 

    smartdelay(1000); 
} 

static void smartdelay(unsigned long ms) 
{ 
    unsigned long start = millis(); 
    do 
    { 
    while (ss.available()) 
     gps.encode(ss.read()); 
    } while (millis() - start < ms); 
} 

static void sendLatLang(float lat, float lang) 
{ 
    if (lat == TinyGPS::GPS_INVALID_F_ANGLE || lang == TinyGPS::GPS_INVALID_F_ANGLE) { 
Serial.println("Searching for GPS fix..."); 
    } else { 
    Serial.println("AT+CMGF=1"); 
    delay(1000); 
    Serial.println("AT+CMGS=\"+94123445678\""); 
    delay(1000); 
    Serial.print("Latittude : "); 
    Serial.println(lat); 
    Serial.print("Longitude : "); 
    Serial.println(lang); 
    Serial.write(26); 
    delay(1000); 
    } 
} 

回答

2

首先,SoftwareSerial是非常非常低效的。它会长时间禁用中断,干扰素描的其他部分。

总结this answer

  • AltSoftSerial是最好的,但它仅适用于针脚8 & 9(上UNO)。
  • NeoSWSerial是次佳。它适用于任何两个引脚,但它仅支持波特率9600,19200和38400

其次,你的,因为你的程序会谈到两个设备,你必须要小心使用delay或“堵”在任何地方你的程序。虽然该程序“卡住”在delay,没有其他任何正在处理。 GPS字符继续进入,并且它们最终会溢出输入缓冲区(64个字符的限制)。 smartDelay函数试图解决这个问题。

您应该使用Finite-state Machine来处理发送,而无需致电delay。每次通过loop时,FSM都会检查是否该做下一步了。对于发送过程的每个“步骤”(即,当前“状态”),这是非常容易实现的,其中switch陈述和case

即使FSM“等待”了一段时间,这允许循环不断处理所有的GPS角色。 FSM未使用delay,它经常检查millis()以查看时间是否已过。它根据loop检查一次。

我也推荐使用我的NeoGPS库。它比所有其他库更小,更快,更准确,它可以配置为只解析您真正使用的字段和NMEA消息。如果您想尝试它,可以从Arduino IDE菜单草图 - >包括库 - >管理库

这是你的草图的NeoGPS版本:

#include <NeoSWSerial.h> 
#include <NMEAGPS.h> 

NMEAGPS gps; 
NeoSWSerial gps_port(5, 6); 

enum state_t { WAITING_TO_SEND, SENDING_CMD1, SENDING_CMD2 }; // valid FSM states 
state_t state;  // current FSM state 
uint32_t stateTime; // FSM timer for delays between states 

bool  newData = false; // true when a fix with a location is ready 
gps_fix fixToSend; 
const uint32_t SEND_INTERVAL = 60 * 1000UL; // once a minute 

void setup() 
{ 
    Serial.begin(115200); 
    gps_port.begin(9600); 
} 

void loop() 
{ 
    // Always process GPS characters so the latest fix is ready to go 
    while (gps.available(gps_port)) { 
    gps_fix newFix = gps.read(); 

    if (newFix.valid.location) { 
     newData = true; 
     fixToSend = newFix; 
    } 
    } 

    // FSM for sending fixes 
    switch (state) { 

    case WAITING_TO_SEND: 
     // Don't send new data too often. 
     if (newData && (millis() - stateTime >= SEND_INTERVAL)) { 
     Serial.println(F("AT+CMGF=1")); 
     stateTime = millis(); 
     state  = SENDING_CMD1; 
     } 
     break; 

    case SENDING_CMD1: 
     // Delay 1 second after the CMGF command 
     if (millis() - stateTime >= 1000) { 
     Serial.println(F("AT+CMGS=\"+94123445678\"")); 
     stateTime = millis(); 
     state  = SENDING_CMD2; 
     } 
     break; 

    case SENDING_CMD2: 
     // Delay 1 second after the CMGS command... 
     if (millis() - stateTime >= 1000) { 
     // ... then send the message 
     sendFix(fixToSend); 
     Serial.write(26); // no more data to send 

     newData = false; 
     stateTime = millis(); 
     state  = WAITING_TO_SEND; 
     } 
     break; 
    } 
} 


static void sendFix(const gps_fix &fix) 
{ 
    // Send only the fix pieces of interest 
    // (other pieces described on Data Model page) 

    Serial.print(F("Latitude : ")); 
    Serial.println(fix.latitude(), 6); 
    Serial.print(F("Longitude : ")); 
    Serial.println(fix.longitude(), 6); 
} 

你原来的程序中使用的8896个字节的程序空间和564个字节的RAM。 NeoGPS版本使用字节的程序空间和字节的RAM。

即使您不使用NeoGPS,也请务必阅读故障排除页面。它描述了很多常见的问题,通常与程序结构和时间有关。

P.S.请注意,F宏用于“双引号”字符串常量......这样可以通过强制使用FLASH存储器来保存RAM。草图还有一个SENDING_INTERVAL以避免每秒发送经纬度信息。:P

+0

非常感谢您的回复!我会尝试所有你提到的事情并尽快报告。 –

相关问题