回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【Arduino 动手做】带定位功能的便携式紧急按钮 (linkit One) 简单

头像 驴友花雕 2025.07.09 5 0

大家好 :)我想和你分享一个小项目。这是我对我妈妈(她得了癌症)做的一个便携式紧急按钮,我需要知道如果她需要我,我该如何找到她。这个按钮有一个 GPS 和 GSM 模块,可以发送短信和谷歌地图链接,并在短信上进行定位(很酷啊?:)),你可以把它放在你的腰带上。它对患有癌症、糖尿病等疾病的人有好处......

让我们进一步了解这个:)

第 1 步:材料
好吧,这就是您需要自己做的:

-Linkit One (带电池、GPS 和 GSM 模块)

-铁焊料

-3D 打印机

- 一个大按钮(否发送带有谷歌地图链接的短信)

- 三个 3mm LED(黄色、绿色和红色)

- 一台钻孔机(用于 Linkit 的钻孔)

- 大量柔性电缆线

- 热胶(按住按钮

-headers (在 Linkit 连接)

- 按钮开/关(关闭电池电源)

第 2 步:3D 图纸和文件
在这里你可以使用和编辑我的 3D 图纸模型,我用 Autodesk Inventor 2016 来画。也有用于 3D 打印的 STL 文件:)
https://dl.dropboxusercontent.com/u/40132197/drawings%20belt.zip

第 3 步:怎么做?
这很简单,您需要做的就是:

- 3D 打印 linkit 案例

- 将软线焊接到 LED、按钮、按钮开/关以及电池和接头上

- 使用热胶按住按钮

- 在外壳上钻孔以固定 Link One

- 将 GPS 和 GSM 模块放在外壳上并连接到 linkit

- 使用好的胶水将皮带固定在 Linkit 外壳上

PS:我需要剪掉我的 linkit 的 SPI 标头,因为按钮很大,我无法关闭 linkit case :P

linkit one 的接线连接端口为:

引脚 2 - 连接一根按钮线

GND- 连接按钮的另一根线

引脚 12 - 绿色 LED 正极(不需要电阻器)

引脚 11- 黄色 LED 正极

引脚 10- 红色 LED 正极

第 4 步:编码
该代码来自 Instructables 的另一个用户,但我稍微更改了一下。我添加了 LED 来指示电池电量。

它的工作原理是这样的:

- 如果绿色闪烁,则电池电量在 100% 到 67% 之间

- 如果黄色闪烁,则电池电量在 66% 到 34% 之间

- 如果红色闪烁,则电池电量在 <=33% 之间

你按下按钮,当所有 LED 都熄灭时,表示 linkit 发送了一条短信(我以后也会添加一个蜂鸣器)

您可以使用 USB 数据线轻松为电池充电。我将在此项目中添加一个蜂鸣器,以指示 linkit 发送了一条短信和电池的改进。

 

00.jpg
01.jpg
02.jpg
03.jpg
04.jpg

项目代码

 

 

代码
#include <LGPS.h>
#include <LGSM.h>
#include <LBattery.h>

gpsSentenceInfoStruct info;
char buff[256];
char url[120];
int fix=0;
int Ledpingreen = 12;
int Ledpinred = 10;
int Ledpinyellow = 11;
int valor=0;

const int noofDest = 2;
const char *numbers[] = {"+351XXXXXXXX"}; // numbers (+XXXXXXXXXX,+XXXXXXXXX)
char incoming_num[21] = "";
char message[256];

int panicButtonPin = 2;

static unsigned char getComma(unsigned char num,const char *str)
{
  unsigned char i,j = 0;
  int len=strlen(str);
  for(i = 0;i < len;i ++)
  {
     if(str[i] == ',')
      j++;
     if(j == num)
      return i + 1; 
  }
  return 0; 
}

static double getDoubleNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atof(buf);
  return rev; 
}

static double getIntNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atoi(buf);
  return rev; 
}

float toWGS84(float nmeaCoord) {
  float degWhole = float(int(nmeaCoord/100));
  float degDec = (nmeaCoord - degWhole*100)/60;
  return degWhole + degDec;  
}

