DIY一个GPS儿童追踪器

描述

  我做了一个 GPS 追踪器来追踪我孩子上学后的位置,并且能够让他们随时发送接送请求,以此能让我做好去接他们放学的准备。

  背景

  我的双胞胎喜欢骑自行车在小径上骑行,而且他们已经到了可以骑得比我快得多的年龄。作为父母,我想鼓励他们自己探索,但我也想密切关注他们的位置,以防出现问题。

  我的孩子们对于手机的认知还不够,所以我试图尽可能避免再重复两个数据计划。虽然说市面上已经有很多商业儿童 GPS 追踪器可用,但几乎所有追踪器都需要支付一笔额外的每月订阅费。

  以上的这一切让我开始思考——作为一名软件开发人员,我应该能够为自己构建这样的东西。

  所以诞生了这个项目!

  我的自定义跟踪器每五分钟读取一次 GPS 读数并将其显示在地图上。此外,跟踪器包括一个按钮,孩子们可以按下该按钮通过短信将他们的位置发送给父母。

  在本文中,我将向您展示我如何构建自己的自定义 GPS 跟踪器,并教您如何自己复制此设置的部分,让我们开始吧。

  第 1 步:组装硬件

  我使用的大部分硬件都来自Swan 的 Blues Wireless Feather Starter Kit。Feather Starter 套件包含一个 Notecard、一个 Notecarrier AF 和一个 Swan MCU。让我们分解它们中的每一个。

  Notecard

  Notecard是一个小型系统级模块,可以为几乎任何物联网项目添加连接性。Blues 生产蜂窝和 Wi-Fi 记事卡,但对于 GPS 跟踪,您需要使用蜂窝记事卡。

跟踪器

  我使用 Notecard 从外部天线(我将立即展示)收集 GPS 坐标,并通过蜂窝连接将这些坐标发送到云端。

  NoteAF

  Notecarriers 是配套板,可以轻松地使用 Notecard 进行物联网项目的原型设计和部署。Notecarrier 为您提供了一个方便的地方来连接 Notecard、为其供电、访问嵌入式天线以及通过 Qwiic 端口连接到 I2C 外围设备。

跟踪器

  Notecarrier AF 还包含与 Feather 兼容的接头,可以轻松嵌入任何与 Feather 兼容的设备以与 Notecard 一起使用。

  Swan

  Notecarrier 可以轻松连接与 Feather 兼容的 MCU,而我使用的 MCU 是Swan。Swan 几乎可以驱动任何物联网项目,因为它拥有 640KB 的大容量 RAM,可扩展至 55 个引脚以访问额外的 I/O 和总线,并内置对 C/C++、Arduino 和 CircuitPython 的支持。

跟踪器

  组装

  要组装此版本,您需要将 Notecard 和 Swan 都插入 Notecarrier AF。Blues 有一个很好的图片指南,如果您是第一次设置,我建议您遵循这些图片。

  组装好零件后,您将拥有一个看起来像这样的设置。

跟踪器

  为了完成构建,我确实添加了最后两件事。首先,我在 Notecarrier AF的插座上添加了一个外部Molex 天线。虽然 Notecarrier AF 有一个内置天线,但外部天线能够更快地接收 GPS 信号,这对我来说对这个项目很重要。

  接下来,我添加了一个小型 Lipo 电池,并将其BATTERY连接到 Notecarrier AF 上的 JST 连接器。当我在办公室外使用时,锂电池为设备供电。

  这是安装天线和电池后的设置:

跟踪器

  注意:Notecarrier-AF 包括一个微型 USB 端口,如果您为该端口供电,您可以为连接的锂电池充电。

  最后,因为我不希望孩子们使用它时一堆松散的碎片四处飞扬,所以我将锂电池用胶带粘在 Notecarrier AF 的背面,并将 Molex 天线的粘性面也贴在背面(中间有一点纸板)。

跟踪器

  从长远来看,我想为该设备建造一个漂亮的外壳,但对于原型设计,这给了我一件我的孩子可以随身携带的物品。

