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

news2024/11/27 2:35:43

目录

引入

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
    # 左部layout
    layout_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)
                    ],
                ]
    # 右部layout
    layout_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)
    # 整体layout
    layout = [
                [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':  
                break
            if 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")
                break
            elif event == 'LED':  
                print(f"LED-----------------") 
            # 处理其他事件...
        except Exception as e:
            window.close()
            print(f"An error occurred: {e}")
            return 0
    window.close()
    return 0  

def main():
    # theme参考/client/README
    event_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的天下了哈哈。

效果展示

项目管理操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1668991.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu 24 换国内源及原理 (阿里源 清华源 中科大源 网易源)

备份原文件 sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak 编辑源文件 sudo gedit /etc/apt/sources.list.d/ubuntu.sources 粘贴到文本&#xff08;其中一个即可&#xff09;&#xff1a; &#xff08;阿里源&#xff09…

与 Apollo 共创生态:Apollo 七周年大会带我体会自动驾驶技术的发展

前言 自动驾驶技术作为当今科技领域的热门话题&#xff0c;吸引着无数开发者和企业的目光。而在这个风起云涌的行业中&#xff0c;Apollo开放平台作为自动驾驶领域的领军者之一&#xff0c;扮演着不可或缺的角色。七年前&#xff0c;当Apollo开放平台刚刚起步时&#xff0c;也…

C语言(指针)5

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

等保一体机能过三级等保吗?过等保无需再买安全设备如何做到?

等保一体机能过三级等保吗&#xff1f;过等保无需再买安全设备如何做到&#xff1f; 全云在线 2024-03-28 12:08 广东 尽管等保建设的标准是统一的&#xff0c;但由于不同行业和用户规模的差异&#xff0c;建设方案呈现出多样化的特点。 虽然重点行业过等保现象确实已经十分…

【35分钟掌握金融风控策略25】定额策略实战2

目录 基于收入和负债的定额策略 确定托底额度和盖帽额度 确定基础额度 基于客户风险评级确定风险系数 计算最终授信额度 确定授信有效期 基于收入和负债的定额策略 在实际生产中&#xff0c;客户的收入和负债数据大多无法直接获得&#xff0c;对于个人的收入和负债数据&…

中小型客户过等保,选择比努力重要!

国内谈网络安全&#xff0c;等保是绕不过去的话题。 作为国家网络安全保障的基本制度、基本策略、基本方法&#xff0c;等保经过十几年发展&#xff0c;其基本概念、相关标准已经深入人心&#xff0c;市面上各类成熟的等保方案让用户应接不暇&#xff0c;挑花了眼。 网络安全…

数据结构之排序(上)

片头 嗨&#xff0c;小伙伴们&#xff0c;大家好&#xff01;我们今天来学习数据结构之排序&#xff08;上&#xff09;&#xff0c;今天我们先讲一讲3个排序&#xff0c;分别是直接插入排序、冒泡排序以及希尔排序。 1. 排序的概念及其应用 1.1 排序的概念 排序&#xff1a…

R语言数据分析案例-股票可视化分析

一、数据整合的对象 # Loading necessary libraries library(readxl) library(dplyr)# Reading the data from Excel files data_1 <- read_excel("云南白药.xlsx") data_2 <- read_excel("冰山.xlsx")二、数据整合的代码 # Reading the data from…

Docker:docker在项目中常用的一些命令

简介   Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;并发布到任何安装了 Docker 引擎的机器上。这些容器是轻量级的&#xff0c;包含了应用程序运行所需的所有东西&#xff0c;如代码、系统库、系统工具…

“数字化叙事的革命:人工智能驱动的创意工具的崛起”

近年来&#xff0c;人工智能 (AI) 改变了我们生活的许多方面&#xff0c;数字故事讲述的世界也不例外。随着人工智能驱动的创意工具的出现&#xff0c;广告商、内容创作者和专业人士现在配备了创新的解决方案来简化他们的工作流程&#xff0c;增强他们的创意输出&#xff0c;并…

08.4.grafana自定义图形并直接数据库取值

grafana自定义图形并直接数据库取值 自定义添加油表图形 选择gauge图形&#xff0c;并且配置对应设定值&#xff0c;点击应用 如图所示&#xff0c;可以看到仪表盘上的值是zabbix上取得值 配置grafana直接数据库取值 添加mysql数据源 添加后进行配置&#xff0c;我这…

二分判定+选插冒排序+归并快速堆希尔+计数排序

二分力扣题 一&#xff1a;搜索二维矩阵 74. 搜索二维矩阵 按照题意&#xff1a;直接利用二维数组转换成一维数组进行求解 方法一&#xff1a;普通等于的二分查找 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {t…

websevere服务器从零搭建到上线(三)|IO多路复用小总结和服务器的基础框架

文章目录 epollselect和poll的优缺点epoll的原理以及优势epoll 好的网络服务器设计Reactor模型图解Reactor muduo库的Multiple Reactors模型 epoll select和poll的优缺点 1、单个进程能够监视的文件描述符的数量存在最大限制&#xff0c;通常是1024&#xff0c;当然可以更改数…

STM32快速入门(定时器之输入捕获)

STM32快速入门&#xff08;定时器之输入捕获&#xff09; 前言 本节主要讲解STM32利用通用定时器&#xff0c;在输入引脚出现指定电平跳变时&#xff0c;将CNT的值锁存到CCR寄存器当中&#xff0c;从而计算PWM波形的频率、占空比、脉冲间隔、电平持续时间等。其功能的应用有&…

免费思维13招之七:空间型思维

免费思维13招之七:空间型思维 本篇给你带来的是空间型思维。 空间型思维,具体分为内部空间型思维和外部空间型思维。 什么叫内部空间型思维呢? 内部空间型就是充分利用现有空间或资源为社会提供免费服务,积累人气,增加流量,从而带动消费。 为什么你生意不好?为什么你…

ubuntu中的docker记录(5)——如何使用阿里云的镜像加速配置docker镜像加速器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、镜像加速器介绍1. 什么是docker镜像加速器&#xff1f;2. 为什么要配置镜像加速器&#xff1f; 二、配置镜像加速器1. 注册阿里云账号2. 注册镜像容器服务3…

C++ int 学习

在C语言中 & 是取地址符号&#xff1b; 在C中有 int& 这样的&#xff0c;这里的&不是取地址符号&#xff0c;而是引用符号&#xff1b; 引用是C对C的一个补充&#xff1b; 变量的引用就是变量的别名&#xff0c;讲的通俗一点就是另外一个名字&#xff1b; a的值…

代码随想录算法训练营第二十七天| LeetCode39. 组合总和、LeetCode40.组合总和II、LeetCode131.分割回文串

#LeetCode 39. Combination Sum #LeetCode 39. 视频讲解&#xff1a;带你学透回溯算法-组合总和&#xff08;对应「leetcode」力扣题目&#xff1a;39.组合总和&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 当建立树的结构的时候&#xff0c;target 可以限制树的深…

Spring Boot 调用外部接口的几种方式

Spring Boot 调用外部接口的几种方式 在微服务架构中&#xff0c;服务间的调用是不可或缺的环节。Spring Boot 为开发者提供了多种方式来实现这一任务&#xff0c;这个文章将为你详细介绍这些方式。 一、使用RestTemplate RestTemplate是 Spring Boot 早期版本中常用的 REST 客…

基于 Spring Boot 博客系统开发(八)

基于 Spring Boot 博客系统开发&#xff08;八&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;七&#xff09;&#x1f…