47711浏览
查看: 47711|回复: 15

[进阶] 使用SIM808 with Leonardo mainboard实现远程定位

[复制链接]
今天教大家一个SIM808 with Leonardo mainboard实现远程定位的方法!具体实现是基于中国移动物联网开放平台(OneNet)及GPRS通信。具体实现原理为: 通过给SIM808 with Leonardo mainboard编程使其上传GPS数据至OneNet平台,计算机软件通过从OneNet平台获取GPS数据并处理后在地图上显示板子所在位置。
好的,其它废话就不多说啦!大家按照如下步骤一步一步来就行了.........


第一步,按照如下方法在OneNet平台创建一个转发设备
            1、浏览器打开https://open.iot.10086.cn注册一个账号,注册后重新打开链接。
            2、点击右上角“项目管理”进入页面后找到“新建项目”并单击进入如下页面。
             使用SIM808 with Leonardo mainboard实现远程定位图1  
          3、在如上页面中输入项目名"ABCD",点击“立即创建项目”进入如下页面
             使用SIM808 with Leonardo mainboard实现远程定位图2
          4、点击“为你的项目添加一个设备”进入如下页面
            使用SIM808 with Leonardo mainboard实现远程定位图3
           5、在“设备名称”栏输入设备名:“123456”
             使用SIM808 with Leonardo mainboard实现远程定位图4
           6、继续下拉页面至地图,使用鼠标单击地图以设置设备位置,设置好后点击“添加设备”完成设备的创建
              使用SIM808 with Leonardo mainboard实现远程定位图5
           7、返回“项目管理”(如上图)并点击选择“ABCD”的项目进入如下页面

              使用SIM808 with Leonardo mainboard实现远程定位图6
           8、点击“添加APIKey”进入如下页面并按如图注释创建一个名称为“TEST APIKey”的API密钥
               使用SIM808 with Leonardo mainboard实现远程定位图7
          至此,我们就已经完成了在OneNet平台的转发设备的创建!


第二步、使用SIM808 with Leonardo mainboard将GPS数据发送到OneNet:

1、将下面的代码粘贴到Arduino IDE编译后下载到板//*********************************************File Start*******************************************//
#include <TimerOne.h>
#include <string.h>
#define Success 1U
#define Failure 0U

const unsigned int bufferLength=600;
char RxBuffer[bufferLength];
unsigned int ii=0;
int L = 13;

const char datastreams_id[]="GPS_Data";//-------------------------设置转发名称
const char device_id[]="154088";//----------------------------------修改此处为"设备ID"
const char api_key[] ="wdovZ5BMOSDNZZAg2a2eI7bCbBAA";//--修改此处为"设备APIKey"
struct
{
unsigned char CMD;
unsigned int LengthA;
char fixed[20];
unsigned char id_length;
char id[20];
unsigned char LengthB1;
unsigned char LengthB2;
char api_key[50];
}login;

struct
{
unsigned char CMD;
unsigned char LengthA;
unsigned char mark;
unsigned char type;
unsigned char LengthB1;
unsigned char LengthB2;
char streamA[24];
char id[20];
char streamB[27];
char GPS_Buffer[150];
char streamC[7];
}Save_Data;

unsigned char mystrstr(char *s,char *t,unsigned int Length_s,unsigned int Length_t)
{        char x=0;char *p;p=t;
int i=0,j=0;
for(;i < Length_s; s++,i++)
            {  
          while(*t == *s)
              {  s++;t++;i++;j++;   
                 if (j>= Length_t) return 1;
              }
              s-=j;
              t=p;j=0;
                }
        return NULL;
}
void clrRxBuffer(void)
{
  memset(RxBuffer,0,bufferLength);
  ii=0;
}

void SIM808_ERROR(void)
{
  while(1)
  {
  digitalWrite(L, HIGH);
  delay(300);
  digitalWrite(L, LOW);
  delay(300);
  }
}

unsigned long  Time_Cont=0;
void Timer1_handler(void)
{
Time_Cont++;
}

unsigned int Send_Command(char *Command,char *Response,unsigned int Res_Length,unsigned long Timeout,unsigned char Retry)
{
  clrRxBuffer();
  for(unsigned char n=0;n<Retry;n++)
  {
  Serial1.write(Command);
  Serial1.write("\r\n");
  Time_Cont=0;
  while(Time_Cont<Timeout)
  {
    readBuffer();
    if((mystrstr(RxBuffer,Response,ii,Res_Length))!=NULL)
    {
      clrRxBuffer();
      return Success;
    }
   }
  Time_Cont=0;
  }
  clrRxBuffer();
  return Failure;
}