跟踪器

  现在您已经看到了硬件的样子,接下来让我们看看如何设置云后端。

  第 2 步:设置云后端

  Notecard 的一大优点是它知道如何将数据发送到云后端Notehub,开箱即用。Notehub 是一种托管服务,旨在连接到 Notecard 设备并同步数据。

  如果您跟随并想自己构建这个项目,您需要在notehub.io 上设置一个帐户,然后创建一个新项目。

跟踪器

  创建项目后,请确保复制新项目的 ProductUID(参见下面的屏幕截图),因为您需要该标识符才能将 Notecard 连接到新的 Notehub 项目。

跟踪器

  第 3 步:编写代码
如果您还记得第 1 步,我正在使用 Swan MCU 来执行驱动儿童跟踪器的代码。Swan 支持 CircuitPython 和 Arduino,因此您可以使用其中任何一个,但我选择了 Arduino,因为它是我之前在 Swan 上多次使用过的平台。

如果您是 Swan 新手,您需要先阅读Swan 快速入门,这将帮助您设置开发环境。如果您想使用与我相同的环境,请完成使用 Arduino IDE部分。

设置好开发环境后,您就可以继续编写代码本身了。在代码中,您需要处理三件主要的事情:

配置记事卡

配置获取 GPS 读数的频率

处理按钮按下

让我们依次解决这些问题。

注意:该项目的完整源代码可在下方找到。

配置Notecard

我们的第一个编码任务是设置Notecard。Notecard 的 API 是基于 JSON 的,因此配置 Notecard 就像发送几个 JSON 请求一样简单。

您可以通过在线游乐场、CLI或Arduino、Python、C/C++ 或 Go 的 SDK发送这些请求。在这种情况下,我们在 Swan MCU 上运行,因此我们将使用note-arduino,这是通过 Arduino 兼容的微控制器与 Notecard 进行通信的官方库。

具体来说,您需要确保使用项目的安装说明在 Arduino IDE 中安装库。note-arduino

之后,您需要从 Arduino 草图中的以下代码开始:

#include

#define serialDebug Serial
#define productUID "com.blues.tj:kidtracker"

Notecard notecard;

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

  notecard.begin();
  notecard.setDebugOutputStream(serialDebug);
 
  J *req1 = notecard.newRequest("hub.set");
  JAddStringToObject(req1, "product", productUID);
  JAddStringToObject(req1, "mode", "periodic");
  JAddNumberToObject(req1, "outbound", 5);
  notecard.sendRequest(req1);

  serialDebug.println("Setup complete");
}

注意:如果您继续进行操作,请确保将“com.blues.tj:kidtracker”更改为您在上一步中复制的 ProductUID。

首先,它初始化 Notecard ( notecard.begin()) 并设置调试输出流 ( notecard.setDebugOutputStream(serialDebug)),这允许您使用 Arduino IDE 的串行监视器查看日志。

接下来,代码使用 note-arduino 库格式化新hub.set命令并将其发送到 Notecard

J *req1 = notecard.newRequest("hub.set");
JAddStringToObject(req1, "product", productUID);
JAddStringToObject(req1, "mode", "periodic");
JAddNumberToObject(req1, "outbound", 5);
notecard.sendRequest(req1);

该hub.set命令控制您要将数据发送到哪个 Notehub 项目,并允许您为 Notecard 的工作方式设置一些基本配置。

设置"mode"为"periodic"告诉记事本定期连接到蜂窝网络,设置"outbound"为5告诉记事本每五分钟尝试一次连接。Notecard 也可以在连续模式下工作 ( "mode": "continuous"),但保持蜂窝调制解调器连接的恒定会消耗大量电池。

每五分钟发送一次数据已经相当耗电,但对于这个项目,我希望在孩子们骑自行车时经常看到数据,而且在两次使用之间为设备的锂电池充电也没有问题。如果您的项目需要在电池使用方面更加保守,您需要将该"outbound"值设置为相当高的数字。

此时您可以将您的程序发送给 Swan进行测试。如果一切顺利,您应该在 Arduino 串行监视器中看到以下内容:

跟踪器

  注意:如果您没有看到日志,您可以在while (!serialDebug)之后添加serialDebug.begin(),这会强制程序等到调试器可用后再继续。只需确保while (!serialDebug)在准备好部署设备时记得删除,因为如果在不存在串行调试器的情况下运行,它将导致无限循环。

  如果您返回到您的 Notehub 项目,您现在应该会看到您的设备已列出:

跟踪器

  此时,您的 Notecard 已连接到 Notehub,这意味着您已准备好发送位置数据。接下来让我们看看如何配置 Notecard 以收集该位置信息。

配置获取 GPS 读数的频率

Notecard 有许多请求,可让您准确配置应如何获取 GPS 读数。您需要向记事卡发送两个主要命令:card.location.mode和card.location.track.

下面的代码(您可以在现有hub.set代码下添加)发出这两个请求。

J *req2 = notecard.newRequest("card.location.mode");
JAddStringToObject(req2, "mode", "periodic");
JAddNumberToObject(req2, "seconds", 300);
notecard.sendRequest(req2);

J *req3 = notecard.newRequest("card.location.track");
JAddBoolToObject(req3, "start", true);
JAddBoolToObject(req3, "heartbeat", true);
JAddNumberToObject(req3, "hours", 12);
notecard.sendRequest(req3);

在card.location.mode通话中,设置"mode"to"periodic"告诉 Notecard 定期激活其 GPS 模块(而不是连续),设置"seconds"to300告诉 Notecard 尝试每 300 秒或五分钟读取一次 GPS 读数。

该card.location.track请求启动实际的跟踪过程。在周期性 GPS 模式下,Notecard 足够智能,仅在设备移动时才获取 GPS 读数(它使用内置的加速度计知道这一点)。将heartbeat选项设置为true告诉记事卡每 12 小时读取一次(因为我们设置"hours"为12),即使记事卡没有移动。

简而言之,这些请求告诉 Notecard 开始获取 GPS 读数;如果设备正在移动,则每五分钟读取一次;如果没有,则每十二小时阅读一次。

注意:如果您想了解有关如何将 Notecard 配置为资产跟踪器的更多信息,请务必阅读Notecard 的资产跟踪综合指南。
如果您将此程序发送到您的 Swan,您应该会在串行监视器中看到以下输出:

跟踪器

  更重要的是,如果您查看 Notehub 项目中的“事件”选项卡,您应该会开始看到_track.qo进入的文件。

跟踪器

  如果您双击一个事件并转到下一页的 JSON 选项卡,您可以查看捕获的 GPS 信息。

跟踪器

  可能需要几分钟才能看到您的第一个事件,因为记事卡可能需要一些时间才能建立 GPS 连接。尽量将您的设备放置在对天空有清晰视线的位置,并尽可能避开地下室等狭窄地方。

  此外,请记住,Notecard 仅在设备移动时才会获取新的 GPS 读数,因此您可能需要稍微摇晃设备才能_track.qo在测试期间看到后续文件进入。

  稍后我们将看看如何在地图上可视化您的 GPS 读数,但让我们首先结束这个项目的代码,看看如何让按下按钮发送带有位置的 SMS 消息。

  通知按钮

  我希望我的追踪器有一个孩子可以按下的按钮,并让该按钮向父母发送一条带有追踪器当前位置的短信。这是大多数商业儿童追踪器的一个功能,所以我相信这也是其他父母想要的。

  有很多方法可以处理 IoT 应用程序中的按钮按下,但 Swan 包含一个用户按钮 ( USER_BTN),用于处理这种确切的场景。

跟踪器

  要使用此按钮,您可以#define先在草图顶部添加以下行。

#define BUTTON_PIN USER_BTN
接下来,添加以下布尔值,您将使用它来跟踪用户是否请求了他们的位置。

bool locationRequested = false;
之后,将以下代码添加到现有setup()函数的末尾。此代码将中断附加到您的 Swan 按钮,并在触发时调用名为ISR.

pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), ISR, FALLING);
您需要定义ISR(中断服务例程),您可以通过将以下函数添加到您的草图来完成。

void ISR(void) {
  serialDebug.println("Button pressed");
  locationRequested = true;
}
locationRequested当用户按下 Swan 的用户按钮时,您的程序现在会更改布尔值。要响应该更改,您需要在 Arduinoloop()函数中监视该布尔值。您可以使用下面的代码来做到这一点。

void loop() {
  if (!locationRequested) {
    return;
  }

  J *req = notecard.newRequest("card.location");
  J *resp = notecard.requestAndResponse(req);
  serialDebug.println("Location:");
  double lat = JGetNumber(resp, "lat");
  double lon = JGetNumber(resp, "lon");
  serialDebug.println(lat, 10);
  serialDebug.println(lon, 10);

  if (lat == 0) {
    serialDebug.println("The Notecard does not yet have a location");
    // Wait a minute before trying again.
    delay(1000 * 60);
    return;
  }

  // http://maps.google.com/maps?q=,
  char buffer[100];
  snprintf(
    buffer,
    sizeof(buffer),
    "Your kids are requesting you. https://maps.google.com/maps?q=%.8lf,%.8lf",
    lat,
    lon
    );
  serialDebug.println(buffer);

  J *req2 = notecard.newRequest("note.add");
  JAddStringToObject(req2, "file", "twilio.qo");
  JAddBoolToObject(req2, "sync", true);
  J *body = JCreateObject();
  JAddStringToObject(body, "message", buffer);
  JAddItemToObject(req2, "body", body);
  notecard.sendRequest(req2);

  locationRequested = false;
  serialDebug.println("Location sent successfully.");
}
这里有很多,所以让我们分解这段代码。首先,请注意这里的所有逻辑都由if (!locationRequested) { return; }检查门控。也就是,如果用户没有按下按钮,在loop().

如果用户请求了一个位置,我们接下来使用 Notecard 的card.location请求来获取当前位置并将其打印出来。

J *req = notecard.newRequest("card.location");
J *resp = notecard.requestAndResponse(req);
serialDebug.println("Location:");
double lat = JGetNumber(resp, "lat");
double lon = JGetNumber(resp, "lon");
serialDebug.println(lat, 10);
serialDebug.println(lon, 10);
Notecard 可能还没有位置(项目启动时需要几分钟才能获取 GPS 位置),因此我们接下来检查是否card.location返回了有效位置。如果没有,我们会记录另一条消息,并等待一分钟后再重试。

if (lat == 0) {
  serialDebug.println("The Notecard does not yet have a location");
  // Wait a minute before trying again.
  delay(1000 * 60);
  return;
}
如果我们确实有一个有效的位置,我们接下来会格式化一条消息,其中包含指向跟踪器当前位置的 Google 地图链接。

char buffer[100];
snprintf(
  buffer,
  sizeof(buffer),
  "Your kids are requesting you. https://maps.google.com/maps?q=%.8lf,%.8lf",
  lat,
  lon
  );
serialDebug.println(buffer);
之后,我们使用 Notecard 的note.add请求将消息发送到 Notehub。

J *req2 = notecard.newRequest("note.add");
JAddStringToObject(req2, "file", "twilio.qo");
JAddBoolToObject(req2, "sync", true);
J *body = JCreateObject();
JAddStringToObject(body, "message", buffer);
JAddItemToObject(req2, "body", body);
notecard.sendRequest(req2);
最后,我们将布尔值翻转回false,因为我们现在已经完成了按钮按下的处理。

locationRequested = false;
serialDebug.println("Location sent successfully.");
这样,您就完成了编写运行该项目所需的代码!在最后一次将代码推送到设备之前,进入 Arduino IDE 的工具菜单,并将C 运行时库切换到支持浮点打印和扫描的库,因为我们在放置纬度和经度的逻辑中使用它进入谷歌地图网址。

跟踪器

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分