18935浏览
查看: 18935|回复: 64

[项目] 【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块

[复制链接]
第二部分 传感器(输入模块)
第八章 通讯类模块
8.6 GY-NEO6MV2飞控GPS模块
8.6 GY-NEO6MV2飞控GPS模块的实物照片

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图2

驴友花雕  中级技神
 楼主|

发表于 2022-5-29 13:44:59

程序九:测试 TinyGPSPlus 的几乎所有功能
1Arduino参考开源代码

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   程序九:测试 TinyGPSPlus 的几乎所有功能
  4. */
  5. #include <TinyGPSPlus.h>//导入驱动库
  6. #include <SoftwareSerial.h>
  7. static const int RXPin = 9, TXPin = 8;//定义软串口接脚
  8. static const uint32_t GPSBaud = 9600;
  9. // TinyGPSPlus 对象
  10. TinyGPSPlus gps;
  11. //与 GPS 设备的串行连接
  12. SoftwareSerial ss(RXPin, TXPin);
  13. // 对于每 5 秒发生一次的统计数据
  14. unsigned long last = 0UL;
  15. void setup() {
  16.   Serial.begin(9600);
  17.   ss.begin(GPSBaud);
  18.   Serial.println(F("KitchenSink.ino"));
  19.   Serial.println(F("测试 TinyGPSPlus 的几乎所有功能"));
  20.   Serial.print(F("测试 TinyGPSPlus 库 v."));
  21.   Serial.println(TinyGPSPlus::libraryVersion());
  22.   Serial.println(F("GY-NEO6MV2模块准备就绪"));
  23.   Serial.println();
  24. }
  25. void loop(){
  26.   // 调度传入的字符
  27.   while (ss.available() > 0)
  28.     gps.encode(ss.read());
  29.   if (gps.location.isUpdated())
  30.   {
  31.     Serial.print(F("LOCATION   Fix Age="));
  32.     Serial.print(gps.location.age());
  33.     Serial.print(F("ms Raw Lat="));
  34.     Serial.print(gps.location.rawLat().negative ? "-" : "+");
  35.     Serial.print(gps.location.rawLat().deg);
  36.     Serial.print("[+");
  37.     Serial.print(gps.location.rawLat().billionths);
  38.     Serial.print(F(" billionths],  Raw Long="));
  39.     Serial.print(gps.location.rawLng().negative ? "-" : "+");
  40.     Serial.print(gps.location.rawLng().deg);
  41.     Serial.print("[+");
  42.     Serial.print(gps.location.rawLng().billionths);
  43.     Serial.print(F(" billionths],  Lat="));
  44.     Serial.print(gps.location.lat(), 6);
  45.     Serial.print(F(" Long="));
  46.     Serial.println(gps.location.lng(), 6);
  47.   }
  48.   else if (gps.date.isUpdated())
  49.   {
  50.     Serial.print(F("DATE       Fix Age="));
  51.     Serial.print(gps.date.age());
  52.     Serial.print(F("ms Raw="));
  53.     Serial.print(gps.date.value());
  54.     Serial.print(F(" Year="));
  55.     Serial.print(gps.date.year());
  56.     Serial.print(F(" Month="));
  57.     Serial.print(gps.date.month());
  58.     Serial.print(F(" Day="));
  59.     Serial.println(gps.date.day());
  60.   }
  61.   else if (gps.time.isUpdated())
  62.   {
  63.     Serial.print(F("TIME       Fix Age="));
  64.     Serial.print(gps.time.age());
  65.     Serial.print(F("ms Raw="));
  66.     Serial.print(gps.time.value());
  67.     Serial.print(F(" Hour="));
  68.     Serial.print(gps.time.hour());
  69.     Serial.print(F(" Minute="));
  70.     Serial.print(gps.time.minute());
  71.     Serial.print(F(" Second="));
  72.     Serial.print(gps.time.second());
  73.     Serial.print(F(" Hundredths="));
  74.     Serial.println(gps.time.centisecond());
  75.   }
  76.   else if (gps.speed.isUpdated())
  77.   {
  78.     Serial.print(F("SPEED      Fix Age="));
  79.     Serial.print(gps.speed.age());
  80.     Serial.print(F("ms Raw="));
  81.     Serial.print(gps.speed.value());
  82.     Serial.print(F(" Knots="));
  83.     Serial.print(gps.speed.knots());
  84.     Serial.print(F(" MPH="));
  85.     Serial.print(gps.speed.mph());
  86.     Serial.print(F(" m/s="));
  87.     Serial.print(gps.speed.mps());
  88.     Serial.print(F(" km/h="));
  89.     Serial.println(gps.speed.kmph());
  90.   }
  91.   else if (gps.course.isUpdated())
  92.   {
  93.     Serial.print(F("COURSE     Fix Age="));
  94.     Serial.print(gps.course.age());
  95.     Serial.print(F("ms Raw="));
  96.     Serial.print(gps.course.value());
  97.     Serial.print(F(" Deg="));
  98.     Serial.println(gps.course.deg());
  99.   }
  100.   else if (gps.altitude.isUpdated())
  101.   {
  102.     Serial.print(F("ALTITUDE   Fix Age="));
  103.     Serial.print(gps.altitude.age());
  104.     Serial.print(F("ms Raw="));
  105.     Serial.print(gps.altitude.value());
  106.     Serial.print(F(" Meters="));
  107.     Serial.print(gps.altitude.meters());
  108.     Serial.print(F(" Miles="));
  109.     Serial.print(gps.altitude.miles());
  110.     Serial.print(F(" KM="));
  111.     Serial.print(gps.altitude.kilometers());
  112.     Serial.print(F(" Feet="));
  113.     Serial.println(gps.altitude.feet());
  114.   }
  115.   else if (gps.satellites.isUpdated())
  116.   {
  117.     Serial.print(F("SATELLITES Fix Age="));
  118.     Serial.print(gps.satellites.age());
  119.     Serial.print(F("ms Value="));
  120.     Serial.println(gps.satellites.value());
  121.   }
  122.   else if (gps.hdop.isUpdated())
  123.   {
  124.     Serial.print(F("HDOP       Fix Age="));
  125.     Serial.print(gps.hdop.age());
  126.     Serial.print(F("ms raw="));
  127.     Serial.print(gps.hdop.value());
  128.     Serial.print(F(" hdop="));
  129.     Serial.println(gps.hdop.hdop());
  130.   }
  131.   else if (millis() - last > 5000)
  132.   {
  133.     Serial.println();
  134.     if (gps.location.isValid())
  135.     {
  136.       static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  137.       double distanceToLondon =
  138.         TinyGPSPlus::distanceBetween(
  139.           gps.location.lat(),
  140.           gps.location.lng(),
  141.           LONDON_LAT,
  142.           LONDON_LON);
  143.       double courseToLondon =
  144.         TinyGPSPlus::courseTo(
  145.           gps.location.lat(),
  146.           gps.location.lng(),
  147.           LONDON_LAT,
  148.           LONDON_LON);
  149.       Serial.print(F("伦敦       距离="));
  150.       Serial.print(distanceToLondon / 1000, 6);
  151.       Serial.print(F(" km Course-to="));
  152.       Serial.print(courseToLondon, 6);
  153.       Serial.print(F(" degrees ["));
  154.       Serial.print(TinyGPSPlus::cardinal(courseToLondon));
  155.       Serial.println(F("]"));
  156.     }
  157.     Serial.print(F("DIAGS      Chars="));
  158.     Serial.print(gps.charsProcessed());
  159.     Serial.print(F(" Sentences-with-Fix="));
  160.     Serial.print(gps.sentencesWithFix());
  161.     Serial.print(F(" Failed-checksum="));
  162.     Serial.print(gps.failedChecksum());
  163.     Serial.print(F(" Passed-checksum="));
  164.     Serial.println(gps.passedChecksum());
  165.     if (gps.charsProcessed() < 10)
  166.       Serial.println(F("警告:没有 GPS 数据,检查接线。"));
  167.     last = millis();
  168.     Serial.println();
  169.   }
  170. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-6-4 08:47:07

程序十三:在OLED上显示日期、时间、纬度和经度
1)Arduino参考开源代码

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   程序十三:在OLED上显示日期、时间、纬度和经度
  4. */
  5. #include <TimeLib.h>//导入驱动库
  6. #include <TinyGPS++.h>
  7. #include <SoftwareSerial.h>
  8. #include <U8glib.h>
  9. //用于连接GY-NEO6MV2模块的引脚D9/D8
  10. static const int RXPin = 9, TXPin = 8;
  11. // TinyGPS++ 对象
  12. TinyGPSPlus gps;
  13. // GPS模块的串口连接
  14. SoftwareSerial Serial_GPS(RXPin, TXPin);
  15. //OLED显示设置
  16. U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_FAST);
  17. void draw() {
  18.   //设置时间/时区
  19.   GPS_Timezone_Adjust();
  20.   //显示的图形命令必须放在这里aqui
  21.   u8g.setFont(u8g_font_8x13B);
  22.   u8g.drawRFrame(0, 0, 128, 64, 4);
  23.   //日期线
  24.   u8g.drawStr(10, 14, "D:        ");
  25.   u8g.setPrintPos(34, 14);
  26.   //显示日期
  27.   if (day() < 10)
  28.   {
  29.     u8g.print("0");
  30.   }
  31.   u8g.print(day());
  32.   u8g.drawStr(51, 14, "/");
  33.   u8g.setPrintPos(60, 14);
  34.   //显示月份
  35.   if (month() < 10)
  36.   {
  37.     u8g.print("0");
  38.   }
  39.   u8g.print(month());
  40.   u8g.drawStr(76, 14, "/");
  41.   u8g.setPrintPos(85, 14);
  42.   //显示年份
  43.   u8g.print(year());
  44.   // 时间线
  45.   u8g.drawStr(10, 29, "H:        ");
  46.   u8g.setPrintPos(45, 29);
  47.   //开始时间
  48.   if (hour() < 10)
  49.   {
  50.     u8g.print("0");
  51.   }
  52.   u8g.print(hour());
  53.   u8g.drawStr(61, 28, ":");
  54.   u8g.setPrintPos(70, 29);
  55.   //显示分钟
  56.   if (minute() < 10)
  57.   {
  58.     u8g.print("0");
  59.   }
  60.   u8g.print(minute());
  61.   u8g.drawStr(86, 28, ":");
  62.   u8g.setPrintPos(95, 29);
  63.   //显示秒数
  64.   if (second() < 10)
  65.   {
  66.     u8g.print("0");
  67.   }
  68.   u8g.print(second());
  69.   //纬度
  70.   u8g.drawStr(10, 44, "Lat:         ");
  71.   u8g.setPrintPos(45, 44);
  72.   u8g.print(gps.location.lat(), 5);
  73.   //经度
  74.   u8g.drawStr(10, 59, "Lon:         ");
  75.   u8g.setPrintPos(45, 59);
  76.   u8g.print(gps.location.lng(), 5);
  77. }
  78. //根据地区调整时区
  79. const int UTC_offset = -3;
  80. void setup() {
  81.   // Arduino 波特率
  82.   Serial.begin(9600);
  83.   //波特率GPS模块
  84.   Serial_GPS.begin(9600);
  85.   //在串口监视器上显示初始信息
  86.   Serial.println(F("日期、时间、纬度和经度"));
  87.   Serial.println(F("GPS 模块 GY-NEO6MV2"));
  88.   Serial.print(F("TinyGPS++ 驱动库 v."));
  89.   Serial.println(TinyGPSPlus::libraryVersion());
  90.   Serial.println();
  91.   //OLED显示设置
  92.   if ( u8g.getMode() == U8G_MODE_R3G3B2 )
  93.   {
  94.     u8g.setColorIndex(255);     // 白色的
  95.   }
  96.   else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
  97.     u8g.setColorIndex(3);         // 最大强度
  98.   }
  99.   else if ( u8g.getMode() == U8G_MODE_BW ) {
  100.     u8g.setColorIndex(1);         //像素开启
  101.   }
  102.   else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
  103.     u8g.setHiColorByRGB(255, 255, 255);
  104.   }
  105. }
  106. void loop() {
  107.   //与GPS模块连接
  108.   while (Serial_GPS.available() > 0)
  109.     if (gps.encode(Serial_GPS.read()))
  110.       displayInfo();
  111.   if (millis() > 5000 && gps.charsProcessed() < 10)
  112.   {
  113.     Serial.println(F("未检测到 GPS:检查接线。"));
  114.     while (true);
  115.   }
  116.   //调用屏幕上的绘图例程
  117.   u8g.firstPage();
  118.   do
  119.   {
  120.     draw();
  121.   }
  122.   while ( u8g.nextPage() );
  123.   delay(1000);
  124. }
  125. void displayInfo() {
  126.   //在串口监视器中显示信息
  127.   Serial.print(F("位置:"));
  128.   if (gps.location.isValid())
  129.   {
  130.     Serial.print(gps.location.lat(), 6); //latitude
  131.     Serial.print(F(","));
  132.     Serial.print(gps.location.lng(), 6); //longitude
  133.   }
  134.   else
  135.   {
  136.     Serial.print(F("无效"));
  137.   }
  138.   Serial.print(F("  日期/时间: "));
  139.   if (gps.date.isValid())
  140.   {
  141.     Serial.print(gps.date.day()); //天
  142.     Serial.print(F("/"));
  143.     Serial.print(gps.date.month()); //月
  144.     Serial.print(F("/"));
  145.     Serial.print(gps.date.year());//年
  146.   }
  147.   else
  148.   {
  149.     Serial.print(F("无效"));
  150.   }
  151.   Serial.print(F(" "));
  152.   if (gps.time.isValid())
  153.   {
  154.     if (gps.time.hour() < 10) Serial.print(F("0"));
  155.     Serial.print(gps.time.hour()); //小时
  156.     Serial.print(F(":"));
  157.     if (gps.time.minute() < 10) Serial.print(F("0"));
  158.     Serial.print(gps.time.minute()); //分钟
  159.     Serial.print(F(":"));
  160.     if (gps.time.second() < 10) Serial.print(F("0"));
  161.     Serial.print(gps.time.second()); //第二
  162.     Serial.print(F("."));
  163.     if (gps.time.centisecond() < 10) Serial.print(F("0"));
  164.     Serial.print(gps.time.centisecond());
  165.   }
  166.   else
  167.   {
  168.     Serial.print(F("无效"));
  169.   }
  170.   Serial.println();
  171. }
  172. void GPS_Timezone_Adjust() {
  173.   while (Serial_GPS.available())
  174.   {
  175.     if (gps.encode(Serial_GPS.read()))
  176.     {
  177.       int Year = gps.date.year();
  178.       byte Month = gps.date.month();
  179.       byte Day = gps.date.day();
  180.       byte Hour = gps.time.hour();
  181.       byte Minute = gps.time.minute();
  182.       byte Second = gps.time.second();
  183.       //根据GPS数据调整日期和时间
  184.       setTime(Hour, Minute, Second, Day, Month, Year);
  185.       //应用偏移来设置日期和时间
  186.       //根据时区
  187.       adjustTime(UTC_offset * SECS_PER_HOUR);
  188.     }
  189.   }
  190. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-31 21:09:11

程序十一:使用 TinyGPSCustom 对象数组监视所有可见的卫星
1)Arduino参考开源代码

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   程序十一:使用 TinyGPSCustom 对象数组监视所有可见的卫星
  4. */
  5. #include <TinyGPSPlus.h>//导入驱动库
  6. #include <SoftwareSerial.h>
  7. static const int RXPin = 9, TXPin = 8;//定义软串口接脚
  8. static const uint32_t GPSBaud = 9600;
  9. // TinyGPSPlus 对象
  10. TinyGPSPlus gps;
  11. //与 GPS 设备的串行连接
  12. SoftwareSerial ss(RXPin, TXPin);
  13. /*
  14.   来自 http://aprs.gids.nl/nmea/:
  15.    
  16.   $GPGSV
  17.   
  18.   视野中的 GPS 卫星
  19.   
  20.   例如:
  21. $GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74   $GPGSV,3,2,11,14,25,170,00,16,57,208,39,18,67,296,40,19,40,246,00*74
  22. $GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D
  23.   1 = 此周期中此类消息的总数
  24.   2 = 消息编号
  25.   3 = 视图中的 SV 总数
  26.   4 = SV PRN 号码
  27.   5 = 以度为单位的仰角,最大 90
  28.   6 = 方位角,从真北的度数,000 到 359
  29.   7 = SNR,00-99 dB(不跟踪时为空)
  30.   8-11 = 关于第二个 SV 的信息,与字段 4-7 相同
  31.   12-15=关于第三个 SV 的信息,与字段 4-7 相同
  32.   16-19= 关于第四个 SV 的信息,与字段 4-7 相同
  33. */
  34. static const int MAX_SATELLITES = 40;
  35. TinyGPSCustom totalGPGSVMessages(gps, "GPGSV", 1); // $GPGSV 句子,第一个元素
  36. TinyGPSCustom messageNumber(gps, "GPGSV", 2);      // $GPGSV 句子,第二个元素
  37. TinyGPSCustom satsInView(gps, "GPGSV", 3);         // $GPGSV 句子,第三个元素
  38. TinyGPSCustom satNumber[4]; // 稍后初始化
  39. TinyGPSCustom elevation[4];
  40. TinyGPSCustom azimuth[4];
  41. TinyGPSCustom snr[4];
  42. struct{
  43.   bool active;
  44.   int elevation;
  45.   int azimuth;
  46.   int snr;
  47. } sats[MAX_SATELLITES];
  48. void setup(){
  49.   Serial.begin(9600);
  50.   ss.begin(GPSBaud);
  51.   Serial.println(F("SatelliteTracker.ino"));
  52.   Serial.println(F("使用 TinyGPSCustom 监控卫星位置和信号强度"));
  53.   Serial.print(F("测试 TinyGPSPlus 库 v."));
  54.   Serial.println(TinyGPSPlus::libraryVersion());
  55.   Serial.println(F("GY-NEO6MV2模块准备就绪"));
  56.   Serial.println();
  57.   
  58.   // 初始化所有未初始化的 TinyGPSCustom 对象
  59.   for (int i=0; i<4; ++i)
  60.   {
  61.     satNumber[i].begin(gps, "GPGSV", 4 + 4 * i); // offsets 4, 8, 12, 16
  62.     elevation[i].begin(gps, "GPGSV", 5 + 4 * i); // offsets 5, 9, 13, 17
  63.     azimuth[i].begin(  gps, "GPGSV", 6 + 4 * i); // offsets 6, 10, 14, 18
  64.     snr[i].begin(      gps, "GPGSV", 7 + 4 * i); // offsets 7, 11, 15, 19
  65.   }
  66. }
  67. void loop(){
  68.   // 初始化所有未初始化的 TinyGPSCustom 对象
  69.   if (ss.available() > 0)
  70.   {
  71.     gps.encode(ss.read());
  72.     if (totalGPGSVMessages.isUpdated())
  73.     {
  74.       for (int i=0; i<4; ++i)
  75.       {
  76.         int no = atoi(satNumber[i].value());
  77.         // Serial.print(F("SatNumber is ")); Serial.println(no);
  78.         if (no >= 1 && no <= MAX_SATELLITES)
  79.         {
  80.           sats[no-1].elevation = atoi(elevation[i].value());
  81.           sats[no-1].azimuth = atoi(azimuth[i].value());
  82.           sats[no-1].snr = atoi(snr[i].value());
  83.           sats[no-1].active = true;
  84.         }
  85.       }
  86.       
  87.       int totalMessages = atoi(totalGPGSVMessages.value());
  88.       int currentMessage = atoi(messageNumber.value());
  89.       if (totalMessages == currentMessage)
  90.       {
  91.         Serial.print(F("Sats="));
  92.         Serial.print(gps.satellites.value());
  93.         Serial.print(F(" Nums="));
  94.         for (int i=0; i<MAX_SATELLITES; ++i)
  95.           if (sats[i].active)
  96.           {
  97.             Serial.print(i+1);
  98.             Serial.print(F(" "));
  99.           }
  100.         Serial.print(F(" 海拔="));//海拔
  101.         for (int i=0; i<MAX_SATELLITES; ++i)
  102.           if (sats[i].active)
  103.           {
  104.             Serial.print(sats[i].elevation);
  105.             Serial.print(F(" "));
  106.           }
  107.         Serial.print(F(" 方位角="));//方位角
  108.         for (int i=0; i<MAX_SATELLITES; ++i)
  109.           if (sats[i].active)
  110.           {
  111.             Serial.print(sats[i].azimuth);
  112.             Serial.print(F(" "));
  113.           }
  114.         
  115.         Serial.print(F(" 信噪比="));//信噪比
  116.         for (int i=0; i<MAX_SATELLITES; ++i)
  117.           if (sats[i].active)
  118.           {
  119.             Serial.print(sats[i].snr);
  120.             Serial.print(F(" "));
  121.           }
  122.         Serial.println();
  123.         for (int i=0; i<MAX_SATELLITES; ++i)
  124.           sats[i].active = false;
  125.       }
  126.     }
  127.   }
  128. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 07:53:02

8.6.1. 科普知识点:经度、维度和全球卫星定位系統GPS
经度(longitude)
1、经度是一种用于确定地球表面上不同点东西位置的地理坐标。经度是一种角度量,通常用度来表示,并被记作希腊字母λ(lambda)。子午线穿过南极和北极并把相同经度的点连起来。按照惯例,本初子午线是经过伦敦格林威治皇家天文台的子午线,是0度经线所在地。其他位置的经度是通过测量其从本初子午线向东或向西经过的角度得到的,经度的范围为从本初子午线0° 向东至180°向西至180° W。具体来说,某位置的经度是一个通过本初子午线的平面和一个通过南极、北极和该位置的平面所组成的二面角(这就组成了一个右手坐标系,其z轴(右手拇指)从地球中心指向北极方向,其x轴(右手食指)从地球中心指向本初子午线与赤道的交点。)

如果地球是一个均质球体,那么一点的经度就等于过该点的南北铅垂面和格林尼治子午面之间夹角的角度。地球上任何地方的南北铅垂面都会包含地球的自转轴。但是地球并不是均质的,而是有很多山脉,在山脉的重力影响下,铅垂面就会偏离地球的自转轴。即便如此,南北铅垂面仍然会和格林尼治子午面相交于某个角度,该角度被称为天文经度,通过天文观测来确定。地图和GPS设备上显示的经度是格林尼治子午面与过该点的一个非严格铅垂面之间夹角的角度,该非严格铅垂面垂直于一个近似于大地水准面的椭球体表面,而不是直接垂直于大地水准面本身。

作为起点,过去其它国家或人也使用过其它的子午线做起点,比如罗马、哥本哈根、耶路撒冷、圣彼德堡、比萨、巴黎和费城等。在1884年的国际本初子午线大会上格林维治的子午线被正式定为经度的起点。东经180°即西经180°,约等同于国际日期变更线,国际日期变更线的两边,日期相差一日。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 07:55:21

2、经度的每一度被分为60角分,每一分被分为60秒。一个经度因此一般看上去是这样的:东经23° 27′ 30"或西经23° 27′ 30"。更精确的经度位置中秒被表示为分的小数,比如:东经23° 27.500′,但也有使用度和它的小数的:东经23.45833°。有时西经被写做负数:-23.45833°。偶尔也有人把东经写为负数,但这相当不常规。一个经度和一个纬度一起确定地球上一个地点的精确位置。纬度的每个度的距离大约相当于111km,但经度的每个度的距离从0km到111km不等。它的距离随纬度的不同而变化,沿同一纬度约等于111km乘纬度的余弦。不过这个距离还不是相隔一经度的两点之间最短的距离,最短的距离是连接这两点之间的大圆的弧的距离,它比上面所计算出来的距离要小一些。一个地点的经度一般与它于协调世界时之间的时差相应:每天有24小时,而一个圆圈有360度,因此地球每小时自转15度。因此假如一个人的地方时比协调世界时早3小时的话,那么他在东经45度左右。不过由于时区的分划也有政治因素在里面,因此一个人所在的时区不一定与上面的计算相符。但通过对地方时的测量一个人可以算得出他所在的地点的经度。为了计算这个数据,他需要一个指示协调世界时的钟和需要观察对太阳经过子午圈的时间。由于地球在一个椭圆轨道上绕太阳旋转,这个计算和观察比上面叙述的还要复杂些。

3、对于地图绘制和远洋航海来说,经度的测量是很重要的。在历史上的大多数时候,水手和探险家们为了确定经度而绞尽脑汁。人们花费了几个世纪来探索确定经度的方法,因此,经度的历史记录了一些最伟大的科学头脑的努力。使用四分仪或星盘可观测到太阳或某特定恒星在地平线上的高度,根据该高度可以计算出该位置的纬度,但是经度的确定要更加复杂些。亚美利哥·韦斯普奇Amerigo Vespucci,1454/03/09-1512/02/22)也许是第一个提出经度确定方法的欧洲人,他在前往新世界的旅途中,花费了大量的时间和精力来研究这个问题:
“至于经度,我发现经度的确定是那么困难,以至于我在确定我所经过的东西距离时困难重重。进行实验的最终结果让我发现确定经度最好的方法是在一颗行星和另一颗连起来的夜晚进行观测,尤其是月球和其他行星连起来的夜晚,因为月球在运行的过程中要比其他所有行星要快。我把我很多个夜晚的观测结果和一本历书做了对比,根据历书,在1499年8月23号午夜或前半小时,月球和火星将会连在一条线上。我发现,在当天午夜时,火星的位置在向东3.5度的方向上。”

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 07:56:45

