2017-01-01 19 views
2

私は2日間これをやろうとしています。私は受信番号にテキストメッセージとしてGPS lat、langを送ることができます。しかし、今私が欲しいのはGPRSを使ってこれを送ることです。私はSIM900A GSM/GPRSモジュールを使用しています。私はソフトウェアエンジニアリングの学生です。私はArduinoにはかなり新しいです。これはGSMを使用する私のコードです。Arduino unoとSIM900aを使用して、GPRSを使用してサーバーにGPS位置を送信する

#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は最高ですが、それだけで(UNOに)ピン8 & 9上で動作します。
  • NeoSWSerialは次善です。これは、任意の2本のピンに動作しますが、それだけでボーレート9600、19200および38400

セカンドをサポートし、あなたの二つのデバイスへのプログラムの会談ので、あなたはどの部分でdelayまたは「ブロッキング」使用について注意する必要がありますあなたのプログラムの。プログラムがdelayに「スタック」している間は、他に何も処理されていません。 GPS文字は引き続き入力され、最終的に入力バッファ(64文字の制限)をオーバーフローします。 smartDelay関数はそれを回避しようとします。

を呼び出すことなく、送信を処理するにはFinite-state Machineを使用する必要があります。 loopを使用するたびに、FSMは次の手順を実行するかどうかを確認します。これは、送信プロセスの各「ステップ」(すなわち、現在の「状態」)について、switchステートメントとcaseステートメントを使用して実装するのが非常に簡単です。

これは、FSMがしばらくの間「待っている」場合でも、ループが常にすべてのGPS文字を処理できるようにします。 FSMはdelayを使用していませんが、時間が経過したかどうかを確認するために常にmillis()をチェックしています。 loopごとに1回点検します。

NeoGPSライブラリの使用をおすすめします。他のすべてのライブラリよりも小さく、速く、正確です。実際に使用するフィールドとNMEAメッセージだけを解析するように設定できます。試してみたい方は、ArduinoのIDEメニューSketch - >ライブラリを含める - >ライブラリの管理から入手できます。

#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バイトとRAMの564バイトを使用:

はここにあなたのスケッチのNeoGPSバージョンです。 NeoGPSバージョンは、バイトのプログラム領域とバイトのRAMを使用します。

NeoGPSを使用しない場合でも、トラブルシューティングのページを必ずお読みください。これは、通常、プログラムの構造とタイミングに関連する多くの一般的な問題を記述します。

P.S. Fマクロが "二重引用符"の文字列定数で使用されていることに注意してください。これにより、FLASHメモリからRAMを強制的に使用してRAMを節約します。スケッチはSENDING_INTERVALも持ち、毎秒緯度/経度のメッセージを送信しないようにしています。:P

+0

返信いただきありがとうございます!あなたが言及したすべてのことを試し、すぐに報告します。 –

関連する問題