zl程序教程

您现在的位置是:首页 >  其他

当前栏目

基于GPS的公交车站点播报调试第五天

调试 基于 GPS 点播 第五天
2023-09-11 14:20:47 时间

基于GPS的公交车站点播报

任务书

本设计的主控芯片单片机为基础,利用GPS获取比较精确的公交位置信息;并由AT89C51进行智能整合处理信息,发送控制指令;利用ISD1700系统语音芯片实现语音播报,并通过LCD液晶模块加以显示信息。具体的功能有以下三点:

  1. GPS定位站点:在GPS自动播报模式下,系统自动实时检测当前所处GPS坐标,并与设置的站点坐标比对,当当前坐标与某个站点的坐标误差在指定范围,则认为到了指定的站点

  2. 手动切换模式:人工通过上一站、下一站按键到了指定站点,则播放对应站点的语音提示。
    GPS自动播报/人工播报模式切换:人工播报模式时,根据往返设置以及按上一站、下一站按键来确定需要播放语音的站点;GPS自动播报则是通过GPS坐标来检测到了哪个站点,此时往返键不起作用。

  3. 显示屏显示对应的站点名称及相关信息

  4. 详细的站点信息包括以下几个:

    寝室站

    食堂站

    足球场站

    琴湖站

    综合楼站

    信息楼站

    南门站

方案设计

通过阅读这个任务书,已经知晓了,需要构建一个包括GPS模块,51核心板模块,OLED显示模块,语音播报模块和按键模块。

在这里插入图片描述

因为时间过于仓促,所以打算使用模块化的设计思路,优先逐个调通各个模块,然后再进行程序的联合调试,最后是硬件部分的调试。

硬件搭建

现在针对不同的模块,进行数据类型分类汇总,从而符合任务书的要求:

  • OLED屏幕

    显示屏用来显示站点信息,系统的位置信息(经纬度),模式信息(手动orGPS),语音提示的文字,所以可以忽略掉时钟信息。

在这里插入图片描述

显示的像素点的范围是128*64

在这里插入图片描述

  • GPS模块

    用来获取当前的位置信息、时钟信息

在这里插入图片描述

  • 矩阵键盘

    用来完成模式切换,手动模式的上下站切换,可以拓展为站点位置的坐标输入。

在这里插入图片描述

目前总共有16个按键,根据任务书的要求,对不同的键值的功能分配如下:

  • 键值0

    主要是实现站点信息的上行播报功能,已经完成了调试,符合任务书要求。

在这里插入图片描述

从图中可以分析得出,所谓上行,就是从第一站到第七站,进行循环执行。

  • 键值1

    主要是实现站点信息的下行播报功能,完成了调试工作,符合任务书要求。

    在这里插入图片描述

    从上图中可以发现,所谓下行,就是站点信息从第七站到第一站进行循环执行。

  • 键值2

在这里插入图片描述

站点语音信息进行重复播报,如图所示,当前站点是G站,并且通过按键,对G站进行了4次播报,并且在完成了重复播报后,程序依旧正常进行下一个站点的信息播报。

  • 键值3

    主要是实现对站点信息的复位,暂定从初始位置开始播报语音

在这里插入图片描述

如图所示,当按下初始化站点信息的时候,无论当前执行到何种站点,程序会把站点信息复位到A站。从上图我们也可发现,共进行了两次复位操作。

  • 键值4

    用于进行站点播报的模式切换,即手动模式和GPS自动播报模式

在这里插入图片描述

  • 键值5

    进行手动模式下的上一站切换

在这里插入图片描述

  • 键值6

    进行手动模式下的下一站切换
    在这里插入图片描述

  • 键值7

  • 键值8

  • 键值9

  • 键值10

  • 键值11

  • 键值12

  • 键值13

  • 键值14

  • 键值15

  • 语音播报模块

    这个模块需要提前进行音频文件的存储,并且需要配备一个SD卡,用来存储音频,另外可以借助5个IO来实现对31段音频文件的选择性播放。结合上一次的项目,可以发现,这里将使用P0端口进行语音播报的控制端口。

    note:对于站点信息的语音播报,可以利用网上的文字转语音软件进行转换。需要注意转换后的文件格式为MP3格式

在这里插入图片描述

用来完成上下站站点语音提示和开车下车的一些语音提示,主要的语音提示如下:

