极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15596|回复: 11

Microduino GPS模块定位+OLED显示

[复制链接]
发表于 2013-12-26 19:55:54 | 显示全部楼层 |阅读模式
本帖最后由 wasdylb 于 2013-12-26 19:54 编辑

Microduino出GPS模块了,测试了其基本功能。包括:时间(年月日,时钟)、经纬度、速度、卫星个数、海拔高度,信号强度。
模块使用详见:http://wiki.microduino.net/index.php?title=Microduino-NEO-6M

整体:
oled.jpg

PPS指示灯:

PPS指示灯

PPS指示灯


注意:必须匹配好串口,在空旷地方调试。Microduino NEO-6M模块默认与Core的串口通讯引脚是RX0、TX1,因此不可直接与Microduino FT232R叠加。为了方便调试改动模块背面的跳线:切断两组的焊盘中间与RX0/TX1的连线,将焊盘中间与D2、D3焊上。

程序:
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
Adafruit_GPS GPS(&Serial1);

//oled=======================================
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);        // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)

//-------字体设置,大、中、小
#define setFont_L  u8g.setFont(u8g_font_courB14)
#define setFont_M u8g.setFont(u8g_font_fixed_v0r)
#define setFont_S u8g.setFont(u8g_font_chikitar)
/*
font:
u8g.setFont(u8g_font_7x13)
u8g.setFont(u8g_font_fixed_v0r);
u8g.setFont(u8g_font_chikitar);
u8g.setFont(u8g_font_osb21);
*/

#define u8g_logo_width 128
#define u8g_logo_height 18

const unsigned char u8g_logo_bits[] U8G_PROGMEM =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0xE0,
  0x03, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00,
  0x00, 0xFE, 0xF9, 0xF7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xF8,
  0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xF9, 0xE1, 0x03, 0x00, 0x00, 0x00,
  0x00, 0x38, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xFC, 0xEF, 0xF9, 0x8F, 0xD7, 0x73, 0xF1, 0xC1, 0x3B, 0x9F, 0xFF,
  0xFF, 0x1E, 0x3E, 0x00, 0x00, 0xBC, 0xEF, 0xC1, 0xE1, 0x9F, 0xFF, 0xDD,
  0xE3, 0x3F, 0xCC, 0xE1, 0xF0, 0xBF, 0x7B, 0x00, 0x00, 0x3C, 0xF7, 0xE1,
  0xE1, 0x9F, 0xFF, 0xC6, 0xF7, 0x3E, 0x8E, 0xF3, 0xF0, 0xFF, 0xF8, 0x00,
  0x00, 0x3C, 0xF3, 0xE1, 0xF1, 0x93, 0xFF, 0xE6, 0xF7, 0x3C, 0x8F, 0xF7,
  0xF0, 0xFF, 0xFC, 0x00, 0x00, 0x7C, 0xF2, 0xE1, 0xF1, 0x83, 0x87, 0xFE,
  0xF7, 0x39, 0xFF, 0xF7, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xF0, 0xE3,
  0xF3, 0xA3, 0x03, 0xFE, 0xF7, 0x3F, 0xFF, 0xF7, 0x71, 0xFC, 0xFF, 0x00,
  0x00, 0x7C, 0xF8, 0xE3, 0xF3, 0xBF, 0x03, 0xFE, 0xE3, 0x3F, 0xFF, 0xF3,
  0x71, 0xDC, 0x7F, 0x00, 0x00, 0x7E, 0xFC, 0xE7, 0xE3, 0xBF, 0x03, 0xFC,
  0xE3, 0x3F, 0xFE, 0xF3, 0x71, 0x9C, 0x7F, 0x00, 0x00, 0xC1, 0x03, 0xF8,
  0xCF, 0xE7, 0x0F, 0xF0, 0x00, 0x7F, 0xFC, 0xFC, 0xFF, 0x3E, 0x1E, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

#define GPSECHO false

//==========================
boolean STA;        //GPS状态

float f_latitude,f_longitude;        //经纬度
char c_lat,c_lon;                //经纬极向

int itime[3];        //时间
int idate[3];        //日期

float f_Speed;        //速度
int i_Speed[2];        //速度格式化

float f_Height;        //海拔