二、纬度(latitude)
1、纬度(φ)是地球表面一个点的南北地理位置的表示法。纬度与经度通常一起使用以确定地表上某点的精确位置。纬度是一个角度,其范围从赤道0度到南北极的90度。在英文文本中,纬度通常使用小写希腊字母phi (φ)来表示。它以度、分、秒或者小数形式的度来计量,再附上N或S来表示北纬或南纬。纬度相同的连线形成与赤道平行的大圆。赤道、南回归线、北回归线、南极圈和北极圈是特殊的纬线。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 07:58:43

2、凡经线上的任何一点至赤道间的弧距称为纬度。系地理坐标之一,在地理坐标中起着纵坐标的作用,可用以确定和描述地球表面上任何地点或位置。纬度有如下几种:地理纬度、天文纬度和地心纬度,这几种纬度间的差数不大。在大部分情况下,纬度指的是地理纬度(即绘制地图时用的纬度)。
地理纬度是地球球心角所对应的地面上的弧长。地理纬度把地球看成椭球,即椭球面的法线(同铅垂线略有不同)同赤道平面的夹角。通常用度、分、秒表示。从赤道向南北两极度量,各为0°—90°。每一纬度之间的宽度基本相等,为110公里(靠近两极处稍长些)。在赤道以北的叫 “北纬”,用“N”作代号;以南的叫“南纬”,用“S”作代号。习惯上称0°—30°为低纬度;30°—60°为中纬度;60°—90°为高纬度。北京的纬度是北纬39° 57′。


【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:00:41

3、纬度数值在0至30度之间的地区称为低纬度地区;纬度数值在30至60度之间的地区称为中纬度地区;纬度数值在60至90度之间的地区称为高纬度地区。在定义经纬度的时候,做了两个抽象假设。第一,以大地水准面来代替地球的物理表面,大地水准面是一个假想的由地球上静止平衡的海平面延伸到陆地内部而形成的闭合曲面。第二,用一个数学上简单的参考表面来作为大地水准面的近似。最简单的参考表面为球面,但是用旋转椭球面来模拟大地水准面要更为准确些。经纬度在这个参考表面上的定义将在下文中详细说明,经度相同和纬度相同的点的连线共同构成了这个参考表面上的经纬网。

地球真实表面上一点的纬度和其在参考表面上的对应点一致,过地球真实表面上一点作参考表面的法线,该法线与参考表面的交点即为真实表面上那一点的对应点。纬度,经度和遵循某种规范的高度共同组成了 ISO 19111 标准中所定义的地理坐标系统。由于有不同的参考椭球面,地表上一点的纬度特征也就并不唯一。ISO标准中关于这一点的描述为:如果坐标参考系统没有完全定义,那么坐标(主要指经度和纬度)顶多是模糊不清的,至少也是毫无意义的。这对于精确的应用非常重要,比如GPS,但是,在一般的使用中,并不需要很高的精度,通常也就不提及参考椭球面。无论是为了使用经纬仪还是为了确定GPS卫星的轨道,纬度的测量都要求人们对地球重力场有充分的了解。

三、地球经纬度(The earth's latitude and longitude)
1、地球自转时南北各有一个不动点叫南极、北极。通过地心连接南北极的假想线是地轴,即地球的自转轴。赤道就是通过地心并垂直于地轴的假想平面与地球表面相交的圆周线。它将地球等分为南北两半球。人们以赤道和南北极为控制点来确定各地经纬度(地理坐标)。经线是连结两极而垂直于赤道的圆周线,纬线是与赤道平行的圆周线。纬度是以赤道为零度线,将南北半球各等分为九十度。经纬度可以方便的标定地球上任何一个位置。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:02:56

2、经线也称子午线,和纬线一样是人类为度量方便而假 设出来的辅助线,定义为地球表面连接南北两极的大圆线上的半圆弧。任两根经线的长度相等,相交于南北两极点。每一根经线都有其相对应的数值,称为经度。经线指示南北方向。
子午线命名的由来:“某一天体是运动轨迹中,同一子午线上的各点该天体在上中天(午)与下中天(子)出现的时刻相同。”不同的经线具有不同的地方时。偏东的地方时要比较早,偏西的地方时要迟。
重要的经线:
本初子午线
巴黎子午线
180度经线
西经20度(W)
东经160度(E)
所有经线长度相等



3、纬线的长度是赤道的周长乘以纬线的纬度的余弦,所以赤道最长,离赤道越远的纬线,周长越短,到了两极就缩为0。从赤道向北和向南,各分90°,称为北纬和南纬,分别用“N”和“S”表示。纬线和经线一样是人类为度量方便而假设出来的辅助线,定义为地球表面某点随地球自转所形成的轨迹。任何一根纬线都是圆形而且两两平行。
重要的纬线:
北极圈66°33' 38" N)
北回归线(23°26' 22" N)
赤道(0°N)
南回归线23° 26' 22" S)
南极圈66°33' 38" S)
长度不同(离赤道越远的纬线越短)



4、经纬度的转换:经纬度以度数表示,一般可直接以小数点表示,但亦可把度数的小数点分为角分1角分等于六十分之一度),和秒(一秒等于六十分之一分)。表示经纬度有多样模式,以下是其中一些例子。
1)度分秒表示(度:分:秒)-49°30'00"-49d30m00s
2)度分表示(度:分)-49°30.0'-49d30.0m
3)度数表示-49.5000°-49.5000d(一般会有四位小数)。
不少软件可把不同的经纬度表示方式实现转换。


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:04:09

