使用esp8266+gps模块+oled屏幕diy一块gps定位器

1.材料准备

1.ESP8266开发板,某宝可以直接购买nodemcu.(ch340和cp2102都可.我这里用的是ch340驱动的)
nodemcu正面
nodemcu背面

2.GPS模块(NMEA协议的)
大夏龙雀GPS模块
在这里插入图片描述

3.0.96寸的OLED屏幕(4针 I²C协议的)
在这里插入图片描述
在这里插入图片描述
4.杜邦线母对母若干

2.接线说明

OLED屏幕需要连接 GND VCC SCL SDA四个引脚 具体对应关系 如下

NODEMCU开发板OLED屏幕备注
GGNDnodemcu中有多个地线引脚.选择一个即可
3VVCCnodemcu中有多个3v供电引脚.选择一个即可
D1(GPIO 5)SCLSCL代表"Serial Clock Line",即串行时钟线
D2(GPIO 4)SDASDA代表"Serial Data Line",即串行数据线

GPS模块需要连接 RXD TXD GND VDD 四个引脚 具体对应关系 如下

NODEMCU开发板GPS模块备注
D5(GPIO 14)RXDgps的RX接模拟串口的TX引脚定义
D6(GPIO 12)TXDgps的TX接模拟串口的RX引脚定义
GGNDnodemcu中有多个地线引脚.选择一个即可
3VVDDnodemcu中有多个3v供电引脚.选择一个即可

3.接线图

在这里插入图片描述

4.烧录程序

打开arduino ide .开发板选择NodeMCU 1.0 (ESP-12E Module).
使用以下代码,直接上传即可.
注意如果本地没有相关库,则需要手动安装 TinyGPSPlus , Adafruit_GFX, Adafruit_SSD1306 这三个库.

5.上电效果

在这里插入图片描述
因为是在室内,gps搜不到星.所以没数据.搜星成功会自动获取到时间和经纬度信息.需要注意的是这里的经纬度是WGS84坐标系.无法直接使用.如需使用则需要做相应的转换.具体可以看我的另一篇文章 java实现GPS(WGS-84)坐标系-火星(GCJ-02)坐标系-百度(BD-09)坐标系转换

6.完整代码

贴上完整代码

#include <TinyGPSPlus.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include "ESP8266WiFi.h"

// I2C款接线说明
// NodeMCU开发板	 0.96寸OLED 引脚连接对应关系
// GND	          GND
// 3V3	          VCC
// SCL	          D1 (GPIO 5)
// SDA	          D2 (GPIO 4)
#define SCREEN_WIDTH 128                                                   // OLED display width, in pixels
#define SCREEN_HEIGHT 64                                                   // OLED display height, in pixels
#define OLED_RESET 13                                                      // 重置引脚
#define SCREEN_ADDRESS 0x3C                                                // OLED 显示屏的地址,固化在芯片上
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);  // 创建实例

// gps模块引脚定义
#define RXPin 12  // GPIO 12 对应nodemcu D6
#define TXPin 14  // GPIO 14 对应nodemcu D5

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

// The TinyGPSPlus object
TinyGPSPlus gps;

// 一些需要使用的变量
int Year, Month, Date, Hour, Minute, Second, Yea, Mon, Dat, Hou;
double Lat, Lng;
String sMonth, sDate, sHour, sMinute, sSecond;


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

  WiFi.mode(WIFI_OFF);  //关闭WIFI模块省电
  WiFi.forceSleepBegin();

  ss.begin(9600);  //GPS模块虚拟串口

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;  // Don't proceed, loop forever
  }

  display.clearDisplay();       // 清屏
  display.setTextColor(WHITE);  // 设置字体颜色为白色
  display.display();            // 显示
  //OLED屏初始化代码
}





void loop() {

  boolean newData = false;
  for (unsigned long start = millis(); millis() - start < 300;) {
    while (ss.available()) {
      if (gps.encode(ss.read())) {
        newData = true;
      }
    }
  }  //上面是GPS数据接收的固定代码,不能删除


  Yea = gps.date.year();       //年
  Mon = gps.date.month();      //月
  Dat = gps.date.day();        //日
  Hou = gps.time.hour();       //时
  Minute = gps.time.minute();  //分
  Second = gps.time.second();  //秒
  Lng = gps.location.lng();    //经度
  Lat = gps.location.lat();    //纬度


  // 创建一个字符串来存储所有变量
  // String origin = String(Yea) + "-" + String(Mon) + "-" + String(Dat) + " " + String(Hou) + ":" + String(Minute) + ":" + String(Second)  + " (" + String(Lng, 8) + "," + String(Lat, 8) + ")";

  // 输出整个字符串
  // Serial.println(origin);


  //年月日时转换部分,将UTC时间转换为北京时间,并消除错误
  Hour = Hou + 8;  //修正时区

  if (Hour >= 24) {
    Hour = Hour - 24;  //修正小时超程
  }

  if (Hou + 8 >= 24) {
    Date = Dat + 1;
    if ((Mon == 1 || Mon == 3 || Mon == 5 || Mon == 7 || Mon == 8 || Mon == 10 || Mon == 12) && (Date > 31)) {
      Date = Date - 30;
      Month = Mon + 1;  //大月进位
    } else {
      Month = Mon;
      Year = Yea;
    }
    if ((Mon == 4 || Mon == 6 || Mon == 9 || Mon == 11) && (Date > 30)) {
      Date = Date - 29;
      Month = Mon + 1;  //小月进位
    } else {
      Month = Mon;
      Year = Yea;
    }
    if ((Yea % 4 == 0) && (Date > 29)) {
      Date = Date - 28;
      Month = Mon + 1;  //闰月判定并进位
    } else {
      Month = Mon;
      Year = Yea;
    }
    if ((Yea % 4 != 0) && (Date > 28)) {
      Date = Date - 27;
      Month = Mon + 1;  //非闰月判定并进位
    } else {
      Month = Mon;
      Year = Yea;
    }
    if (Month > 12) {
      Month = Month - 12;
      Year = Yea + 1;  //年超程进位
    }
  } else {
    Date = Dat;
    Month = Mon;
    Year = Yea;
  }

  //结果显示部分
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(38, 0);
  display.setTextSize(1);
  display.print(Year);

  display.setCursor(63, 0);
  display.setTextSize(1);
  display.print("-");
  display.setTextSize(1);
  display.setCursor(71, 0);
  sMonth = formatNumber(Month, 2);
  display.print(sMonth);


  display.setCursor(83, 0);
  display.setTextSize(1);
  display.print("-");
  display.setTextSize(1);
  display.setCursor(91, 0);
  sDate = formatNumber(Date, 2);
  display.print(sDate);


  display.setTextSize(2);
  display.setCursor(26, 13);
  sHour = formatNumber(Hour, 2);
  display.print(sHour);


  display.setCursor(46, 13);
  display.setTextSize(2);
  display.print(":");

  display.setTextSize(2);
  display.setCursor(56, 13);
  sMinute = formatNumber(Minute, 2);
  display.print(sMinute);


  display.setCursor(76, 13);
  display.setTextSize(2);
  display.print(":");

  display.setTextSize(2);
  display.setCursor(86, 13);
  sSecond = formatNumber(Second, 2);
  display.print(sSecond);


  display.setTextSize(1);
  display.setCursor(35, 33);
  display.print(gps.location.lng(), 8);


  display.setTextSize(1);
  display.setCursor(35, 43);
  display.print(gps.location.lat(), 8);


  // 创建一个字符串来存储所有变量
  // String message = String(Year) + "-" + String(sMonth) + "-" + String(sDate) + " "+ String(sHour) + ":" + String(sMinute) + ":" + String(sSecond) + " (" + String(Lng, 8) + "," + String(Lat, 8) + ")";

  // 输出整个字符串
  // Serial.println(message);



  display.setCursor(105, 53);
  display.setTextSize(1);
  display.print("m");

  display.setCursor(50, 53);
  display.setTextSize(1);
  display.print("km/h");


  display.setTextSize(1);
  display.setCursor(80, 53);
  display.print(gps.speed.mps());


  display.setTextSize(1);
  display.setCursor(25, 53);
  display.print(gps.speed.kmph());


  display.display();
  delay(500);
  display.clearDisplay();
}


// 格式化数字的函数
String formatNumber(int number, int digits) {
  String formatted = "";
  if (number < pow(10, digits - 1)) {
    formatted = String(number, DEC);
    while (formatted.length() < digits) {
      formatted = "0" + formatted;
    }
  } else {
    formatted = String(number, DEC);
  }
  return formatted;
}

为了将ESP8266与4G模块连接起来,您需要采取以下步骤: 1. 确保您的ESP8266具备与4G模块通信的硬件能力。有些ESP8266模块上预装了4G模块,但如果您的模块没有预装4G模块,您需要购买一个4G模块并将其安装在ESP8266上。确保这两个模块的引脚能够正确地连接。 2. 下载并安装适当的4G模块库。为了让ESP8266能够与4G模块进行通信,您需要下载4G模块相关的库文件。这些库文件可以从供应商或官方网站上获得。确保将库文件正确地导入到您的开发环境中。 3. 编写代码以实现ESP8266与4G模块的交互。使用所选择的开发环境,在您的代码中引入4G模块库并编写相应的程序。这些程序应该涵盖建立通信连接、发送和接收数据以及处理通信错误等方面。 4. 编译和上传代码以将其加载到ESP8266中。将ESP8266连接到计算机,并使用适当的烧写工具将编写的代码烧写到ESP8266中。确保代码能够成功地上传并运行。 5. 测试ESP8266与4G模块的连接。使用串口监视器或其他设备,监视ESP8266与4G模块之间的通信。发送一些数据并确保ESP8266能够正确地与4G模块进行通信,并能够接收和处理来自4G模块的响应。 需要注意的是,这只是一个简单的步骤指南,并不能覆盖所有可能的情况和具体的实施细节。具体的步骤可能会根据所使用的硬件、软件和4G模块的型号而有所不同。因此,在进行连接之前,建议查阅所使用的硬件和软件的相关文档,并参考出售4G模块的供应商提供的指南。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值