char EER_GPS_Buffer[24]={"$GPRMC,,V,,,,,,,,,,N*7F"};
int GET_GPS(void)
{ char *GPS_BufferHead,*GPS_BufferTail;

clrRxBuffer();
  if(Send_Command("AT+CGNSTST=1","OK",2,3000,5)==Success);
   Time_Cont=0;
  while(Time_Cont<5000)
  {
    readBuffer();

   if((GPS_BufferHead = strstr(RxBuffer, "$GPRMC,")) != NULL)
  {
    if(((GPS_BufferTail = strstr(GPS_BufferHead,"\r\n")) != NULL)&&(GPS_BufferTail >GPS_BufferHead)){
      memcpy(Save_Data.GPS_Buffer,GPS_BufferHead,GPS_BufferTail-GPS_BufferHead);
    clrRxBuffer();
    break;
    }
  }
  memcpy(Save_Data.GPS_Buffer,EER_GPS_Buffer,24);
  }
   Time_Cont=0;
    clrRxBuffer();
     if(Send_Command("AT+CGNSTST=0","OK",2,5000,10)==Success) ;
}

void SIM808_Initialization()
{
   if(Send_Command("AT","OK",2,3000,10)==Success);
   else SIM808_ERROR();

if(Send_Command("ATE0","OK",2,3000,10)==Success);
else SIM808_ERROR();

if(Send_Command("AT+CREG?","+CREG: 0,1",10,2000,20)==Success);
else SIM808_ERROR();

if(Send_Command("AT+CGREG?","+CGREG: 0,1",11,2000,20)==Success)
else SIM808_ERROR();
}


void SIM808_BOOT()
{
   if(Send_Command("AT","OK",2,100,5)==Success) return;
else
{
   digitalWrite(12, HIGH);
if(Send_Command("AT","OK",2,1000,20)==Success) {digitalWrite(12, LOW);return;}
else
{
   digitalWrite(12, LOW);
   SIM808_ERROR();
}
}
}

void Process_Save_Data()
{
}

void setup()
{
  Serial1.begin(115200);
  pinMode(L, OUTPUT);
  pinMode(12, OUTPUT);

  Timer1.initialize(1000);
  Timer1.attachInterrupt(Timer1_handler); // blinkLED to run every 1ms
  delay(5000);
digitalWrite(L, HIGH);


  SIM808_BOOT();

SIM808_Initialization();
if(Send_Command("AT+CGNSPWR=1","OK",2,3000,2)==Success) ;
else SIM808_ERROR();
}

const char data[]={0x00,0x03,0x45,0x44,0x50,0x01,0x40,0x01,0x00,0x00};
char response[]={0x20,0x02,0x00,0x00};
char responseX[]={0x0D,0x0A,0x20,0x02,0x00,0x00,0x0D,0x0A,0x3E,0x20};

void loop()
{
GET_GPS();

if(Send_Command("AT+CIPSTART=\"TCP\",\"183.230.40.39\",\"876\"","CONNECT",7,10000,2)==Success);//Serial.write("BinGo......AT+CIPSTART=\"TCP\"\r\n");

if(Send_Command("AT+CIPSEND",">",1,3000,2)==Success);// Serial.write("BinGo......AT+CIPSEND\r\n");

login.CMD=0x10;
login.id_length=strlen(device_id);

for(unsigned char i=0;i<10;i++)
{
login.fixed=data;
}
strcpy(login.id,device_id);


login.LengthB1=0x00;
login.LengthB2=strlen(api_key);
strcpy(login.api_key,api_key);
login.LengthA=login.LengthB2+login.id_length+13;

Serial1.write(login.CMD);
Serial1.write(login.LengthA);
for(unsigned char i=0;i<10;i++)
{
Serial1.write(login.fixed);
}
Serial1.write(login.id_length);
Serial1.write(login.id);
Serial1.write(login.LengthB1);
Serial1.write(login.LengthB2);
Serial1.write(login.api_key);
if(Send_Command("32",response,sizeof(response)/sizeof(char),3000,1)==Success);
if(Send_Command("AT+CIPSEND",">",1,2000,1)==Success);


Save_Data.CMD=0X80;
Save_Data.mark=0x00;
Save_Data.type=0x01;
Save_Data.LengthB1=0x00;
strcpy(Save_Data.streamA,"{\"datastreams\":[{\"id\":\"");
strcpy(Save_Data.id,datastreams_id);
strcpy(Save_Data.streamB,"\",\"datapoints\":[{\"value\":\"");
strcpy(Save_Data.streamC,"\"}]}]}");

Save_Data.LengthB2=strlen((const char *)Save_Data.streamA)+strlen(datastreams_id)+strlen((const char *)Save_Data.streamB)+strlen((const char *)Save_Data.GPS_Buffer)+strlen((const char *)Save_Data.streamC);
Save_Data.LengthA=Save_Data.LengthB2+4;

Serial1.write(Save_Data.CMD);
Serial1.write(Save_Data.LengthA);
if(Save_Data.LengthA>127)Serial1.write(0x01);
Serial1.write(Save_Data.mark);
Serial1.write(Save_Data.type);
Serial1.write(Save_Data.LengthB1);
Serial1.write(Save_Data.LengthB2);
Serial1.write(Save_Data.streamA);
Serial1.write(Save_Data.id);
Serial1.write(Save_Data.streamB);
Serial1.write(Save_Data.GPS_Buffer);
Serial1.write(Save_Data.streamC);
if(Send_Command("32","SEND OK",7,3000,1)==Success);

memset(Save_Data.GPS_Buffer, 0, sizeof Save_Data.GPS_Buffer);
clrRxBuffer();

if(Send_Command("AT+CIPCLOSE","CLOSE OK",8,1000,1)==Success);
clrRxBuffer();

  digitalWrite(L, HIGH);
  delay(300);
  digitalWrite(L, LOW);
}
void readBuffer()
{
  while(Serial1.available())
        {
         RxBuffer[ii++]=Serial1.read();
         if(ii==bufferLength)clrRxBuffer();
         }
}
//*********************************************File End*******************************************//

