039——解决室内不能使用GPS问题

2024-05-13 04:04

本文主要是介绍039——解决室内不能使用GPS问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

引入

GUI整改

client添加GPS分析

完善服务器网络通讯部分代码

添加GPS的BSW层

GPS操作部分代码(相当于驱动)

效果展示

项目管理操作


引入

        最近在写论文加上出去玩了一圈所以停更了一段时间。上次咱们GPS有个室内用不了的问题,咱们看看咋解决一下。

GUI整改

'''
fuction : 客户端界面
author  : 辛天宇
date    : 2024-4-12
-------------------------------
author  date     modify
辛天宇 2024-4-12 引入大小控制全局设置功能'''
import PySimpleGUI as sg
import tool
import global_var# 调用显示框架
def show_window(theme):# 是否使用自定义标题栏use_custom_titlebar = False# 设置主题sg.theme(theme)# 创建菜单Menu = sg.Menu# 左部layoutlayout_l =  [[tool.name('NetWork'), sg.Button('Connect', key='Connect', font=global_var.GLOBAL_FONT)],[tool.name('NetWork'), sg.Button('Disconnect', key='Disconnect', font=global_var.GLOBAL_FONT)],[tool.name('NetWork'), sg.Output(size=(32, 1), key='IP', font=global_var.GLOBAL_FONT)],[sg.Checkbox('Input', use_custom_titlebar, enable_events=True, key='input', font=global_var.GLOBAL_FONT)],[sg.InputText(disabled=True, key='txbuff', font=global_var.GLOBAL_FONT), sg.Button('SEND', key='send', font=global_var.GLOBAL_FONT)],[sg.Slider(range=(0, 100), orientation='h', size=(57, 40), default_value=0, key='DAC', enable_events=True, font=global_var.GLOBAL_FONT), sg.Text('DAC', size=(5,2), justification='c',pad=(0,(20,0)), font=global_var.GLOBAL_FONT)],[sg.InputText(key='AT24C02_I', default_text='', font=global_var.GLOBAL_FONT), sg.Button('AT24C02 WRITE', key='AT24C02_W', font=global_var.GLOBAL_FONT)],]# 右部layoutlayout_r  = [[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='LED_O', font=global_var.GLOBAL_FONT), sg.Button('LED', key='LED', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='SR501_O', font=global_var.GLOBAL_FONT), sg.Button('SR501', key='SR501', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='SR04_O', font=global_var.GLOBAL_FONT), sg.Button('SR04', key='SR04', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='IRDA_O', font=global_var.GLOBAL_FONT), sg.Button('IRDA', key='IRDA', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='DHT11_O', font=global_var.GLOBAL_FONT), sg.Button('DHT11', key='dht11', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='DS18B20_O', font=global_var.GLOBAL_FONT), sg.Button('DS18B20', key='ds18b20', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='GPS_O', font=global_var.GLOBAL_FONT), sg.Button('DIRECT', key='GPS_direct', font=global_var.GLOBAL_FONT), sg.Button('MEMORY', key='GPS_memory', font=global_var.GLOBAL_FONT)],[sg.Output(size=(global_var.OUTPUT_X, global_var.OUTPUT_Y), key='AT24C02_O', font=global_var.GLOBAL_FONT), sg.Button('AT24C02 READ', key='AT24C02_R', font=global_var.GLOBAL_FONT)],#[tool.name('Text'), sg.Button('IIC', key='IIC')],]# 修饰topic = tool.add_stars_to_string(global_var.TOPIC, 10)# 整体layoutlayout = [[sg.T(topic, text_color='blue', justification='c', font=global_var.topic_font)],[sg.Col(layout_l), sg.Col(layout_r)],[sg.Text('Output:', size=(7,1), justification='r',pad=(0,0), font=global_var.GLOBAL_FONT),],[sg.Output(size=(120, 16), key='Output', font=global_var.GLOBAL_FONT)],[sg.Button('Clean', key='Clean'), sg.Button('Quit', key='Quit')]]window = sg.Window('The PySimpleGUI Element List', layout, finalize=True, keep_on_top=True)return window# 处理事件
def event_handle():window = show_window('DefaultNoMoreNagging')# 事件循环  while True:  try:event, values = window.read()if event == 'Exit':  breakif event == 'dht11':message = f"{global_var.TEM}°C   {global_var.HUM}%"window['Getvalue'].update(message)if event == 'ds18b20':message = f"{global_var.TEM}°C"window['Getvalue'].update(message)if event == 'input': print(f"INPUT-----------------") elif event == 'Quit':  print(f"See you.............")break# elif event == 'Connect':#     global_var.SERVER_IP = "192.168.5.10"#     window['IP'].update(global_var.SERVER_IP)# elif event == 'Disconnect':  #     global_var.SERVER_IP = "connectionless network service"#     window['IP'].update(global_var.SERVER_IP)elif event is None:print(f"xxxxxxxxxxxxxxxxxxxx")breakelif event == 'LED':  print(f"LED-----------------") # 处理其他事件...except Exception as e:window.close()print(f"An error occurred: {e}")return 0window.close()return 0  def main():# theme参考/client/READMEevent_handle()if __name__ == '__main__':main()

        之前给老师看了下ui,老师说字太小了所以这次我优化了一下可以通过全局变量控制。

这次够大了吧

这里可以控制大小设定了

client添加GPS分析

        接收到的数据只有成功和失败两种,但是发送的话我设置了两种模式direct和memory。

         direct:    这种模式是直接启动GPS读取实际的数据,但是我们室内肯定用不了GPS哇。于是就加个读取存储器的默认值。

         memory:这个模式就是直接读取存储器的默认值

GPS的命令不多所以两种模式共用一个设备号

完善服务器网络通讯部分代码

        这块就比较简单了,基本和以前的没啥区别。后面这里要整合一下抽象出一个函数来。可以缩小代码体积。

添加GPS的BSW层

/*
* func        : Handle dac Settings
* return      : error code
* input       : <cmd> (GPS cmd)
* output      :<data> (longitude and latitude)
* author      date     modify
--------------------------------xintianyu  2024-5-11  create
*/
int gps_handle(GPS_CMD cmd, char *data)
{char *device = "/dev/ttymxc5";int fd;int iRet;char *memory = usth;char buf[1000];char time[100];char Lat[100]; char ns[100]; char Lng[100]; char ew[100];float fLat, fLng;/* 1. open *//* 2. setup * 115200,8N1* RAW mode* return data immediately*//* 3. write and read */if (cmd_direct == cmd){fd = open_port(device);if (fd < 0){printf("open %s err!\n", device);return -1;}iRet = set_uart(fd, 9600, 8, 'N', 1);if (iRet){printf("set port err!\n");return iRet;}/* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"<CR><LF>*//* read line */iRet = read_gps_raw_data(fd, buf);/* parse line */if (iRet == 0){iRet = parse_gps_raw_data(buf, time, Lat, ns, Lng, ew);}/* printf */if (iRet == 0){printf("Time : %s\n", time);printf("ns   : %s\n", ns);printf("ew   : %s\n", ew);printf("Lat  : %s\n", Lat);printf("Lng  : %s\n", Lng);/* 纬度格式: ddmm.mmmm */sscanf(Lat+2, "%f", &fLat);fLat = fLat / 60;fLat += (Lat[0] - '0')*10 + (Lat[1] - '0');/* 经度格式: dddmm.mmmm */sscanf(Lng+3, "%f", &fLng);fLng = fLng / 60;fLng += (Lng[0] - '0')*100 + (Lng[1] - '0')*10 + (Lng[2] - '0');printf("Lng,Lat: %.06f,%.06f\n", fLng, fLat);sprintf(data,"@009s%s%s", Lng, Lat);}else{sprintf(data,"@009e");}}else if(cmd_memory == cmd){sprintf(data,"@009s%s", memory);}else{sprintf(data,"@009e");}return 0;
}

大部分内容沿用了韦东山老师的代码,在外层封装了个任务判断而已。

GPS操作部分代码(相当于驱动)

