差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
creative:gps:gps-phone [2015/06/01 08:04]
yayi [设计]
creative:gps:gps-phone [2015/06/01 08:05] (当前版本)
yayi [手机APP接收数据格式]
行 1: 行 1:
 +====== GPS手机远程接收方案 ======
  
 +===== 需要材料 =====
 +^ 材料 ​       ^ 数量^ ​            
 +| RTrobot GPS模块 ​       | 1|         
 +| RTrobot GSM模块 ​        | 1|
 +| 电源 ​       | 1|
 +| TCP服务器 ​      | 1|   
 +| 可编程单片机 ​     | 1|       
 +| 杜邦线 ​       | 若干|
 +| 螺丝螺母 ​      | 若干| ​      
 +
 +===== 设计 =====
 +GPS模块是串口收发的,如果需要把接收到的信息处理后传输给手机上查看,那么我们需要先设计出无线传输方案;
 +无线传输方案中有几种办法:\\
 +1.蓝牙传输\\
 +2.WIFI传输\\
 +3.通过GSM模块把经纬度信息放到网络服务器中\\
 +这里我们只介绍第三种方案,前面两种相对简单,​需要介绍。
 +
 +无论哪种方案,我们都需要先在众多的GPS数据中提取经纬度信息,提取方法参RTrobotGPS的资料文档。GSM模块需要先设定好访问网络的功能,设置方法参考RTrobotGSM的资料文档。
 +
 +现在准备好的模块有2个串口传输,而大多数便宜单片机只有1个串口,这时可以采取下图的方案设计。
 +{{https://​farm9.staticflickr.com/​8825/​17720921354_8f18ae0fae_z.jpg}}
 +
 +把GSM模块的RX接到单片机的TX,并把GPS的TX接到单片机的RX,这样就可以利用一个串口分别接两个模块达成效果。
 +
 +
 +===== 服务器 =====
 +服务器方案可以自己架设或者使用网络服务器,这里我们以LINUX服务为案例;服务器的工作非常简单,仅仅建立一个TCP服务器并把两个客户端得信息互相转发。这里提供下C的参考程序给大家修改。
 +<code c>
 +/*
 + * main.cpp
 + * TCP客户端信息转发
 + * Author: Yayi
 + */
 +#include <​stdlib.h>​
 +#include <​stdio.h>​
 +#include <​errno.h>​
 +#include <​string.h>​
 +#include <​netdb.h>​
 +#include <​sys/​types.h>​
 +#include <​netinet/​in.h>​
 +#include <​sys/​socket.h>​
 +#include <​unistd.h>​
 +#include <​arpa/​inet.h>​
 +#include <​time.h>​
 +#include <​sys/​wait.h>​
 +
 +#define WAITBUF 10
 +int main(int argc, char *argv[])
 +{
 + int sockfd,​clientnub,​client2nub;​
 + struct sockaddr_in server_addr;​
 + struct sockaddr_in client_addr,​client2_addr;​
 + socklen_t sin_size;
 + char serverlog0[1024] = {0};
 + char serverlog1[1024] = {0};
 + char serverlog2[1024] = {0};
 + time_t timep;
 + struct tm *p;
 +
 + /​*服务器端开始建立socket描述符*/​
 + if((sockfd=socket(AF_INET,​SOCK_STREAM,​0))==-1)
 + {
 +        fprintf(stderr,"​Socket error:​%s\n",​strerror(errno));​
 +        exit(1);
 + }
 +
 + /​*服务器端填充 sockaddr结构*/​
 + bzero(&​server_addr,​sizeof(struct sockaddr_in));​
 + server_addr.sin_family=AF_INET;​
 +
 + /​*自动填充主机IP*/​
 + ​ server_addr.sin_addr.s_addr=htonl(INADDR_ANY);​
 + ​ server_addr.sin_port=htons(8888);​
 +
 + ​ /​*捆绑sockfd描述符*/​
 + ​ if(bind(sockfd,​(struct sockaddr *)(&​server_addr),​sizeof(struct sockaddr))==-1)
 +  {
 +        fprintf(stderr,"​Bind error:​%s\n",​strerror(errno));​
 +        exit(1);
 + }
 +
 + /​*监听sockfd描述符*/​
 + if(listen(sockfd,​ WAITBUF)==-1)
 + {
 +        fprintf(stderr,"​Listen error:​%s\n",​strerror(errno));​
 +        exit(1);
 + }
 +
 + /​*等待客户端链接*/​
 +        sin_size=sizeof(struct sockaddr_in);​
 +        clientnub=accept(sockfd,​(struct sockaddr *)(&​client_addr),&​sin_size);​
 +
 +        /​*日志格式化*/​
 +    time(&​timep);​
 +    p = gmtime(&​timep);​
 +
 + sprintf(serverlog0,"​[%d.%d.%d",​ (1900+p->​tm_year),​ (1+p->​tm_mon),​ p->​tm_mday);​
 + sprintf(serverlog1,"​ %d:%d:%d] ", p->​tm_hour,​ p->​tm_min,​ p->​tm_sec);​
 + sprintf(serverlog2,"​Server get connection from %s\n",​inet_ntoa(client_addr.sin_addr));​
 +
 + FILE* file = fopen("​tcpserver.log","​a+"​);​
 + fwrite(serverlog0,​1,​strlen(serverlog0),​file);​
 + fwrite(serverlog1,​1,​strlen(serverlog1),​file);​
 + fwrite(serverlog2,​1,​strlen(serverlog2),​file);​
 + fclose(file);​
 +
 + /​*发送链接"​OK\n"​信号*/​
 + send(clientnub,"​OK\n",​strlen("​OK\n"​),​0);​
 +
 + /​*等待客户端2链接*/​
 + sin_size=sizeof(struct sockaddr_in);​
 + client2nub=accept(sockfd,​(struct sockaddr *)(&​client2_addr),&​sin_size);​
 +        /​*日志格式化*/​
 +    time(&​timep);​
 +    p = gmtime(&​timep);​
 +
 +
 + sprintf(serverlog0,"​[%d.%d.%d",​ (1900+p->​tm_year),​ (1+p->​tm_mon),​ p->​tm_mday);​
 + sprintf(serverlog1,"​ %d:%d:%d] ", p->​tm_hour,​ p->​tm_min,​ p->​tm_sec);​
 + sprintf(serverlog2,"​Server get connection from %s\n",​inet_ntoa(client2_addr.sin_addr));​
 +
 + file = fopen("​tcpserver.log","​a+"​);​
 + fwrite(serverlog0,​1,​strlen(serverlog0),​file);​
 + fwrite(serverlog1,​1,​strlen(serverlog1),​file);​
 + fwrite(serverlog2,​1,​strlen(serverlog2),​file);​
 + fclose(file);​
 +
 + /​*发送链接"​OK\n"​信号*/​
 + send(client2nub,"​OK\n",​strlen("​OK\n"​),​0);​
 +
 + while(1)
 +  {
 + char recv_send_data[1024]={0};​
 + /​*把客户端2接收转发客户端*/​
 + if((recv(client2nub,​recv_send_data,​1024,​0))>​0)
 + send(clientnub,​recv_send_data,​strlen(recv_send_data),​0);​
 + /​*把客户端接收转发客户端2*/​
 + if((recv(clientnub,​recv_send_data,​1024,​0))>​0)
 + send(client2nub,​recv_send_data,​strlen(recv_send_data),​0);​
 +  }
 + ​ close(sockfd);​
 + ​ exit(0);​
 +}
 +</​code>​
 +编译后运行一下即在阻塞等待两个客户端的接入。
 +
 +
 +===== 手机APP接收数据格式 =====
 +在单片机提取出经纬度的时候必须按照以下格式发送,否则手机APP不做处理。
 +<​code>​Latitude:​xx.xxxxx,​Longitude:​xxx.xxxxx\r\n</​code>​
 +
 +===== 效果预览 =====
 +{{https://​farm8.staticflickr.com/​7765/​18158318139_cedfa51288_z.jpg}}
 +
 +图片是带着小狗跑步,可以看到小狗就在我得身后。
 +
 +===== 注意 =====
 +<note warning>​此方法仅供学习参考,不可做危害别人,窥视隐私与触犯法律行为。
 +RTrobot提供手机测试软件,但此测试涉及TCP服务器架设知识,需要有一定得基础,RTrobot不做技术提供与其他定制方案。
 +</​note>​