2、下载完成后按照如下方式连接GPS及GSM天线,注意供电方式及NO BAT?的跳线帽切换。
使用SIM808 with Leonardo mainboard实现远程定位图8
3、程序会自动运行并使模块开机,等待约1分钟后开始将GPS数据上传到OneNet,届时L灯闪烁一次表示数据上传成功一次。

第三步、测试工具软件的使用:
打开工具软件,待地图加载完毕后点击“参数设置”选项卡,并按之前代码中设置的参数值填入图框中的三个文本框。输入完成后点击“连接”按钮开始接收板子上传的数据。使用SIM808 with Leonardo mainboard实现远程定位图9
由于天气原因或板子没有放置在露天位置导致GPS未成功定位的时候,软件中的“数据记录”中会显示“GPS数据无效!-----<服务器数据上传时间>20**-**-** **:**:**.***”(如下图)。
使用SIM808 with Leonardo mainboard实现远程定位图10
当成功定位时,我们可以在软件“实时地图”选项卡中查看到板子所在具体位置。下面是使用效果!
使用SIM808 with Leonardo mainboard实现远程定位图11






bobo  NPC

发表于 2015-9-10 17:20:56

不错,用这个模块做一个自动升空拍照的气球是非常方便的。
回复

使用道具 举报

Grey  中级技匠

发表于 2015-9-10 17:44:41

看上去很有意思的样子,又多了一个物联网案例!
回复

使用道具 举报

吹口琴的钢铁侠  初级技匠

发表于 2015-9-10 20:29:56

直接上传多费流量啊.......
回复

使用道具 举报

Strictus  初级技师
 楼主|

发表于 2015-9-11 13:16:06

Grey 发表于 2015-9-10 17:44
看上去很有意思的样子,又多了一个物联网案例!

每次上传消耗不了1KB的流量!
回复

使用道具 举报

Strictus  初级技师
 楼主|

发表于 2015-9-11 16:10:05

吹口琴的钢铁侠 发表于 2015-9-10 20:29
直接上传多费流量啊.......

每次上传消耗不了1KB的流量!
回复

使用道具 举报

Phoebe  高级技匠

发表于 2015-9-11 16:52:16

好实用的教程
回复

使用道具 举报

吹口琴的钢铁侠  初级技匠

发表于 2015-9-13 19:16:29

Strictus 发表于 2015-9-11 16:10
每次上传消耗不了1KB的流量!

一分钟就要上传好多好多次吧..............还是觉得很费
回复

使用道具 举报

dsweiliang  初级技神

发表于 2015-9-14 21:12:03

如果能做得更小更轻就更好了
回复

使用道具 举报

zcx  见习技师

发表于 2016-2-19 15:52:24

大牛,远程定位测试工具发我一份,邮箱408323171@qq.com,,,谢谢
回复

使用道具 举报

Strictus  初级技师
 楼主|

发表于 2016-2-25 13:50:58

zcx 发表于 2016-2-19 15:52
大牛,远程定位测试工具发我一份,邮箱,,,谢谢

下载链接 https://mc.dfrobot.com.cn/thread-12647-1-1.html#pid41958
回复

使用道具 举报

Rockets  NPC

发表于 2016-6-30 11:18:32

计算下流量消耗吧。我记得这个流量的消耗,每个月的月租大概也就28元那种套餐就够了。
回复

使用道具 举报

514655040  学徒

发表于 2016-12-2 12:02:09

Rockets 发表于 2016-6-30 11:18
计算下流量消耗吧。我记得这个流量的消耗,每个月的月租大概也就28元那种套餐就够了。 ...

您会做这个吗,我现在想实现这个功能,就是把gps定位的位置通过GPRS在计算机的地图上显示位置,514655040我的QQ,麻烦您教我下,谢谢
回复

使用道具 举报

yzm65580952  见习技师

发表于 2017-8-24 16:16:31

楼主我直接复制网页里的程序编译之后出错了,是不是你的代码出错了?
回复

使用道具 举报

球球q1u1iu1  学徒

发表于 2018-10-12 12:06:58

请问您的这个定位测试工具是用QT做的吗,我自己也做了个差不多的,但是我的程序里的webengineview里显示百度地图不能使用定位功能,一点击地图上的定位按钮就会过个几秒钟弹出定位超时的警告,请问您遇到过这个情况吗,应该怎么设置才可以确定当前位置呢?
回复

使用道具 举报

gada888  版主

发表于 2018-10-29 14:47:11

看着有点懵
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail