Arduino UNO GPS 制作 里程表 经纬度

机缘

        上过月买了一个GPS模块,然后我用esp32读取GPS数据,并使用LVGL显示GPS信息。期间踩了很多坑,我用乐鑫的IDF开发,自己写了一个GPS信息提取方法,BUG很多,而且加上多任务处理,串口中断,快给我人搞麻了。

        今天在网上找到一个解析GPS的库,使用起来非常简单。我立马开始动手实验一下。


硬件

我顺手拿了一块 Arduino UNO和一块LCD1602,然后用杜邦线连一下。


软件部分

这个解析GPS的库是 “TinyGPSPlus”,里面自带很多例子,我照着例子一顿复制粘贴,然后下载运行,一次就成功了。功能是在LCD1602上显示经纬度,已连接卫星个数,距起始点的距离和方向。

//LCD1602
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

//GPS
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

double home_lat = 0.0, home_lon = 0.0;

void setup()
{
    //初始化LCD屏幕
    lcd.begin();
    lcd.backlight();
    lcd.setCursor(0, 0);

    Serial.begin(115200);
    ss.begin(GPSBaud);

    while(!gps.location.isValid())
    {
        lcd.print("Searching for stars");
        smartDelay(1000);
    }
    lcd.setCursor(0, 0);
    lcd.print("   Search is OK!   ");

    smartDelay(1000);

    home_lat=gps.location.lat();
    home_lon=gps.location.lng();

    lcd.clear();
    lcd.setCursor(0, 0);

}

void loop()
{

    double home_lat_NEW = 0.0, home_lon_NEW = 0.0;


    if(gps.location.isValid())
    {
        home_lat_NEW=gps.location.lat();
        home_lon_NEW=gps.location.lng();

        //输出经纬度
        lcd.setCursor(0, 0);
        printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
        lcd.setCursor(0, 1);
        printFloat(gps.location.lng(), gps.location.isValid(), 11, 6);

        unsigned long distanceKmToLondon =
            (unsigned long)TinyGPSPlus::distanceBetween(
                home_lat_NEW,
                home_lon_NEW,
                home_lat,
                home_lon);

        double courseToLondon =
            TinyGPSPlus::courseTo(
                home_lat_NEW,
                home_lon_NEW,
                home_lat,
                home_lon);
        //输出离家距离,已校准卫星个数,方向
        lcd.setCursor(11, 0);
        printInt(distanceKmToLondon, gps.location.isValid(), 5);
        lcd.setCursor(15, 0);
        printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
        lcd.setCursor(13, 1);
        printInt(courseToLondon, gps.location.isValid(), 5);
    }

    smartDelay(1000);

    if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));
}

//只能延时,在延时的过程中处理GPS的数据
static void smartDelay(unsigned long ms)
{
    unsigned long start = millis();
    do
    {
        while (ss.available())
            gps.encode(ss.read());
    }
    while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
    if (!valid)
    {
        while (len-- > 1)
            lcd.print('*');
        lcd.print(' ');
    }
    else
    {
        lcd.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
            lcd.print(' ');
    }
    smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
    char sz[32] = "*****************";
    if (valid)
        sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
    if (len > 0)
        sz[len-1] = ' ';
    lcd.print(sz);
    smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
    if (!d.isValid())
    {
        lcd.print(F("********** "));
    }
    else
    {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
        lcd.print(sz);
    }

    if (!t.isValid())
    {
        lcd.print(F("******** "));
    }
    else
    {
        char sz[32];
        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
        lcd.print(sz);
    }

    printInt(d.age(), d.isValid(), 5);
    smartDelay(0);
}

static void printStr(const char *str, int len)
{
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
        lcd.print(i<slen ? str[i] : ' ');
    smartDelay(0);
}

运行效果

这个是在室内测试的,可以接收25颗卫星,在室外可以接收30颗卫星,精度的话,跟手机上的相差不大。


总结

哎,自己写代码,搞三天勉强能用;用别人开源代码,几分钟搞定。以后还是少造轮子吧。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Arduino Uno是一种开源的电子开发板,内置了Atmega328P微控制器。它具有多个数字输入/输出引脚、模拟输入引脚和其他与电子元件交互的接口,具备一定的处理和控制能力,可以用于制作各种电子原型和小型项目。 对于制作智能手表,Arduino Uno是可以实现的。首先,你可以通过连接一个LCD显示屏幕,显示时间、日期等基本信息。其次,你可以利用加速度传感器、陀螺仪和运动传感器等模块,实现计步、计时、定位等功能。同时,利用蓝牙或者Wi-Fi模块,可以将智能手表连接到手机或电脑,实现与其他设备的通讯和数据传输。 通过编写Arduino Uno的程序,结合不同的传感器和模块,你可以根据自己的需求和创意,扩展更多的功能,比如心率监测、温度检测、通知提醒等等。 需要注意的是,Arduino Uno虽然具有一定的处理能力,但其内存和资源相对较小,无法处理过于复杂的任务。因此,在制作智能手表时,你可能需要权衡功能和性能的平衡,并合理安排代码和资源的利用。 总结而言,Arduino Uno可以用于制作基本的智能手表,并通过连接不同的模块和传感器,实现更多的功能。不同的创意和需求会导致不同的应用方案,由你来决定如何利用Arduino Uno打造出自己的智能手表。 ### 回答2: 可以,Arduino Uno是一款开放源代码的单片机开发板,具有灵活性和可编程性,适合制作各种智能设备,包括智能手表。 智能手表一般包括时钟显示、计时器、闹钟等功能,而Arduino Uno具有数码管和LCD显示屏的接口,可以用于实现时钟显示功能。通过添加按键、触摸屏等输入设备,可以实现对时间的调整和设置功能。另外,加入电池供电和蓝牙模块,可以实现与手机连接、接收来电和短信等通知功能。 除了基本的功能,还可以添加其他传感器模块,如加速度传感器、心率传感器等,可以实现运动监测、睡眠监测等健康功能。 此外,Arduino Uno可以通过编程控制外部LED灯和蜂鸣器,可以用来作为闹钟提醒功能。 总之,虽然Arduino Uno的资源有限,但它提供了足够的接口和功能扩展能力,可以作为制作智能手表的基础平台。通过添加适当的传感器和模块,进行编程实现所需功能,就可以自主制作一款实用的智能手表。 ### 回答3: Arduino Uno可以用来制作智能手表。对于智能手表的功能来说,Arduino Uno可以提供一些基本的功能和特性。首先,Arduino Uno板载了一个微控制器,它可以接收和处理外部传感器的数据,包括温度、湿度、光线等等。这样,通过连接适当的传感器,可以实现智能手表的环境监测和数据采集。 其次,Arduino Uno还可以连接到蓝牙模块,这意味着可以与其他的蓝牙设备(如手机、电脑等)进行无线通讯,实现智能手表与其他设备的互联互通。通过蓝牙连接,智能手表可以接收来自手机的消息、电话、社交媒体通知等等,或者将数据传输给其他设备。 此外,Arduino Uno还可以连接到液晶显示屏,可以实时显示时间、日期等信息,也可以显示来自手机或其他设备的通知。同时,Arduino Uno的编程灵活性也意味着可以编写程序实现更多的功能,如计步器、闹钟、定时提醒等。 总结来说,虽然Arduino Uno的资源有限,但它提供了足够的功能和特性来制作一个简单的智能手表。如果需要更复杂的功能和高级特性,可能需要选择使用更强大的硬件平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎之名之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值