四、GPS系统Global Positioning System
1、全球卫星定位系统,是美国国防部研制,美国太空军运营与维护的中距离圆型轨域卫星导航系统,简称GPS。它可以为地球表面绝大部分地区(98%)提供准确的定位、测速和高精度的标准时间。全球定位系统可满足位于全球地面任何一处或近地空间的军事用户连续且精确地确定三维位置、三维运动和时间的需求。该系统包括太空中的31颗GPS人造卫星;地面上1个主控站、3个资料注入站和5个监测站,及作为用户端的GPS军用接收机器、智能手机等。最少只需其中4卫星,就能迅速确定用户端在地球上所处的位置及海拔高度;所能接收到的卫星讯号数越多,解码出来的位置就越精确。


【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:06:11

2、GPS系统由美国政府1970年代开始进行研制,1978年2月首次发射,并于1994年全面建成。使用者只需拥有GPS接收晶片即可使用该服务。GPS信号分为民用的标准定位服务(SPS,Standard Positioning Service)和军用的精确定位服务(PPS,Precise Positioning Service)两类。由于GPS无须任何授权即可任意使用,原本美国因为担心敌对国家或敌对组织会利用GPS对美国发动攻击,故在民用讯号中人为地加入选择性误差(即SA政策,Selective Availability)以降低其精确度,使其最终定位精确度大概在100米左右;军规的精度在(20~1英尺)以下。2000年以后,比尔·克林顿政府决定取消对民用讯号的干扰。因此,现在民用GPS也可以达到(20~1英尺)左右的定位精度。GPS系统拥有如下多种优点:使用低频讯号,就算天气不佳仍能保持相当的讯号穿透性;高达98%的全球覆盖率;高精度三维定速定时;快速、省时、高效率;应用广泛、多功能;可移动定位。不同于双星定位系统,使用过程中接收机不需要发出任何信号;此举增加了隐蔽性,提高了其军事应用效能。

