使用ESP8266+GPS模块+OLED屏幕DIY一块GPS定位器
创作时间:
作者:
@小白创作中心
使用ESP8266+GPS模块+OLED屏幕DIY一块GPS定位器
引用
CSDN
1.
https://blog.csdn.net/a654540233/article/details/142500249
本文将介绍如何使用ESP8266开发板、GPS模块和OLED屏幕制作一个GPS定位器。通过本教程,读者可以学习到硬件连接、程序编写以及数据处理等实用技能。
1. 材料准备
ESP8266开发板(建议购买带有CH340或CP2102驱动的NodeMCU)
GPS模块(支持NMEA协议)
0.96寸OLED屏幕(支持I²C协议)
若干杜邦线(母对母)
2. 接线说明
OLED屏幕接线
NODEMCU开发板 | OLED屏幕 | 备注 |
|---|---|---|
G | GND | NodeMCU中有多个地线引脚,选择一个即可 |
3V | VCC | NodeMCU中有多个3V供电引脚,选择一个即可 |
D1 (GPIO 5) | SCL | SCL代表"Serial Clock Line",即串行时钟线 |
D2 (GPIO 4) | SDA | SDA代表"Serial Data Line",即串行数据线 |
GPS模块接线
NODEMCU开发板 | GPS模块 | 备注 |
|---|---|---|
D5 (GPIO 14) | RXD | GPS的RX接模拟串口的TX引脚定义 |
D6 (GPIO 12) | TXD | GPS的TX接模拟串口的RX引脚定义 |
G | GND | NodeMCU中有多个地线引脚,选择一个即可 |
3V | VDD | NodeMCU中有多个3V供电引脚,选择一个即可 |
3. 烧录程序
打开Arduino IDE,选择开发板为NodeMCU 1.0 (ESP-12E Module)。使用以下代码,直接上传即可。如果本地没有相关库,需要手动安装TinyGPSPlus、Adafruit_GFX和Adafruit_SSD1306这三个库。
4. 上电效果
由于是在室内环境,GPS可能无法搜到卫星信号,因此可能没有数据输出。当GPS成功搜星后,会自动获取时间和经纬度信息。需要注意的是,这里的经纬度是WGS84坐标系,无法直接使用。如需转换为其他坐标系(如火星坐标系或百度坐标系),可以参考相关转换方法。
5. 完整代码
#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;
}
热门推荐
无偿献血:身体与心灵的双重馈赠
长青春痘了怎么办才能消除
两个月13张停货通知!白酒"涨价潮"戛然而止
五十年前中国法定结婚年龄:从18岁到22岁的历史变迁
达人合作话术的三个基本格式是什么?如何进行有效沟通
影响紫砂壶的价格有哪些因素
广东湛江“肥娟小吃店”爆火出圈,盘点走红网络的平民小店
股票期权行权日如何确定?
二战法国投降,到底是明智的选择,还是愚蠢的决定?
官杀运解析:命理学视角下的权位与挑战
铭瑄主板如何进入BIOS设置界面?
全球首个通用智能人“通通”亮相,还在持续“变聪明”
对应分析(Correspondence Analysis,CA)
腰肌劳损需要做哪些检查才能诊断出来?
医疗器械加速老化测试:如何选择正确的温湿度条件?
什么是深度学习?——深入解析现代人工智能的核心技术
什么是关税优惠政策
六大核心应用场景,解锁AI检测系统的智能安全之道
法院会判决第三人承担责任吗?
民事纠纷第三人可以不出庭吗
当前我国房地产业偷逃税存在的问题及其治理方式
仓库管理中PCS的含义、作用及未来发展趋势
AI识别智能人安全预警系统:用科技守护无人作业区安全
灭火器多久充装一次
灭火器充装规定
食品安全风险评估:对食品添加剂的法律分析与实践
去医院洗牙又贵又麻烦,可以自己买个仪器在家洗?
黄金净化及精炼提纯的工艺有哪些?
网贷逾期导致抑郁:如何应对与缓解心理压力
个人网贷债务重组指南:方法、注意事项与法律依据