ارتباط GNSS در آردوینو و تبدیل NMEA به URL گوگل

با سلام خدمت شما بنده با آردوینو میخواهم کدی بنویسم که موقعیت مکانی را از طریق at command از mc60 بگیرد و با لینک گوگل ادغام کرده و آن را با پیامک ارسال کند به زبان آردوینو بدین صورت:(http://maps.google.com/maps?q=loc:xxxx,xxxxx) فرمت NMEA رو کامل دریافت میکنم و مشکلم توی برنامه نویسی تبدیل آن به LAT&LONG اگر امکانش هست کدی رو برای بنده بنویسید که ابتدا AT+QGNSSRD? نوشته بشه و در جواب LAT&LONG رو داخل لینک بهم تو سریال مانیتور بده

سلام
باید ابتدا فرمت NMEA رو Parse بفرماید.
برای این کار از کتابخانه های آماده میتونید استفاده کنید. هر چند Parse کردن Nmea کار سختی نیست به عنوان مثال:
با دستور strstr میتوانید در رشته دریافتی به دنبال RMC باشید - RMC یکی از پکت های NMEA هست که مقدار طول و عرض داخلش هست.
در لینک زیر نوع فرمت RMC هست. (البته داخل داکیومنت GNSS خود MC60 هم هست )
فرمت RMC

میتونید به شکل زیر این کار رو بکنید:
1-ابتدا با strstr به دنبال "RMC " باشید نیاز به Include string.h - لینک آموزشی
2- سپس با sscanf دیتا های داخل رشته را استخراج کنید نیاز به Include stdio.h . لینک آموزشی

3- پس از استخراج دیتا های مد نظر تون از RMC با دستور sprintf یک پکت جدید بسازید. :slight_smile:
لینک آموزشی

خودتون با لینک ها کار کنید اگر نیاز داشتید به سمپل کد بگید که براتون یک نمونه بگزارم.

3 پسندیده

تا اینحا تونستم تفکیکش کنم ولی تبدیلش parse نتونستم ، این کد من هست. لطفا بررسی کنید ممنونم

#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(4, 3);  // تعریف سریال نرم‌افزاری برای ارتباط با ماژول GPS
String sentence;
double latitude, longitude;
void extractCoordinates(String sentence);
void processString(const String &inputString);
void setup() {
  Serial.begin(9600);  
  gpsSerial.begin(9600);
  gpsSerial.print("AT+QGNSSRD?\r");
}

void loop() {
  
  if (gpsSerial.available()) {

   sentence = gpsSerial.readString();
   Serial.print(sentence);

    processString(sentence);
    
  }
}

void extractCoordinates(String sentence) {
  int startIndex = sentence.indexOf(",", 15) + 1;
  int endIndex = sentence.indexOf(",", startIndex);
  String latitudeStr = sentence.substring(startIndex, endIndex);

  startIndex = endIndex + 1;
  endIndex = sentence.indexOf(",", startIndex);
  String longitudeStr = sentence.substring(startIndex, endIndex);

  latitude = atof(latitudeStr.c_str());
  longitude = atof(longitudeStr.c_str());
}

void processString(const String &inputString) {
  char charArray[inputString.length() + 1];
  inputString.toCharArray(charArray, sizeof(charArray));

  char *token = strtok(charArray, ",");
  while (token != NULL) {
    
    if (strcmp(token, "A") == 0) {
      token = strtok(NULL, ",");
      if (token != NULL) {
        Serial.print("عرض جغرافیایی: ");
        Serial.println(token);
      }
    }


    if (strcmp(token, "N") == 0) {
      token = strtok(NULL, ",");
      if (token != NULL) {
        Serial.print("طول جغرافیایی: ");
        Serial.println(token);
      }
    }

    token = strtok(NULL, ",");
  }
}

سلام
کد تون رو بررسی کردم. چند باگ داره.
راه حل ساده ولی کاربردی میتونه راه کار زیر باشه:
ابتدا در حلقه اصلی کد خودتون مطابق تصویر زیر عمل کنید و دیتا های خروجی از serial رو درون متغیر شبیه به _str ذخیره و سپس به همراه دو ادرس متغیر float به فانکش با نام _procces_nmea_rmc پاس بدهید:

همچنین در کد زیر اگر کاربر انسانی دستور getlocation را در پورت سریال بنویسد یک پکت از اخرین موقع ایجاد میکند. و برایش پرینت میکند.
دقت داشته باشید برای قسمت last_zn من یک مقدار پیش فرض مثلا 17 قرار دادم نسبت به موقعیت شهر اصفهان که در تصویر سوم مشاهده خواهید کرد. که همچنین برای محاسبه خود ان در انتهای مطلب لینک قرار میدهم.
** دقت شود قسمت های از کد رو باید خودتان اضافه کنید که به صورت کامنت مشخص شده.


سپس بدنه فانکشن تحلیل NMEA-> RMC


خب حالا باید نگاهی کنیم به ساختار یک لینک

خب برای مطالعه نحوه محاسبه zone در کد یعنی متغییر last_zn باید لینک زیر رو مطالعه کنید و براش خودتون بنویسید: (دقت داشته باشید کـــــ ممکنه نیاز باشه لینک زیر رو با V-P-N باز کنید)

Link+

همچنین برای آماده کردن این پاسخ برای شما دوست عزیز از لینک زیر برای اشنایی با api های سریال آردوینو استفاده کردم :
arduino_serial_api

1 پسندیده