3、GPS的功能
1)精确定时:广泛应用在天文台、通信系统基站、电视台中
2)工程施工:道路、桥梁、隧道的施工中大量采用GPS设备进行工程测量
3)勘探测绘:野外勘探及城区规划中都有用到
4)导航:
武器导航——精确制导导弹、巡航导弹
车辆导航——车辆调度、监控系统
船舶导航——远洋导航、港口/内河引水
飞机导航——航线导航、进场着陆控制
星际导航——卫星轨域定位
个人导航——个人旅游及野外探险
5)定位:
车辆防盗系统,手机、PDA、PPC等通信流动装置防盗,电子地图,定位系统
儿童及特殊人群的防走失系统
精准农业——农机具导航、自动驾驶,土地高精度平整
提供时间数据:用于给电信基站、电视发射站等提供精确同步时钟源

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:07:52

4、其他定位系統
除了美国的GPS系统外,目前正在运行的全球卫星定位系统还有俄罗斯的GLONASS系统和中国的北斗卫星导航定位系统。而欧盟于1999年初正式推出「伽利略」计划,部署新一代定位卫星。该方案由27颗运行卫星和3颗预备卫星组成,可以覆盖全球,位置精度达几米,亦可与美国的GPS系统兼容,总投资额为35亿欧元。目前已经发射11颗在轨卫星,于2016年12月15日提供早期服务。

