Strictus 发表于 2015-9-9 13:13:30

使用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、点击右上角“项目管理”进入页面后找到“新建项目”并单击进入如下页面。
               
          3、在如上页面中输入项目名"ABCD",点击“立即创建项目”进入如下页面
            
          4、点击“为你的项目添加一个设备”进入如下页面
            
         5、在“设备名称”栏输入设备名:“123456”
            
         6、继续下拉页面至地图,使用鼠标单击地图以设置设备位置,设置好后点击“添加设备”完成设备的创建
            
         7、返回“项目管理”(如上图)并点击选择“ABCD”的项目进入如下页面

            
         8、点击“添加APIKey”进入如下页面并按如图注释创建一个名称为“TEST APIKey”的API密钥
               
          至此,我们就已经完成了在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;
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;
unsigned char id_length;
char id;
unsigned char LengthB1;
unsigned char LengthB2;
char api_key;
}login;

struct
{
unsigned char CMD;
unsigned char LengthA;
unsigned char mark;
unsigned char type;
unsigned char LengthB1;
unsigned char LengthB2;
char streamA;
char id;
char streamB;
char GPS_Buffer;
char streamC;
}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 longTime_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={"$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=Serial1.read();
         if(ii==bufferLength)clrRxBuffer();
         }
}
//*********************************************File End*******************************************//

2、下载完成后按照如下方式连接GPS及GSM天线,注意供电方式及NO BAT?的跳线帽切换。

3、程序会自动运行并使模块开机,等待约1分钟后开始将GPS数据上传到OneNet,届时L灯闪烁一次表示数据上传成功一次。

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

当成功定位时,我们可以在软件“实时地图”选项卡中查看到板子所在具体位置。下面是使用效果!







bobo 发表于 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

好实用的教程{:5_132:}

吹口琴的钢铁侠 发表于 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 发表于 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

看着有点懵
页: [1]
查看完整版本: 使用SIM808 with Leonardo mainboard实现远程定位