GPS手机远程接收方案

需要材料

材料 数量
RTrobot GPS模块 1
RTrobot GSM模块 1
电源 1
TCP服务器 1
可编程单片机 1
杜邦线 若干
螺丝螺母 若干

设计

GPS模块是串口收发的,如果需要把接收到的信息处理后传输给手机上查看,那么我们需要先设计出无线传输方案; 无线传输方案中有几种办法:
1.蓝牙传输
2.WIFI传输
3.通过GSM模块把经纬度信息放到网络服务器中
这里我们只介绍第三种方案,前面两种相对简单,需要介绍。

无论哪种方案,我们都需要先在众多的GPS数据中提取经纬度信息,提取方法参RTrobotGPS的资料文档。GSM模块需要先设定好访问网络的功能,设置方法参考RTrobotGSM的资料文档。

现在准备好的模块有2个串口传输,而大多数便宜单片机只有1个串口,这时可以采取下图的方案设计。 farm9.staticflickr.com_8825_17720921354_8f18ae0fae_z.jpg

把GSM模块的RX接到单片机的TX,并把GPS的TX接到单片机的RX,这样就可以利用一个串口分别接两个模块达成效果。

服务器

服务器方案可以自己架设或者使用网络服务器,这里我们以LINUX服务为案例;服务器的工作非常简单,仅仅建立一个TCP服务器并把两个客户端得信息互相转发。这里提供下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);
}

编译后运行一下即在阻塞等待两个客户端的接入。

手机APP接收数据格式

在单片机提取出经纬度的时候必须按照以下格式发送,否则手机APP不做处理。

Latitude:xx.xxxxx,Longitude:xxx.xxxxx\r\n

效果预览

farm8.staticflickr.com_7765_18158318139_cedfa51288_z.jpg

图片是带着小狗跑步,可以看到小狗就在我得身后。

注意

此方法仅供学习参考,不可做危害别人,窥视隐私与触犯法律行为。 RTrobot提供手机测试软件,但此测试涉及TCP服务器架设知识,需要有一定得基础,RTrobot不做技术提供与其他定制方案。