int i_satellites;        //卫星数

float f_fixquality;        //信号质量

#define init_updata 1000                        //gps数据刷新时间
#define init_oled 500                        //OLED刷新时间

unsigned long time_oled = millis();
unsigned long timer = millis();

void setup()
{
  Serial.begin(115200);

  GPS.begin(38400);

  delay(1000);
  // Ask for firmware version
// u8g.setRot180();
  volcdlogo(0, 10);
  delay(2000);
}

void volcdlogo(unsigned int x, unsigned int y)
{
  u8g.firstPage();
  do
  {
    u8g.drawXBMP( x, y, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
  }
  while( u8g.nextPage() );
}

void vogps_dataread()
{
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
      return; // we can fail to parse a sentence in which case we should just wait for another
  }

  if (timer > millis())
    timer = millis();
  if (millis() - timer > init_updata)
  {
    timer = millis(); // reset the timer
    if(GPS.hour>=0&&GPS.hour<=16)
    itime[0]=GPS.hour+8;
    else
     itime[0]=GPS.hour;
    itime[1]=GPS.minute;
    itime[2]=GPS.seconds;

    idate[0]=GPS.year;
    idate[1]=GPS.month;
    idate[2]=GPS.day;

    f_fixquality=GPS.fixquality;        //信号质量
    STA=GPS.fix;                        //GPS定位状态

    if (STA)                //当GPS定位上
    {
      f_latitude=GPS.latitude;
      f_longitude=GPS.longitude;
      c_lat=GPS.lat;
      c_lon=GPS.lon;

      lat_lon_transform();                //经纬度转化

      f_Speed=1.852*GPS.speed;                        //速度转化
      i_Speed[0]=int(f_Speed*10)%10;        //速度格式化
      i_Speed[1]=int(f_Speed);                        //速度格式化

      f_Height=GPS.altitude;                        //海拔

      i_satellites=GPS.satellites;      //卫星数
    }
    vooled();//OLED显示
  }
}

//lat_lon_transform================================
void lat_lon_transform()
{
  f_latitude=(int(f_latitude)/100)+((int(f_latitude)%100)/60.0)+((f_latitude-int(f_latitude))/60.0);
  if(c_lat=='S')                //南纬
    f_latitude=-f_latitude;

  //---------------------------------

  f_longitude=(int(f_longitude)/100)+((int(f_longitude)%100)/60.0)+((f_longitude-int(f_longitude))/60.0);
  if(c_lon=='W')                //西经
    f_longitude=-f_longitude;
}

void draw(void)
{
  for(int a=0;a<3;a++)
  {
    u8g.drawFrame(106+(6*a), 4-(a*2), 5, 4+(a*2));
  }
  for(int a=0;a<f_fixquality+1;a++)
  {
    u8g.drawBox(106+(6*a), 4-(a*2), 5, 4+(a*2));
  }
  u8g.setPrintPos(0, 8);
  u8g.print("Sat:");
  u8g.print(i_satellites);

  u8g.setPrintPos(36, 8);
  u8g.print("ELE:");
  u8g.print(f_Height);
  u8g.print("m");

  u8g.drawLine(0,11 , 128, 11);

  setFont_L;

  u8g.setPrintPos(2, 27);

  u8g.print("Speed:");
  if(STA)
  {
    u8g.print(i_Speed[1]);
    setFont_M;
    u8g.print(".");
    u8g.print(i_Speed[0]);
  }
  else
  {
    u8g.print("N/A");
    setFont_M;
  }

  u8g.drawLine(0,29 , 128, 29);

  u8g.setPrintPos(2, 41);
  u8g.print("Lat.: ");
  u8g.print( f_latitude,4);
  u8g.print(" ");
  u8g.print( c_lat);

  u8g.setPrintPos(2, 50);
  u8g.print("Lon.: ");
  u8g.print(f_longitude,4);
  u8g.print(" ");
  u8g.print( c_lon);

  u8g.drawLine(0, 53, 128, 53);

  u8g.setPrintPos(2, 64);
  u8g.print("20");
  u8g.print(idate[0]);
  u8g.print("-");
  u8g.print(idate[1]);
  u8g.print("-");
  u8g.print(idate[2]);

  u8g.print("  ");
  u8g.print(itime[0]);
  u8g.print(":");
  u8g.print(itime[1]);
  u8g.print(":");
  u8g.print(itime[2]);

}

