内容简介:基于3G模块的树莓派基站定位
具体的AT命令请查阅相关手册,绝大多数命令是通用的,部分命令会随着生产厂家有所差异,这里列举有关基站定位的几个AT命令
#测试有无SIM Q: AT+CPIN? A: +CPIN:READY #信号强度 AT+CSQ +CSQ: 16,99 #运营商信息 AT+COPS? +COPS: 0,2,"46001" #基站信息 AT+CREG=2 AT+CREG? +CREG: 2,1,"AAAA","BBBBBB"
串口编程
c
首先对上面的AT命令进行测试,观察返回的信息, win 平台上有串口调试助手可以使用, linux 下也有 minicom ,或者像我一样直接上 C 语言测试串口收发
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int set_opt( int fd, int nSpeed, int nBits, char nEvent, int nStop );
int main( int argc, char **argv )
{
if ( argc != 3 )
{
printf( "Usage: ttytest device cmd\n" );
exit( 0 );
}
int fd;
char * cmgf = argv[2];
strcat( cmgf, "\r" );
char reply[128];
fd = open( argv[1], O_RDWR | O_NOCTTY | O_NDELAY );
if ( fd < 0 )
{
perror( "Can't Open Serial Port" );
return(-1);
}
/* 配置串口 */
set_opt( fd, 115200, 8, 'N', 1 );
write( fd, cmgf, strlen( cmgf ) );
printf( "write %s\n", cmgf );
sleep( 2 );
memset( reply, 0, sizeof(reply) );
read( fd, reply, sizeof(reply) );
printf( "reply :\n" );
printf( "%s\n", reply );
}
int set_opt( int fd, int nSpeed, int nBits, char nEvent, int nStop )
{
struct termios newttys1, oldttys1;
if ( tcgetattr( fd, &oldttys1 ) != 0 ) /* 保存原先串口配置 */
{
perror( "Setupserial 1" );
return(-1);
}
bzero( &newttys1, sizeof(newttys1) ); /* 将一段内存区域的内容全清为零 */
newttys1.c_cflag |= (CLOCAL | CREAD); /* CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 */
newttys1.c_cflag &= ~CSIZE; /* 设置数据位数 */
switch ( nBits ) /*选择数据位 */
{
case 7:
newttys1.c_cflag |= CS7;
break;
case 8:
newttys1.c_cflag |= CS8;
break;
}
switch ( nEvent ) /* 设置校验位 */
{
case '0': /* 奇校验 */
newttys1.c_cflag |= PARENB; /* 开启奇偶校验 */
newttys1.c_iflag |= (INPCK | ISTRIP); /* INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特 */
newttys1.c_cflag |= PARODD; /* 启用奇校验(默认为偶校验) */
break;
case 'E': /* 偶校验 */
newttys1.c_cflag |= PARENB; /* 开启奇偶校验 */
newttys1.c_iflag |= (INPCK | ISTRIP); /* 打开输入奇偶校验并去除字符第八个比特 */
newttys1.c_cflag &= ~PARODD; /* 启用偶校验; */
break;
case 'N': /* 关闭奇偶校验 */
newttys1.c_cflag &= ~PARENB;
break;
}
switch ( nSpeed ) /* 设置波特率 */
{
case 2400:
cfsetispeed( &newttys1, B2400 ); /* 设置输入速度 */
cfsetospeed( &newttys1, B2400 ); /* 设置输出速度 */
break;
case 4800:
cfsetispeed( &newttys1, B4800 );
cfsetospeed( &newttys1, B4800 );
break;
case 9600:
cfsetispeed( &newttys1, B9600 );
cfsetospeed( &newttys1, B9600 );
break;
case 115200:
cfsetispeed( &newttys1, B115200 );
cfsetospeed( &newttys1, B115200 );
break;
default:
cfsetispeed( &newttys1, B9600 );
cfsetospeed( &newttys1, B9600 );
break;
}
if ( nStop == 1 ) /* 设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。 */
{
newttys1.c_cflag &= ~CSTOPB; /* 默认为送一位停止位; */
}else if ( nStop == 2 )
{
newttys1.c_cflag |= CSTOPB; /* CSTOPB表示送两位停止位; */
}
/* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时 */
newttys1.c_cc[VTIME] = 0; /* 非规范模式读取时的超时时间; */
newttys1.c_cc[VMIN] = 0; /* 非规范模式读取时的最小字符数; */
tcflush( fd, TCIFLUSH ); /* tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
/* 在完成配置后,需要激活配置使其生效 */
if ( (tcsetattr( fd, TCSANOW, &newttys1 ) ) != 0 ) /* TCSANOW不等数据传输完毕就立即改变属性 */
{
perror( "com set error" );
return(-1);
}
return(0);
}
编译
gcc ttytest.c -o ttytest
使用方法就是 ttytest device cmd
python
安装 Python 的串口支持模块
sudo pip install pyserial -i https://pypi.douban.com/simple/
一个简单的串口程序框架
import serial
cmd="AT\r"
ser=serial.Serial('/dev/ttyUSB1',115200)
ser.write(cmd)
print ser.readline()
获取 AT 返回信息的代码,为了避免串口长时间等待加了超时处理
#coding=utf-8
import serial
import signal
import time
ser=serial.Serial('/dev/ttyUSB3',115200)
# Define signal handler function
def myHandler(signum, frame):
print("Recieve timeout!")
exit()
def time_out(fun):
def wrapper(*argv):
signal.signal(signal.SIGALRM, myHandler)
signal.alarm(5)
return fun(*argv)
return wrapper
@time_out
def getRes(cmd):
#保存OK之前的所有接收信息
res=''
#保存每一行的信息
line=''
#发出AT信息
ser.write(cmd)
#死循环
while True:
#读取每一个返回的字符
for c in ser.read():
#添加字符到res和line
res+=c
line+=c
#到达行末
if c == '\n':
#打印输出 便于调试
#print("Line: " + line)
#每一行如果匹配到 OK 或ERROR 则结束循环返回res
if not ((line.find("OK")) == -1):
return res
line = ''
# test start
req="AT+CREG?"
res=getRes(req+"\r")
print "req is "+req+"\nres is:"+res
req="AT+CSQ"
res=getRes(req+"\r")
print "req is "+req+"\nres is:"+res
# test end
测试结果
可以看到返回的一行如果以 +CREG 开头则包含运营商基站信息,其中 AAAA 格式的为 lac , BBBBBB 格式的为 CID ,均为十六进制,我们要提取并转化为十进制
str='''
+CREG: 2,1,AAAA,BBBBBB
OK
'''
lac=int((str.replace("\n","").replace("\r","").split(',')[2]),16)
cid=int((str.replace("\n","").replace("\r","").split(',')[3][:-2]),16)
print lac
print cid
获取API
基站信息获取基站位置
基站定位接口介绍以及API文档 传送门
params={
"mmc":"460",
"mnc":"01",
"lac":"",
"ci":"",
"output":"json",
}
返回范例:
{
"errcode": 0,
"lat": "30.495039",
"lon": "114.392479",
"radius": "403",
"address": "湖北省武汉市洪山区关山街道当代曙光嘉园2号楼-1单元;民族大道与南湖北路路口东南166米"
}
编写脚本从串口拿到的 lac 和 cid 获取基站的经纬度以及其他信息
def getStationLocation(longtitude, latitude):
getURL="http://api.cellocation.com/cell/"
params={
"mmc":"460",
"mnc":"01",
"lac":"",
"ci":"",
"output":"json",
}
try:
rep=urllib.urlopen(getURL,urllib.urlencode(params))
repdict=eval(rep.read())
except Exception, e:
print 'str(Exception):\t', str(Exception)
print 'str(e):\t\t', str(e)
return repdict
经纬度获取地名
上面拿到的只是基站的具体地理位置,我们仍然需要从基站的经纬度确定树莓派的大致位置
我们无法通过经纬度直观的知道自己在哪里,不过有提供好的 API 给我们调用,这里使用 腾讯地图 开放API,现阶段对开发者是免费的。
注册过后拿到开发密钥XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
经纬度信息转为详细地理位置的API使用文档 传送门
返回的格式如下
{
"status": 0,
"message": "query ok",
"request_id": "6269494254796579061",
"result": {
"location": {
"lat": 30.494491,
"lng": 114.399033
},
"address": "湖北省武汉市洪山区民族大道163号桃园路",
"formatted_addresses": {
"recommend": "洪山区桃园路关山荷兰风情园",
"rough": "洪山区桃园路关山荷兰风情园"
},
...
}
脚本调用API获取地理位置
def getRPILocation(longtitude, latitude):
getURL="http://apis.map.qq.com/ws/geocoder/v1/"
params={
"location":longtitude+","+latitude,
"output":"json",
"key":"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
}
try:
rep=urllib.urlopen(getURL,urllib.urlencode(params))
repdict=eval(rep.read())
except Exception, e:
print 'str(Exception):\t', str(Exception)
print 'str(e):\t\t', str(e)
return repdict
剩下的工作就是对拿到的 json 数据进行解析提取,比较简单就不做说明
以上所述就是小编给大家介绍的《基于3G模块的树莓派基站定位》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- SeaGlass:手工搭建伪基站监控系统
- 技术讨论 | 基于基站定位APP开发实录
- 建一个 5G 基站,到底要花多少钱?
- Eero分布式组网路由器推2代产品 包括基站和Beacon
- [树莓派]树莓派的入门教程
- 「玩转树莓派」树莓派 3B+ 安装 OpenCv
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
What Technology Wants
Kevin Kelly / Penguin Group (USA) Incorporated / 2010-10-14 / USD 27.95
A refreshing view of technology as a living force in the world. This provocative book introduces a brand-new view of technology. It suggests that technology as a whole is not a jumble of wires and ......一起来看看 《What Technology Wants》 这本书的介绍吧!