void parseGPGGA(const char* GPGGAstr)
{
  
  double latitude;
  double longitude;
  int tmp, hour, minute, second, num;
  
  if(GPGGAstr[0] == '$')  {
    //latitude
    tmp = getComma(2, GPGGAstr);
    latitude = getDoubleNumber(&GPGGAstr[tmp]);
    tmp = getComma(3, GPGGAstr); // N or S
    float latWGS84 = toWGS84(latitude);
    if('S' == GPGGAstr[tmp]) {
      latWGS84 = -latWGS84; // negate if southern hemisphere coordinate
    }
    //longitude
    tmp = getComma(4, GPGGAstr);
    longitude = getDoubleNumber(&GPGGAstr[tmp]);
    tmp = getComma(5, GPGGAstr); // E or W
    float lonWGS84 = toWGS84(longitude);
    if('W' == GPGGAstr[tmp]) {
      lonWGS84 = -lonWGS84; // negate if western coordinate
    }
    
    sprintf(url,"http://maps.google.com/?q=%f,%f", latWGS84, lonWGS84);

    // location fix
    tmp = getComma(6, GPGGAstr);
    fix = getIntNumber(&GPGGAstr[tmp]);
  } else {
    Serial.println("GPS Data empty"); 
  }
}

void send_sms(char* number, char* message) {
  LSMS.beginSMS(number);
  for(int i = 0; i < strlen(message); i++) {
    LSMS.write(message[i]);
  }
  LSMS.endSMS();
}

void setup() {
  pinMode(panicButtonPin, INPUT_PULLUP);
  pinMode(Ledpingreen, OUTPUT);
  pinMode(Ledpinyellow, OUTPUT);
  pinMode(Ledpinred, OUTPUT);
  Serial.begin(115200);
  LGPS.powerOn();
  Serial.println("GPS turning on, wait ...");
  delay(3000);
}

void loop() {
    valor=100;
    valor= LBattery.level();
  if (valor==100){
    digitalWrite(Ledpingreen, HIGH);
     digitalWrite(Ledpinyellow, LOW);
     digitalWrite(Ledpinred, LOW);
     delay(500);
     digitalWrite(Ledpingreen, LOW);
     
  }
  else if (valor==66) {
    digitalWrite(Ledpingreen, LOW);
     digitalWrite(Ledpinyellow, HIGH);
     digitalWrite(Ledpinred, LOW);
     delay(500);
     digitalWrite(Ledpinyellow, LOW);
  }
  else{
    digitalWrite(Ledpingreen, LOW);
     digitalWrite(Ledpinyellow, LOW);
     digitalWrite(Ledpinred, HIGH);
     delay(500);
     digitalWrite(Ledpinred, LOW);
  }
  LGPS.getData(&info);
  Serial.print((char*)info.GPGGA);
  parseGPGGA((const char*)info.GPGGA);

  if(digitalRead(panicButtonPin) == LOW) {
    if(fix != 0) {
      sprintf(message, "I need help. I'm here: %s", url);
    } else {
      sprintf(message, "I need help. My last location was here: %s", url);
    }
    Serial.println(message);
    for(int i=0; i < noofDest; i++) {
      char num[20];
      sprintf(num, numbers[i]);
      send_sms(num, message);
    }
    delay(5000);
  }
  
  if(LSMS.available()) {
    LSMS.remoteNumber(incoming_num, 20);
    if(fix != 0) {
      sprintf(message, "My Location: %s", url);
    } else {
      sprintf(message, "Last Location: %s", url);
    }
    Serial.println(message);
    send_sms(incoming_num, message);
    LSMS.flush();
  }
}

【Arduino 动手做】带定位功能的便携式紧急按钮 (linkit One)
项目链接:https://www.instructables.com/Portable-emergency-button-with-localization-linkit/
项目作者:Macinblack20

项目代码:https://content.instructables.com/FIT/G7C5/IHTH0MCM/FITG7C5IHTH0MCM.ino
3D 文件:https://dl.dropboxusercontent.com/u/40132197/drawings%20belt.zip

 

05.jpg

评论

user-avatar
icon 他的勋章
    展开更多