语音信息的数据类型:

  • 起步阶段

    • 车辆起步请扶好站好注意安全
    • 请主动给老弱病残等乘客让座
  • 到站阶段

    • 站点信息+到了

    • 请依次从后门下车请注意安全

      note:站点信息包括7个站点,分别是如下几个站:
      第一站:寝室站

      第二站:食堂站

      第三站:足球场站

      第四站:琴湖站

      第五站:综合楼站

      第六站:信息楼站

      第七站:南门站

器件选型
  • 51单片机核心板

在这里插入图片描述

  • OLED屏幕 IIC接口 两根线 SCL SDA

在这里插入图片描述

  • GPS模块 UART通信 两根线 TX RX ATGM336H

在这里插入图片描述

  • 矩阵按键 需要8个IO口

在这里插入图片描述

  • 语音播报模块 需要5个IO口 MP3语音播放提示模块

在这里插入图片描述

软件搭建

软件的调试步骤和硬件搭建过程类似,也是分模块调试,先完成各个模块的独立调试,验证其功能性,然后再接着进行所有模块的程序联合调试,最后是转移到核心板上进行硬件平台的测试。

任务达成汇总:

  1. 今天先完成用手动模式的加减换站功能,也就是完成手动模式的站点播报。

    • 如果单片机采用的是12Mhz,则系统在进行串口通信时,对于波特率的调整是非常的不自由,只能选择2400的波特率。而9600有些时候也是可以的。
  2. 完成了对于GPS例程的研究,知道了如何对经度和纬度数据进行解析和获取方式。也学到了一些c语言的基础知识,比如:

    •  extern char *strstr(char *str1, const char *str2);
      // 若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
      // extern这个关键字,是在一个x.c文件中定义,然后在x.h文件中进行声明;假设在
      //另一个y.c文件中需要使用,则可以将该x.h头文件包含在y.c文件中即可使用
      
    • 还知道了一些如何在单片机的串口调试中,进行换行操作:

      sendstring("\r\n");// 在需要换行操作的字符串后边,跟上这样一个字符串,即可
      //完成换行
      
矩阵按键

对于矩阵按键的功能设定如下:

在这里插入图片描述

系统在上电后,默认是GPS模式,如果需要,可以通过按键4切换到手动模式。

fig_mode=~fig_mode //利用这个取反符号,可以实现用一个按键,实现两种不同模式的功能切换

从上面的设定中,也是可以看出来的,如果目前是手动触发模式,则需要对于车辆的起步信号,也要作为手动才可。截止目前为止,已经将程序的大体框架构建了起来,只需要等到GPS模块出现即可!

在对于触发模式的开发过程中,些微遇到点麻烦,一开始是无法进入到按键4的状态,开始怀疑是三个问题,其一是自己编写软件的问题,其二是开发板的矩阵按键有故障,其三是芯片问题。其实一开始是不知道是芯片的问题,直到将矩阵按键的例程下载到开发板上后,通过呢使用,才发觉是芯片的问题,后更换芯片后,同样的例程,功能正常,所以开发板的硬件是正常的。随后将自己编写的模式触发程序下载到板子上进行测试,功能正常。故总结一句,软硬都得啃的动,才是合格的电子工程师。

