
我做了一个GPS追踪器,可以追踪孩子放学后的位置,它可以让孩子随时发出接机请求,这样我就可以随时准备接孩子放学了。
背景
我的双胞胎喜欢在小路上骑自行车,他们的年龄比我骑得快得多。作为家长,我想鼓励他们自己探索,但也想密切关注他们的位置,以防出现问题。
孩子对手机了解不够,我尽量避免重复两次数据计划。虽然市面上有很多商用的儿童GPS追踪器,但是几乎所有的追踪器都需要额外支付月订费。
以上种种让我开始觉得,作为一个软件开发人员,我应该有能力为自己打造这样的东西。
于是这个项目诞生了!
我的定制跟踪器每五分钟读取一次GPS读数,并在地图上显示出来。此外,追踪器还包括一个按钮,孩子们可以按下这个按钮,通过短信将他们的位置发送给父母。
在这篇文章中,我将向你展示如何建立我自己的自定义GPS跟踪器,并教你如何复制这个设置的一部分。让我们开始吧。
步骤1:组装硬件
我使用的大部分硬件来自天鹅的蓝调无线羽毛入门套件。羽毛初学者工具包包括一个笔记卡,一个笔记载体AF和一个Swan MCU。让我们逐一分析。
留言卡
Notecard是一个小型系统级模块,可以为几乎任何物联网项目添加连接。Blues生产蜂窝和Wi-Fi笔记卡,但对于GPS跟踪,你需要使用蜂窝笔记卡。
我使用Notecard从外部天线(我将很快向您展示)收集GPS坐标,并通过蜂窝连接将它们发送到云端。
NoteAF
Notecarriers是一个支持板,您可以轻松地使用Notecard进行物联网项目的原型设计和部署。Notecarrier为您连接Notecard、为其供电、访问嵌入式天线以及通过Qwiic端口连接I2C外设提供了一个方便的地方。
Notecarrier AF还包括一个羽毛兼容连接器,可以轻松嵌入任何羽毛兼容设备,与Notecard配合使用。
天鹅
Notecarrier可以很方便的和Feather兼容的MCU连接,我用的MCU是Swan。Swan几乎可以驱动任何物联网项目,因为它拥有640KB RAM的大容量,可以扩展到55个引脚来访问额外的I/O和总线,并且内置了对C/C、Arduino和CircuitPython的支持。
放在一起
要组装这个版本,您需要将Notecard和Swan都插入Notecarrier AF。蓝调有很好的图片指南。如果你是第一次设置,我建议你按照这些图片。
组装部件后,您将得到如下所示的设置。
我添加了最后两个东西来完成构建。首先,我在Notecarrier AF的插座上添加了一个外部Molex天线。虽然Notecarrier AF内置天线,但是外置天线可以更快的接收GPS信号,这对于我这个项目来说非常重要。
接下来,我添加了一个小的Lipo电池,并将其电池连接到Notecarrier AF上的JST连接器。当我在办公室外使用时,锂电池为设备供电。
这是安装天线和电池后的设置:
注:注carrier-AF包括一个微型USB端口。如果给这个端口供电,就可以给连接的锂电池充电。
最后,因为不想让孩子使用时一堆松散的碎片飞来飞去,所以我把锂电池贴在了Notecarrier AF的背面,把Molex天线的粘性表面贴在了背面(中间有一点纸板)。
从长远来看,我想为设备建立一个漂亮的外壳,但对于原型设计,它给了我一些我的孩子可以随身携带的东西。
现在您已经看到了硬件的样子,让我们看看如何设置云后端。
步骤2:设置云后端
Notecard的一个很大的优点是,它知道如何将数据发送到云后端Notehub,开箱即用。Notehub是一个托管服务,旨在连接到Notecard设备并同步数据。
如果你跟随并且想要自己构建这个项目,你需要在notehub.io上设置一个账号,然后创建一个新的项目。
创建项目后,确保复制新项目的ProductUID(参见下面的截图),因为您需要这个标识符将Notecard连接到新的Notehub项目。
第三步:编写代码如果您还记得第一步,我正在使用Swan MCU来执行驱动儿童跟踪器的代码。Swan支持CircuitPython和Arduino,所以你可以使用任何一个,但我选择Arduino是因为它是我之前在Swan上多次使用的平台。
如果您是Swan新手,您需要先阅读Swan快速入门,这将有助于您设置开发环境。如果你想和我使用相同的环境,请完成使用Arduino IDE部分。
设置开发环境后,您可以继续编写代码本身。在代码中,您需要处理三件主要的事情:
配置便笺
配置获取GPS读数的频率。
按下处理按钮
让我们依次解决这些问题。
注意:这个项目的完整源代码可以在下面找到。
配置便笺
我们的第一个编码任务是建立Notecard。Notecard的API是基于JSON的,所以配置Notecard就像发送几个JSON请求一样简单。
你可以通过在线游乐园、Arduino的CLI或SDK、Python、C/C或Go发送这些请求。在这种情况下,我们运行在Swan MCU上,所以我们将使用note-arduino,这是通过arduino兼容的微控制器与Notecard通信的官方库。
具体来说,您需要确保使用项目的安装说明将库安装在Arduino IDE中。注意-arduino
之后,你需要从Arduino的草图中的以下代码开始:
#包括
# define Serial debug Serial # define product uid ' com . blues . TJ:kid tracker '
便签卡;
void setup(){ serial debug . begin(115200);
note card . begin();note card . setdebugoutputstream(serial debug);j * req 1=note card . new request(' hub . set ');JAddStringToObject(req1,'产品'product uid);JAddStringToObject(req1,'模式''周期');JAddNumberToObject(请求1,'出站'5);note card . send request(req 1);
serialDebug.println('安装完成');}
注意:如果继续,请确保将“com.blues.tj:kidtracker”更改为您在上一步中复制的ProductUID。
首先,它初始化Notecard (notecard.begin())并设置调试输出流(Notecard。设置调试输出流(串行调试)),允许您使用Arduino IDE的串行监视器查看日志。
接下来,代码使用note-arduino库格式化新的hub.set命令,并将其发送到Notecard。
j * req 1=note card . new request(' hub . set ');JAddStringToObject(req1,'产品'product uid);JAddStringToObject(req1,'模式''周期');JAddNumberToObject(请求1,'出站'5);note card . send request(req 1);
hub.set命令控制您希望将数据发送到哪个Notehub项目,并允许您为Notecard的工作方式设置一些基本配置。
将“模式”设置为“定期”以告知记事本定期连接到蜂窝网络,将“出站”设置为5以告知记事本每五分钟尝试连接一次。Notecard也可以在连续模式下工作(“mode”:“continuous”),但保持蜂窝调制解调器连接不变会消耗大量电池。
每五分钟发送一次数据是相当耗电的,但是对于这个项目,我希望孩子们在骑自行车的时候经常看到数据,在使用之间给设备的锂电池充电是没有问题的。如果您的项目需要在电池使用方面更加保守,您需要将“出站”值设置为一个相当大的数字。
此时,您可以将您的程序发送到Swan进行测试。如果一切顺利,您应该会在Arduino串行监视器中看到以下内容:
注意:如果没有看到日志,可以在while(!添加serialDebug。begin () after serialdebug),这将强制程序等待,直到调试器可用。请确保在(!idspnonenote)运行期间。SerialDebug)在准备部署设备时,记得删除它,因为如果在没有串行调试器的情况下运行它,将导致无限循环。
如果您返回到您的Notehub项目,您现在应该看到您的设备被列出:
此时,您的Notecard已连接到Notehub,这意味着您已准备好发送位置数据。接下来,让我们看看如何配置Notecard来收集位置信息。
配置获取GPS读数的频率。
Notecard有许多请求,允许您配置如何获取GPS读数。您需要向便笺发送两个主要命令:card.location.mode和card.location.track。
以下代码(可以添加到现有的hub.set代码下)发出这两个请求。
j * req 2=note card . new request(' card . location . mode ');JAddStringToObject(req2,'模式''周期');JAddNumberToObject(req2,'秒'300);note card . send request(req 2);
j * req 3=note card . new request(' card . location . track ');JAddBoolToObject(req3,' start 'true);JAddBoolToObject(req3,' heartbeat 'true);JAddNumberToObject(req3,'小时'12);note card . send request(req 3);
在card.location.mode调用中,将“mode”设置为“periodic”以告诉Notecard定期(而不是连续)激活其GPS模块,并将“seconds”设置为300以告诉Notecard尝试每300秒或5分钟读取一次GPS读数。
card.location.track请求开始实际的跟踪过程。在周期性GPS模式下,Notecard足够智能,只有在设备移动时才能获得GPS读数(它通过内置的加速度计知道这一点)。将heartbeat选项设置为true,告诉便笺每12小时读取一次(因为我们将“小时”设置为12),即使便笺没有移动。
简而言之,这些请求告诉Notecard开始获取GPS读数;如果设备在移动,每五分钟读一次;如果没有,每十二小时读一遍。
注意:如果您想了解更多关于如何将Notecard配置为资产跟踪器的信息,请务必阅读Notecard的全面的资产跟踪指南。如果您将这个程序发送到Swan,您应该在串行监视器中看到以下输出:
更重要的是,如果您查看Notehub项目中的Events选项卡,您应该开始看到由_ track.qo输入的文件.
如果双击一个事件并转到下一页的JSON选项卡,您可以查看捕获的GPS信息。
可能需要几分钟才能看到您的第一个活动,因为便笺可能需要一些时间来建立GPS连接。尽量把设备放在能清楚看到天空的位置,尽量避开地下室等狭窄的地方。
此外,请记住Notecard仅在设备移动时获得新的GPS读数,因此您可能需要轻微摇动设备以_track.qo查看测试期间输入的后续文件。
稍后,我们将了解如何在地图上可视化您的GPS读数,但让我们先结束这个项目的代码,看看如何使按钮按下以发送带有位置的短信。
通知按钮
我希望我的追踪器有一个按钮,孩子们可以按下它,并让按钮向父母发送一条短信,告知追踪器的当前位置。这是大多数商业儿童追踪器的功能,所以我相信这也是其他家长想要的。
在物联网应用中,有许多方法来处理按钮按压,但Swan包含一个用户按钮(USER_BTN)来处理这种确切的场景。
要使用此按钮,您可以首先在草图顶部#定义以下线条。
#define BUTTON_PIN USER_BTN接下来,添加以下布尔值,您将使用它来跟踪用户是否请求了他们的位置。
bool locationRequested=false然后,将以下代码添加到现有setup()函数的末尾。这段代码将一个中断附加到Swan按钮上,当被触发时,它调用一个名为ISR的调用。
pinMode(BUTTON_PIN,INPUT _ pull up);附加中断(digitalpinpointerum(BUTTON _ PIN),ISR,下降);您需要定义ISR(中断服务例程),您可以通过将以下函数添加到您的草图来完成。
void ISR(void){串行调试。println('按钮已按下');locationRequested=true}位置请求当用户按下天鹅的用户按钮时,您的程序现在会更改布尔值。要响应该更改,您需要在Arduinoloop()函数中监视该布尔值。您可以使用下面的代码来做到这一点。
void loop() { if(!请求的位置){ return}
j * req=便笺。新请求('卡。位置’);j * resp=便笺。请求安德烈响应(req);串行调试。println(' Location:');double lat=JGetNumber(resp,' lat ');double lon=JGetNumber(resp,' lon ');serialDebug.println(lat,10);serialDebug.println(lon,10);
if(lat==0){串行调试。打印便条卡还没有位置');//请稍等片刻,然后重试。延时(1000 * 60);返回;}
//http://maps.google.com/maps?q=,字符缓冲区[100];snprintf( buffer,sizeof(buffer),'您的孩子在请求您。https://maps.google.com/maps?q=%.8lf,%.8lf '拉特隆);serialDebug.println(缓冲区);
j * req 2=便笺。新请求('注意。添加’);JAddStringToObject(req2,' file '' twilio。qo’);JAddBoolToObject(req2,' sync 'true);j * body=JCreateObject();JAddStringToObject(正文,'消息,缓冲区);JAddItemToObject(req2,' body 'body);便签卡。发送请求(请求2);
location requested=false serial debug . println('位置发送成功。');}这里有很多,所以让我们分解这段代码。首先,请注意这里的所有逻辑都由如果(!请求的位置){ return}检查门控。也就是,如果用户没有按下按钮,在循环()。
如果用户请求了一个位置,我们接下来使用留言卡的卡片。位置请求来获取当前位置并将其打印出来。
j * req=便笺。新请求('卡。位置’);j * resp=便笺。请求安德烈响应(req);串行调试。println(' Location:');double lat=JGetNumber(resp,' lat ');double lon=JGetNumber(resp,' lon ');serialDebug.println(lat,10);serialDebug.println(lon,10);留言卡可能还没有位置(项目启动时需要几分钟才能获取全球(卫星)定位系统位置),因此我们接下来检查是否卡片。位置返回了有效位置。如果没有,我们会记录另一条消息,并等待一分钟后再重试。
if(lat==0){串行调试。打印便条卡还没有位置');//请稍等片刻,然后重试。延时(1000 * 60);返回;}如果我们确实有一个有效的位置,我们接下来会格式化一条消息,其中包含指向跟踪器当前位置的谷歌地图链接。
茶缓冲器[100];snprintf( buffer,sizeof(buffer),'您的孩子在请求您。https://maps.google.com/maps?q=%.8lf,%.8lf '拉特隆);serialDebug.println(缓冲区);之后,我们使用留言卡的注释。添加请求将消息发送到Notehub。
j * req 2=便笺。新请求('注意。添加’);JAddStringToObject(req2,' file '' twilio。qo’);JAddBoolToObject(req2,' sync 'true);j * body=JCreateObject();JAddStringToObject(正文,'消息,缓冲区);JAddItemToObject(req2,' body 'body);便签卡。发送请求(请求2);最后,我们将布尔值翻转回假的,因为我们现在已经完成了按钮按下的处理。
location requested=false serial debug . println('位置发送成功。');这样,您就完成了编写运行该项目所需的代码!在最后一次将代码推送到设备之前,进入Arduino IDE的工具菜单,并将C运行时库切换到支持浮点打印和扫描的库,因为我们在放置纬度和经度的逻辑中使用它进入谷歌地图网址。