//OLED===================================================
void vooled()
{
  if (time_oled > millis())
    time_oled = millis();
  if(millis()-time_oled>init_oled)
  {
    u8g.firstPage();
    do
    {
      draw();
    }
    while( u8g.nextPage() );
  }
}

void loop()
{
  vogps_dataread();
}
回复

使用道具 举报

发表于 2013-12-30 09:16:56 | 显示全部楼层
谢谢楼主的好帖!请问你这个gps刷新率是用的5Hz模式吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-18 19:34:56 | 显示全部楼层
fangtaonj 发表于 2013-12-30 09:16
谢谢楼主的好帖!请问你这个gps刷新率是用的5Hz模式吗?

是的,模块详细参考:http://wiki.microduino.net/index.php?title=Microduino-NEO-6M
回复 支持 反对

使用道具 举报

发表于 2014-6-5 13:34:48 | 显示全部楼层
wasdylb 发表于 2014-2-18 19:34
是的,模块详细参考:http://wiki.microduino.net/index.php?title=Microduino-NEO-6M

你好照你的程序写进ARDUION里OLED显示正常,但不读GPS,GPS的信号接到ARDUION的RX1上面的,不知道是哪里问题,用串口测试GPS正常。
回复 支持 反对

使用道具 举报

发表于 2014-6-8 12:44:08 | 显示全部楼层
{:soso_e104:}
回复 支持 反对

使用道具 举报

发表于 2014-9-24 01:15:04 | 显示全部楼层
你好,做好后其他功能基本可以,就是时间换算有问题,每天到凌晨1点就显示的是17点,请问该怎么计算,和修改呢?谢谢!!
回复 支持 反对

使用道具 举报

发表于 2014-9-26 11:22:33 | 显示全部楼层
504835618 发表于 2014-9-24 01:15
你好,做好后其他功能基本可以,就是时间换算有问题,每天到凌晨1点就显示的是17点,请问该怎么计算,和修改 ...

自问自答,问题已解决,把正确的算法贴出来,供大家参考。
itime[0]=GPS.hour+8>24?GPS.hour+8-24:GPS.hour+8;
回复 支持 反对

使用道具 举报

发表于 2014-10-1 17:11:42 | 显示全部楼层
本帖最后由 yuqingshan 于 2014-10-1 17:21 编辑

7#您好,有2个问题想请教:

1.按您的方法,将原句: itime[0]=GPS.hour+8; 改为:
itime[0]=GPS.hour+8>24?GPS.hour+8-24:GPS.hour+8;

可像还是一样的,显示还是UTC时间而不是北京时间。只有与UTC时间在同一天才正常。

2.程序运行大约40-60分钟后就死机,出现如下画面,连续1-2天都是如此,不知什么原因?难道外星人?
问题-02.jpg

回复 支持 反对

使用道具 举报

发表于 2014-11-3 13:37:51 | 显示全部楼层
网站403了。。。
回复 支持 反对

使用道具 举报

发表于 2014-12-25 19:31:03 | 显示全部楼层
yuqingshan 发表于 2014-10-1 17:11
7#您好,有2个问题想请教:

1.按您的方法,将原句: itime[0]=GPS.hour+8; 改为:

UTC时间+8修正
回复 支持 反对

使用道具 举报

发表于 2015-11-1 20:34:50 | 显示全部楼层
我也出现过大大的信号。估计是信号图示部分出错了。可以把这个代码去了,试试。去了感觉简洁一些。
回复 支持 反对

使用道具 举报

发表于 2016-6-10 22:59:11 | 显示全部楼层
有问题了
  f_latitude=(int(f_latitude)/100)+((int(f_latitude)%100)/60.0)+((f_latitude-int(f_latitude))/60.0);
  if(c_lat=='S')   

这句里面int(f_latitude)/100 是先计算除法 还是先取整
要是先计算除法后取整没有问题
要是先除法后计算取整 那么根据gps 报文 ddmm。mmmm 那么ddmm 中的mm 被叠加了2次
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-7-14 19:20 , Processed in 0.056850 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表