/*
* func        : set uart
* return      : err code
* input       : <fd> (uart device) <Speed> (speed) <Bits> (bits) <Event> (event) <Stop> (stop bit)
* output      :NULL
* author      date     modify
--------------------------------weidongshan  2024-5-11  create
*/
int set_uart(int fd, int Speed, int Bits, char Event, int Stop)
{struct termios newtio,oldtio;if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1");return -1;}bzero( &newtio, sizeof( newtio ) );newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/newtio.c_oflag  &= ~OPOST;   /*Output*/switch( Bits ){case 7:newtio.c_cflag |= CS7;break;case 8:newtio.c_cflag |= CS8;break;}switch( Event ){case 'O':newtio.c_cflag |= PARENB;newtio.c_cflag |= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);break;case 'E': newtio.c_iflag |= (INPCK | ISTRIP);newtio.c_cflag |= PARENB;newtio.c_cflag &= ~PARODD;break;case 'N': newtio.c_cflag &= ~PARENB;break;}switch( Speed ){case 2400:cfsetispeed(&newtio, B2400);cfsetospeed(&newtio, B2400);break;case 4800:cfsetispeed(&newtio, B4800);cfsetospeed(&newtio, B4800);break;case 9600:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;case 115200:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;default:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;}if( Stop == 1 )newtio.c_cflag &= ~CSTOPB;else if ( Stop == 2 )newtio.c_cflag |= CSTOPB;newtio.c_cc[VMIN]  = 1;  /* 读数据时的最小字节数: 没读到这些数据我就不返回! */newtio.c_cc[VTIME] = 0; /* 等待第1个数据的时间: * 比如VMIN设为10表示至少读到10个数据才返回,* 但是没有数据总不能一直等吧? 可以设置VTIME(单位是10秒)* 假设VTIME=1,表示: *    10秒内一个数据都没有的话就返回*    如果10秒内至少读到了1个字节,那就继续等待,完全读到VMIN个数据再返回*/tcflush(fd,TCIFLUSH);if((tcsetattr(fd,TCSANOW,&newtio))!=0){perror("com set error");return -1;}//printf("set done!\n");return 0;
}/*
* func        : set uart
* return      : err code
* input       : <com> (uart id)
* output      :NULL
* author      date     modify
--------------------------------weidongshan  2024-5-11  create
*/
int open_port(char *com)
{int fd;//fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);fd = open(com, O_RDWR|O_NOCTTY);if (-1 == fd){return(-1);}if(fcntl(fd, F_SETFL, 0)<0) /* 设置串口为阻塞状态*/{printf("fcntl failed!\n");return -1;}return fd;
}/*
* func        : read gps values
* return      : err code
* input       : <fd> (device id) <buf> (values)
* output      :NULL
* author      date     modify
--------------------------------weidongshan  2024-5-11  create
*/
int read_gps_raw_data(int fd, char *buf)
{int i = 0;int iRet;char c;int start = 0;while (1){iRet = read(fd, &c, 1);if (iRet == 1){if (c == '$')start = 1;if (start){buf[i++] = c;}if (c == '\n' || c == '\r')return 0;}else{return -1;}}
}/*
* func        : gps values handle
* return      : err code
* input       : <buf> (values) <time> (time) <ns> (Northern and southern hemispheres) <ew> (Eastern and western hemispheres)
*             : <lat> (latitude) <lng> (longitude)
* output      :NULL
* author      date     modify
--------------------------------weidongshan  2024-5-11  create
*/
/* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"<CR><LF> */
int parse_gps_raw_data(char *buf, char *time, char *lat, char *ns, char *lng, char *ew)
{char tmp[10];if (buf[0] != '$')return -1;else if (strncmp(buf+3, "GGA", 3) != 0)return -1;else if (strstr(buf, ",,,,,")){printf("Place the GPS to open area\n");return -1;}else {//printf("raw data: %s\n", buf);sscanf(buf, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]", tmp, time, lat, ns, lng, ew);return 0;}
}

        我直接拿韦东山老师的代码过来用了,这些代码都比较简单,就是打开串口设置串口读取数据和数据处理。严格来说韦东山老师也是仿照linux源码的驱动程序写的。在国外引用思想也要表明。但是国内版权意识比较差这里也没要求。如果严格实施的话估计全世界都成为GPL的天下了哈哈。

效果展示

项目管理操作

这篇关于039——解决室内不能使用GPS问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/984627

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三