另外一个问题是设定系统使用手动触发后,亦需要借助手动按键区分车辆起步和到站这两个状态。在一开始区分这个状态时,也是遇到了一点困难,好在最后得到了解决,具体是怎么解决的呢?请看下面的代码:

		 else  //手动触发模式
		 {
		   led1=1;
//		   led=1;
		   if(KeyValue==5 )
		    {
			  led=1;
		      stationx=station+1; 
			  station++;
	
		      if(station==7)
			  {
		        station=0;	
			  }
			  if(stationx==7)
			  {
			    stationx=0;
			  }	
			  KeyValue=0XFF;		  
			}
		   if(KeyValue==6 )
		    {
			  led=1;

			  stationx=station-1;
			  station--;
	
		      if(station==0XFF )
			   {
			    station=6;
			   }
			  if(stationx==0xff)
			   {				
				stationx=6;
			   }
			   KeyValue=0XFF;
			}
		   sendchar(staname[station]);
		   sendstring(longstring2);
		   sendstring(longstring3);
		   sendstring("\r\n");
		   stationow= station;
		   while(KeyValue==0XFF)
		       KeyDown();

上述的代码不做解释,懂的自然懂。

GPS模块

GPS模块使用的是ATGM336H模块,通过串口接受到的字符串数据如下所示:

系统接收到的GPS数据主要由帧头、帧尾和帧内数据组成。根据数据帧的不同,帧头也不相同,主要有$GPGGA、$GPGSA、$GPGSV以及$GPRMC等。这里选用推荐的$GPRMC。各类数据帧分别包含了不同的信息,在此列举出$GPRMC的各项含义:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,*hh
<1>当前位置的格林威治时间,格式为hhmmss。
<2>状态,A为有效位置,V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。
<3>纬度,格式为ddmm.mmmm。
<4>标明南北半球,N为北半球、S为南半球。
<5>径度,格式为dddmm.mmmm。
<6>标明东西半球,E为东半球、W为西半球。
<7>地面上的速度,范围为000.0节~999.9节(1节=1.852km/h)。
<8>方位角,范围为000.0度~359.9度。
<9>日期,格式为ddmmyy。
<10>地磁变化,从000.0度~180.0度。
<11>地磁变化方向,为E或W。
由于帧内各数据段由逗号分割,因此在处理缓存数据时一般通过搜寻ASCII码“$”来判断是否是帧头。在对帧头的类别进行识别后,再通过对所经历逗号个数的计数判断出当前正在处理的是哪一种定位导航参数,并做出相应处理。

从指标上看定位精度是小于2米,且数值变化上,满足:

在这里插入图片描述

[参考文档一]((1条消息) 北斗+GPS模块的调试经_疯仔嵌入式的博客-CSDN博客):

3906.1703,N,11720.8518,E,北纬39度06分10.218秒,东经117度20分51.108秒
3906.1704,N,11720.8518,E,北纬39度06分10.224秒,东经117度20分51.108秒

经度不变,维度增加0.0001,即0.006秒,换算成距离约为0.2米

纬度不变,经度增加0.0001,即0.006秒,换算成距离约为0.1米
感谢博主又带我回顾了一下初中数学和地理。妙啊!!

从上面的数据中,还可以从中知道,需要将字符串转换为数值型才可以。可以通过如下的代码来完成:

/*-----字符串转化为数字-----*/
/*-----只有当是数值型的字符串时,才可以完成字符串的转换。目前仅仅是完成了整数部分的转换,*/
 double Uintnum(char* digit)
{
    unsigned int num = 0;
    double  num1 = 0;
    while (*digit != '\0')
    {
        if (*digit >= '0' && *digit <= '9')
        {
            num = num * 10 + (*digit - '0');
            digit++;
        }
        else
        {
            if (*digit == '.')
            {
                digit++;
                break;
            }
            else
                num = 0;
            break;
        }
    }
    while(*digit != '\0')
        digit++;
    digit = digit - 1;
    while (*digit != '.')
    {
        if (*digit >= '0' && *digit <= '9')
        {
            num1 = num1*0.1 + (*digit - '0');
            digit--;
        }
        else
        {
            num1 = 0;
            break;
        }
    }
    return(num + num1*0.1);
}

单片机编程,少量的浮点计算,应该转换成整数运算来处理。但是考虑到需要存储的数据量是惊人的,所以需要做一些妥协。即只将关键的信息提取出来用来做数据运算。

语音模块

语音模块是采用的是MP3音频播放模块,所以需要提前录入这个音频文件,我打算使用文字转音频文件,来获得音频数据。

在这里插入图片描述

因为涉及的站点信息和语音比较多,所以需要设置为编码模式,进行音频文件的选择性播放。具体的操作如下:

首先需要将A10引脚接地,将模块设置为触发播放;

然后将单片机的P0到P4和模块的A1到A5连接,具体的编程方式如下所示:

在这里插入图片描述

从上图中可以发现,采用的反码编程,在对A1到A5输入对应的编码后,需要在200ms~500ms之后,将A1到A5重新恢复到高电平,才可以完成该音频的触发播报。下面以第一首音频播报为例:

#define voice=P0;  //宏定义
void main(void)
{
  voice=~0X01;
  delayms(200); //延时200ms~500ms
  voice=0xff;   //即可触发第一次播报;
}

对于SD卡中存储的文件格式为MP3格式或者WAV格式,具体的操作如下:

首先要在SD卡中建立一个01的文件夹;

然后从001开始命名第一个音频文件,直到999结束,即一共可以存001.mp3 ~ 999.mp3个文件;

note:使用过程中,音频接口和喇叭接口同一时间只有一个有效;外接喇叭最多能接3w 4~8欧功放;最高电压不得高于5.5v

经过统计,这个模块共需要存储八段音频,分别是如下:

寝室站到了请依次从后门下车下车请注意安全

食堂站到了请依次从后门下车下车请注意安全

足球场站到了请依次从后门下车下车请注意安全

琴湖站到了请依次从后门下车下车请注意安全

综合楼站到了请依次从后门下车下车请注意安全

信息楼站到了请依次从后门下车下车请注意安全

南门站到了请依次从后门下车下车请注意安全

车辆起步请扶好站好注意安全请主动给老弱病残等乘客让座

目前已经完成了所有音频的转换工作,这里推荐一个[小破站](在线文字转语音,语音合成,真人语音合成-在线工具 (bugscaner.com)),可以完成常规意义上的文字转语音服务。。[小破站](在线文字转语音,语音合成,真人语音合成-在线工具 (bugscaner.com))

OLED显示模块

屏幕上要显示的语音提示如下:

到站:

  • 请依次从后门下车请注意安全

起步:

  • 车辆起步请扶好站好注意安全

  • 请主动给老弱病残等乘客让座

首先先说一下,今天总算把所有的模块都收到了,并且已经对于OLED屏幕模块,语音模块进行了功能性的实现,并且预留出了联调时需要用到的数据接口,还差一个GPS模块,因为初次启动,需要下载星历数据,所以占用的时间比较多,官方说是10分钟,但是在我看来,得一个小时了。。那我接下来总结一下上述两个模块在功能实现过程中,遇到的问题,以及解决之法吧!

首先是OLED模块,原先的设计是将汉字和英文都设置为12号字体,结果发现,OLED屏幕无法显示12号字体大小的汉字,显示时会出现乱码现象,且必须使用16号字体,而且不能更改,故必须调整最初的设计方案。新的显示设计如下:

在这里插入图片描述

再一次调试后,发现上面的设计方案还是不允许,因为纬度数据是10字节的字符串。,而经度数据是11字节的字符串。所以在屏幕上一张屏幕上不能实现数据的同时显示,需要进行分页显示。而为了达到时时显示的目的,可以通过矩阵按键将系统引导进时时显示的界面即可。这个对于后续的调试也是非常的容易。

然后是语音播报模块,经过昨天的分享,我们也知道了,目前系统总共有8个音频,所以目前有两个思路是可行的,就是直接开通8个引脚,通过将引脚拉低,来实现语音的播报,这样虽然实现上简单粗暴,但是这样的设计,一个是废资源,占用了太多的引脚,十分不利于后续功能的开发;二是利用单片机触发的方式来进行,共占用5个引脚,而且功能上更加的具有可扩展性,能够播报的音频数目也是可以达到31个音频。故最后选择了思路二,并且初步完成了手动语音播报。支持上下行切换的。有两个问题需要注意:

  • 在引脚拉低后,必须保持200ms的间隔再拉高,否则,模块检测不到触发信号的上升沿。
  • 需要将A10接地,从而将模块的触发方式设置为单片机触发模式。

最后是GPS模块了,这个模块官方说必须得放到室外进行初始化,我在室内窗前进行调试,依旧没有反应,大概已经快一个小时了,因为去年就使用过这个模块,所以并没有因为还没有驱动起来,而焦躁,因为心里有数,不是不能驱动,而是时候未到,静静等待就是最好的调试节奏。

在这里插入图片描述

[参考网址二](中科微GPS模块使用教程 ATGM332D ATGM336H - GPS/北斗模块 - 维可思电子 - Powered by Discuz! (waaax.top))

如图所示,上图中的逗号就是还没有正确得到的位置信息,可能是想偷懒,偷偷放在了窗子前,进行位置更新,所以卫星信号比较弱,数据更新异常慢慢。但这也放映了一个问题,功夫不负有心人,已经等到了好多数据了。并且对于其中的位置信息进行了验证,基本符合预期。接着等吧。。不如趁现在这点时间,写一下我的VHDL和ASIC作业吧!!

经过一番操作,也算是懂得了这个模块脾气了,初始化花费的时间比较多,第一次大概1个小时,每一次断电之后,进行系统重启后,这个模块都需要大概1分钟的准备时间,只有当模块上的灯出现一闪一闪的时候,才说明模块接收到了卫星信号,即此时的位置信息是有效的。这个可以作为一个状态指示信号。

[参考网址二](中科微GPS模块使用教程 ATGM332D ATGM336H - GPS/北斗模块 - 维可思电子 - Powered by Discuz! (waaax.top))

经过今天的一番操作,已经完成了所有模块的功能性编程,并且按照最后联调的方案,进行了数据接口的开发,所以基本是满足项目要求的。明天可以接着进行GPS模块的精度测量,并且确定如何写入任务书的位置信息。哈哈。