全球卫星导航系统国际委员会为联合国的一个非正式机构。其目的是促进与民用卫星定位、导航、正时和增值服务有关的问题及各种全球卫星导航系统的兼容性和互通性问题的合作和发展。

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 08:09:03

8.6.2. 科普知识点:NEO-6M、陶瓷天线与GY-NEO6MV2飞控GPS模块
NEO-6M
1、NEO-6M是一款的经典GPS芯片,具有高灵敏度、低功耗、小型化的特点,其极高追踪灵敏度大大扩大了其定位的覆盖面,在普通GPS接收模块不能定位的地方,如狭窄都市天空下、密集的丛林环境,NEO-6M 都能高精度定位。NEO-6M具有50个通道,追踪灵敏度高达-161dBm,测量输出频率最高可达5Hz。NEO-6M 模块自带高性能无源陶瓷天线(无需再购买昂贵的有源天线了),兼容 3.3V 和5V 单片机系统,并自带可充电后备电池(支持温启动或热启动)。NEO-6M模块非常小巧(25.5mm*31mm),模块通过 4 个 2.54mm 间距的排针与外部连接。模块的高灵敏度、小静态漂移、低功耗及轻巧的体积,适用于车载、手持设备如PDA,车辆监控、手机、摄像机及其他移动定位系统的应用,是GPS产品应用的最佳选择。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:10:54

2、NEO-6M特性
1)u-blox 6 定位引擎:
o 跟踪灵敏度 –162dBm ,冷启动灵敏度–148 dBm
o 更快的捕获速度,带有 AssistNow Autonomous功能
o 可配置的电源管理
o GPS/SBAS 混合型引擎(WAAS、EGNOS、MSAS)
o 抗干扰技术
2)易于与 u-blox 无线模块集成
3)A-GPS:AssistNow Online 和 AssistNow Offline 服务,符合 OMA SUPL 规范
4)向后兼容(硬件和固件);可从 NEO-5 系列或NEO-4S 轻松迁移
5)采用可靠的 LCC 封装,制造性价比高
6)工作温度范围:–40° C 至 85° C

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图2

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:13:36

3、精确度
定位2.5MCEP
SBAS 2.0mCEP
捕获冷启动29s
温启动27s
辅助启动<3s
热启动<1s

灵敏度
捕获-162dBm
跟踪-147dBm
冷启动-146dBm

多径抑制
智能化多径检测与抑制
A-GPS
支持AssistNow Online及AssistNow Offline

运行限制
速度515m/s(1000节)
串口1个UART接口
1个USB V2.0,全速12Mbit/s
1个DDC接口
1个SPI接口
串口和I/O电压3V电平
协议NMEA、UBX二进制
数字I/O接口可配置的时间脉冲
1个EXTINT输入接口
电压2.7V – 3.6V
功耗<80mW @ 1.8V 
120mW @ 3.0V
备用电源1.3V -4.8V有 30uA
天线类型有源与无源
运行温度-40℃- +85℃  
存储温度-40℃- +85℃


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:15:58

二、GPS陶瓷有源天线
1、GPS就是通过接受卫星信号,进行定位或者导航的终端。而接收信号就必须用到天线。 GPS卫星信号分为L1和L2,频率分别为1575.42MHZ和1228MHZ,其中L1为开放的民用信号,信号为圆形极化。信号强度为-166dBW左右,属于比较弱的信号。 这些特点决定了要为GPS信号的接收准备专门的天线。GPS天线是由接收天线和前置放大器两个部件组成。GPS接收天线的作用,是将卫星来的无线电信号的电磁波能量变换成接收机电子器件可摄取应用的电流。绝大部分内置GPS天线为右旋极化陶瓷介质,其组成部分为:陶瓷天线、低噪音信号模块、线缆、接头。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:17:53

2、GPS天线工作原理
1)陶瓷片:陶瓷粉末的好坏以及烧结工艺直接影响它的性能。现市面使用的陶瓷片主要是25×25、18×18、15×15、12×12。陶瓷片面积越大,介电常数越大,其共振频率越高,接受效果越好。陶瓷片大多是正方形设计,是为了保证在XY方向上共振基本一致,从而达到均匀收星的效果。
2)银层:陶瓷天线表面银层可以影响天线共振频率。理想的GPS陶瓷片频点准确落在1575.42MHz,但天线频点非常容易受到周边环境影响,特别是装配在整机内,必须通过调整银面涂层外形,来调节频点重新保持在1575.42MHz。
3)馈点:陶瓷天线通过馈点收集共振信号并发送至后端。由于天线阻抗匹配的原因,馈点一般不是在天线的正中央,而是在XY方向上做微小调整。这样的阻抗匹配方法简单而且没有增加成本。仅在单轴方向上移动称为单偏天线,在两轴均做移动称为双偏。
4)放大器:承载陶瓷天线的PCB形状及面积。由于GPS接收信号有触地反弹的特性,当背景是7cm×7cm无间断大地时,天线的效能可以发挥到极致。虽然受外观结构等因素制约,但尽量保持相当的面积且形状均匀。放大器增益的选择必须配合后端LNA增益。Sirf的GSC3F要求信号输入前总增益不得超过29dB,否则信号过饱和会产生自激。

GPS天线在室外空旷地区接受信号较好,在车内,因金属外壳和玻璃的防爆膜尤其是含金属粉的车膜,以及车内音响等都会对内置GPS天线接收信号产生干扰甚至阻碍,在室内受钢筋混凝土的遮挡,甚至无法接受GPS信号。

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:20:51

3、GPS天线相关参数

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:22:20

三、GY-NEO6MV2飞控GPS模块
1GPS模块 NEO-6M
3V-5V供电通用
型号:GY-GPS6MV2
模块带陶瓷有缘天线,信号超强
EEPROM掉电保存配置参数数据
带数据备份电池
LED信号指示灯
天线尺寸25*25mm
模块尺寸25mm*35mm
安装孔径3mm
默认波特率:9600
兼容各种飞控模块,GPS电脑测试软件


【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:24:00

2、GPS模块原理图

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:25:13

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:26:48

2、模块组成示意说明

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2022-5-23 09:28:02

【Arduino】168种传感器模块系列实验(75)-- NEO6MV2飞控GPS模块图1
回复

使用道具 举报

1234下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail