0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32跑步路径记录

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-09-18 09:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

基于STM32跑步路径记录

随着科技不断进步,电子化设备不断进入涌入我们的日常生活。生活水平的提高,各项健身运动应运而生,然后,健身运动不能盲目进行,科学的健身方式才能有效的提升我们自身的身体素质。

现如今各自手环手表的出现, 通过智能手环,用户可以记录日常生活中的锻炼、睡眠、部分还有饮食等实时数据,并将这些数据与手机、平等同步,起到通过数据指导健康生活的作用。

智能手环作为可穿戴设备,其功能还是比较强大的,其开发涉及智能手环MCU数据指令到蓝牙IC的传输、蓝牙到APP的数据通信协议、APP到手机内部的通信调试逻辑实现、APP数据到云端服务器的数据库算法设计等一系列的开发。支持多种运动监控模式,可以实时监控身体的各项性能指标。

我国智能手环产品真正大范围进入消费市场是在2012年以后,一方面是这一时期步入4G时代以后手机智能化趋势加快,与手机一样具备数据分享的智能手环的出现给智能手环的研究和应用打开了另一个世界。另一方面是更多实用性功能快速出现,手环不仅仅是用来记录身体特征的单纯工具,同时也可以满足通话、移动支付、人体识别、智能提醒功能以及分享功能,极大的扩宽了手环的应用人群。佩戴智能手环带来健康、科技、自信有品位的良好感受,成为了高科技产品的典型之一。

  基于STM32的跑步路记录主要用于记录用户在日常身体锻炼中,可设置跑步路径,跑步路线规划,在50~80m前提醒拐弯,蜂鸣器报警提示;记录跑步路径,显示当前位置,通过按键设置跑步距离。

2.模块选型

2.1 主控MCU:STM32F103C8最小系统板

  STM32最小系统板:STM32系统板

pYYBAGMl1VqAadOtAALXCNzhAsY724.png#pic_center

2.2 OLED显示屏:0.96寸SPI/IIC接口

  显示屏幕:OLED屏幕

poYBAGMl1VqAeYm6AAG1S6bL93A707.png#pic_center

2.3 GPS定位模块

GPS定位:GPS模块 北斗模块 双模定位 ATGM336H

pYYBAGMl1VqADX-SAAGLWKsdK4I204.png#pic_center

支持北斗/GPS/GLONASS卫星系统

支持3.3V-5V供电,可以方便接入3.3V或者5V单片机系统3、板载可充电电子,可加速热启动搜星过程

默认波特率9600,波特率可设置

TTL电平UART接口,用户连接单片机的串口TTL电平或者USB-TTL模块测试。

带有SMA和 IPEX两种天线接口,方便选择自己需要的外置天线。

带有PPS授时输出引脚,方便做时钟同步等应用。

poYBAGMl1VuAcSN1AAJWRsuDDFA662.png#pic_centerpYYBAGMl1VuALeEnAAOOC8U2fBs276.png#pic_center

2.4 蜂鸣器

  蜂鸣器:有源蜂鸣器

poYBAGMl1VuANwshAAHuk9Zbvm0921.png#pic_center

3.电路设计

poYBAGMl1VyAJQlhAAGj2YUgI74662.png#pic_center

4.实物展示

pYYBAGMl1VyAPjb8AAYQaG5owXc416.png#pic_centerpoYBAGMl1V2AbU4tAAbxna4FSIQ113.png#pic_center

4.软件设计

4.1 GPS定位信息获取

  ATGM336H采用串口协议,直接接上电源,在空旷的地方只要接收到卫星信号即可返回卫星定位数据。

pYYBAGMl1V2AQhWMAARi-lW3NT4103.png#pic_center

/*
函数功能:分析BDGSV信息
函数参数:GPS_DecodeInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/
void GPS_BDGSV_InfoGet(GPS_Msg *GPS_DecodeInfo,u8 *buf)
{
	u8 *p,*p1,dx;
	u8 len,i,j,slx=0;
	u8 posx;
	p=buf;
	p1=(u8*)strstr((const char *)p,"$BDGSV");
	if(!p1)return; //没有查找成功
	len=p1[7]-'0';								//得到BDGSV的条数
	posx=GPS_GetCommaOffset(p1,3); 					//得到可见北斗卫星总数
	if(posx!=0XFF)GPS_DecodeInfo->beidou_svnum=GPS_StrtoNum(p1+posx,&dx);
	for(i=0; ibeidou_slmsg[slx].beidou_num=GPS_StrtoNum(p1+posx,&dx);	//得到卫星编号
			else break;
			posx=GPS_GetCommaOffset(p1,5+j*4);
			if(posx!=0XFF)GPS_DecodeInfo->beidou_slmsg[slx].beidou_eledeg=GPS_StrtoNum(p1+posx,&dx);//得到卫星仰角 
			else break;
			posx=GPS_GetCommaOffset(p1,6+j*4);
			if(posx!=0XFF)GPS_DecodeInfo->beidou_slmsg[slx].beidou_azideg=GPS_StrtoNum(p1+posx,&dx);//得到卫星方位角
			else break;
			posx=GPS_GetCommaOffset(p1,7+j*4);
			if(posx!=0XFF)GPS_DecodeInfo->beidou_slmsg[slx].beidou_sn=GPS_StrtoNum(p1+posx,&dx);	//得到卫星信噪比
			else break;
			slx++;
		}
		p=p1+1;//切换到下一个BDGSV信息
	}
}


4.2 卫星数量获取

/*
函数功能:分析GNGGA信息
函数参数:
		GPS_DecodeInfo:nmea信息结构体
		buf:接收到的GPS数据缓冲区首地址
*/
void GPS_GNGGA_InfoGet(GPS_Msg *GPS_DecodeInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	p1=(u8*)strstr((const char *)buf,"$GNGGA");
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,6);								//得到GPS状态
	if(posx!=0XFF)GPS_DecodeInfo->gpssta=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,7);								//得到用于定位的卫星数
	if(posx!=0XFF)GPS_DecodeInfo->posslnum=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,9);								//得到海拔高度
	if(posx!=0XFF)GPS_DecodeInfo->altitude=GPS_StrtoNum(p1+posx,&dx);
}

4.3 移动速度获取

/*
函数功能:分析GNVTG信息
函数参数:GPS_DecodeInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/

void GPS_GNVTG_InfoGet(GPS_Msg *GPS_DecodeInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	p1=(u8*)strstr((const char *)buf,"$GNVTG");
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,7);								//得到地面速率
	if(posx!=0XFF)
	{
		GPS_DecodeInfo->speed=GPS_StrtoNum(p1+posx,&dx);
		if(dx<3)GPS_DecodeInfo->speed*=GPS_GetPow(10,3-dx);	 	 		//确保扩大1000倍
	}
}

4.4 主函数

int main()
{
  u8 key;
  char buff[100];
	u32 E_data=0,E_data2=0,N_data=0,N_data2=0;
	LEDInit();
  KEYInit();
  Beep_Init();
	USARTx_Init(USART1,115200);
	USARTx_Init(USART2,9600);//串口3初始化(接收GPS数据)
  TIMx_Init(TIM2,72,20000);//定时20ms,用定时器2辅助usart1接收
	TIMx_Init(TIM3,72,20000);
	USARTx_Sendstr(USART1,"串口1初始化成功\r\n");
	OLED_Init();//OLED初始化
  u8 x=5;
  u8 y=16;
  u8 stat=0xff;
  u8 stat2=0;
  u16 time=0;
  u16 distance=400;
AA:
  while(1)
  {
    /*距离选择*/
    OLED_ClearGram();
    OLED_Display_Font(32,0,16,2);
    OLED_Display_Font(32+16,0,16,3);
    OLED_Display_Font(32+16*2,0,16,4);
    OLED_Display_Font(32+16*3,0,16,5);
    OLED_Display_str(24,16,16,(u8 *)"400 M");
    OLED_Display_str(24,16*2,16,(u8 *)"1000 M");
    OLED_Display_str(24,16*3,16,(u8 *)"2000 M");
    OLED_Display_str(128-30,y,16,(u8 *)"<--");
    key=GetKeyVual(1);
    if(key==1)//距离选择
    {
      if(y<48)y+=16;
      else y=16;   
      OLED_RefreshGram();//更新数据到屏幕
    }
    else if(key==2)//确认
    {
      BEEP=1;
      if(y==16)distance=400;
      else if(y==32)distance=1000;
      else if(y==48)distance=2000;
      OLED_RefreshGram();//更新数据到屏幕
      DelayMs(50);
      BEEP=0;
      DelayMs(200);
      break;
    }
    DelayMs(1);
    time++;
    if(time>=50)
    {
      time=0;
      OLED_RefreshGram();//更新数据到屏幕
      LED1=!LED1;
    }
  }
  y=60;
  while(1)
  {
		if(usart2_flag)//获取GPS数据
		{
			usart2_rx_buff[usart2_cnt]='\0';
			//printf("%s\r\n",usart2_rx_buff);
			usart2_flag=0;
			usart2_cnt=0;
			GPS_GNGGA_InfoGet(&GPS_DecodeInfo,usart2_rx_buff);//获取卫星数量
      GPS_GNVTG_InfoGet(&GPS_DecodeInfo,usart2_rx_buff);//获取移动速度
      GPS_GNRMC_InfoGet(&GPS_DecodeInfo,usart2_rx_buff);//获取经纬度		
			printf("卫星数量: %d\r\n",GPS_DecodeInfo.posslnum);
			E_data=GPS_DecodeInfo.longitude;
			N_data=GPS_DecodeInfo.latitude;
			printf("经度:%c,%d \r\n",GPS_DecodeInfo.ewhemi,E_data);
			printf("纬度:%c,%d\r\n",GPS_DecodeInfo.nshemi,N_data);		
      printf("移动速度:%.1f. km/h\r\n",GPS_DecodeInfo.speed/1000.0);
    }
    if(GPS_DecodeInfo.posslnum>=3 && stat2==0)//卫星数量超过3颗开始定位
    {
      printf("stat2==%d\n",stat2);
      BEEP=1;
      DelayMs(1000);
      BEEP=0;
      stat2=1;
      
    }
    key=GetKeyVual(1);
    if(key==1 && stat2==1)//开始
    {
      LED1=!LED1;
      stat=0;
      x=5;
      y=60;
    }
    else if(key==2)//退出
    {
      LED3=LED2=1;
      LED1=!LED1;
      stat=0xff;
      stat2=0;
      y=16;
      goto AA;//重新选择距离
    }
    OLED_ClearGram();
    OLED_Display_Font(15,35,16,2);
    OLED_Display_Font(15+16,35,16,3);
    snprintf(buff,sizeof(buff),":%d M",distance);
    OLED_Display_str(15+16*2,35,16,(u8 *)buff);
    OLED_Display_Font(15,15,16,0);
    OLED_Display_Font(15+16,15,16,1);
    //snprintf(buff,sizeof(buff),":%.fkm/h",GPS_DecodeInfo.speed/1000.0);
    snprintf(buff,sizeof(buff),":%.fkm/h",GPS_DecodeInfo.speed/1000.0);
    OLED_Display_str(15+16*2,15,16,(u8 *)buff);
    OLED_DrawRectangle(5, 5, 124, 60);
    OLED_DrawRectangle(4, 4, 125, 61);
    gui_circle(x, y,1,3,1);
    if(stat==0)
    {
      if(N_data-N_data2>=4)
      {
        x+=2;
        N_data2=N_data;
      }
    }
    else if(stat==1)
    {
      if(N_data-N_data2>=2 || N_data2-N_data>=2)
      {
        N_data2=N_data;
        y--;
      }
    }
    else if(stat==2)
    {
      if(N_data2-N_data>=3)
      {
        N_data2=N_data;
        x-=2;
      }
    }
    else if(stat==3)
    {
      if(N_data-N_data2>=3 || N_data2-N_data>=3)
      {
        N_data2=N_data;
        y+=2;
      }
    }
    if(x>=124 && y==60)
    {
      x=124;
      stat=1;
    }
    else if(y==5 && x>=124)
    {
      x=124;
      stat=2;
    }
    else if(x<=5 && y==5)
    {
      x=5;
      stat=3;
    }
    else if(x==5 && y>=60 && (stat==3 || stat==4))
    {
      BEEP=1;
      DelayMs(100);
      BEEP=0;
      stat=4;
      LED1=LED2=1;
      LED3=!LED3;
      y=60;
      x=5;
      
    }
    if(time>=20)
    {
      time=0;
      if(stat==0xff)
      {
        LED3=LED2=1;
        LED1=!LED1;
      }
      else if(stat<=3)
      {
        LED1=LED3=1;
        LED2=!LED2;
      }
    }
    DelayMs(1);
    time++;
    OLED_RefreshGram();//更新数据到屏幕
  }
}

5.注意事项

  由于采用的是STM32F103实现本功能,该CPU主频仅有72MHZ,SRAM和flash均比较小,所以此示例并未调用地图接口实现,而是通过直接判断经纬度来决定当前位置。因此实现功能方式类似于公交报站实现方式,所有路径需要提交采集路线,进行路径保存。




审核编辑:刘清


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6074

    文章

    45340

    浏览量

    663586
  • GPS技术
    +关注

    关注

    0

    文章

    26

    浏览量

    10567
  • sram
    +关注

    关注

    6

    文章

    808

    浏览量

    117225
  • STM32F103
    +关注

    关注

    34

    文章

    490

    浏览量

    67085
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    电源管理芯片在跑步机中的应用

    跑步是一项全民性的健身运动,跑步机作为一种现代化健身器材,已经越来越多地融入到人们的日常生活当中。
    的头像 发表于 09-30 11:40 1237次阅读
    电源管理芯片在<b class='flag-5'>跑步</b>机中的应用

    京东:调用用户行为API分析购买路径,优化页面跳转逻辑

    ​  在电商平台的激烈竞争中, 用户购买路径的流畅性 直接影响转化率。京东通过深度整合用户行为API,构建了完整的购买路径分析体系,显著优化了页面跳转逻辑。以下是关键技术实现路径: 一、用户行为
    的头像 发表于 09-18 14:38 419次阅读
    京东:调用用户行为API分析购买<b class='flag-5'>路径</b>,优化页面跳转逻辑

    铁路巡检升级:云翎智能高精度执法记录仪+指挥调度系统实现故障秒级响应

    数据实时回传;结合AI智能调度算法,动态优化响应路径,将故障识别与资源调度效率提升至秒级。云翎智能高精度巡检执法记录仪一、系统核心架构与技术实现高精度执法记录仪硬件
    的头像 发表于 07-29 22:37 601次阅读
    铁路巡检升级:云翎智能高精度执法<b class='flag-5'>记录</b>仪+指挥调度系统实现故障秒级响应

    STM32CUBEIDE使用UCOS的时候,头文件路径已经添加了,依旧提示未找到路径怎么解决?

    在使用UCOS的时候,头文件路径已经添加了,他依旧提示未找到路径怎么解决
    发表于 07-25 06:28

    智能路径调度:AI驱动负载均衡的异常路径治理实践

    在AI驱动的数据中心网络环境中,传统的“尽力而为”和“无差别均分”负载均衡策略已力不从心。基于路径综合质量的动态WCMP机制,通过实时感知路径状态、果断剔除异常、智能调度“健康”资源,有效解决了AI流量对网络高可靠、高性能的核心诉求。
    的头像 发表于 07-03 16:26 1019次阅读
    智能<b class='flag-5'>路径</b>调度:AI驱动负载均衡的异常<b class='flag-5'>路径</b>治理实践

    【正点原子STM32MP257开发板试用】系统更新

    【正点原子STM32MP257开发板试用】系统更新 本文介绍了正点原子 STM32MP257 开发板实现固件上传与系统更新的主要流程。 项目介绍 前期准备工作包括:官方资料更新记录查询、固件下载
    发表于 06-17 18:35

    AGV小车中的动态路径规划算法揭秘

    在现代仓储、物流和制造业中,自动导引车(AGV)的身影日益普遍。它们如同勤劳的工蚁,在复杂的环境中自主穿梭,高效地完成物料搬运任务。而支撑AGV实现智能导航的核心技术之一,便是路径规划。特别是当环境
    的头像 发表于 06-17 15:54 1160次阅读
    AGV小车中的动态<b class='flag-5'>路径</b>规划算法揭秘

    言必信_如何选择适合跑步机的电源滤波器

    本文主要介绍了跑步机电源滤波器的作用、选择与使用要点,以及滤波器的插入损耗特性。在选择跑步机电源滤波器时,应考虑电源参数电压、电流、电磁兼容标准要求、插入损耗特性以及安规认证与安全性。
    的头像 发表于 06-09 17:12 482次阅读
    言必信_如何选择适合<b class='flag-5'>跑步</b>机的电源滤波器

    基于STM32的卫星GPS路径记录仪(附完整源代码)实例项目下载

    基于STM32的卫星GPS路径记录仪(附完整源代码)实例项目推荐下载!
    发表于 05-29 21:35

    每周推荐!基于STM32开发项目实例下载(含PCB、原理图、源码等)

    、论文等) 基于STM32的武警哨位联动报警系统设计,支持以太网和WIFI通信(硬件、源码、论文等) 项目实例下载! 4、基于STM32的卫星GPS路径记录仪(附完整源代码) 基
    发表于 05-26 14:01

    基于STM32的卫星GPS路径记录仪(附完整源代码)

    基于STM32的卫星GPS路径记录仪(附完整源代码) 项目实例下载! 纯分享帖,需要者可点击附件免费获取完整资料~~~【免责声明】本文系网络转载,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请第一时间告知,删
    发表于 05-23 20:48

    FRED的光路和光路历史记录

    用户之后使用诊断工具,如光路追迹路径报告、杂散光报告、图像伪影诊断工具,以及在分析表面中使用射线选择过滤器。 创建/用户线光历史记录文件 此选项保存每条光线的每个交点的坐标数据,可以用于重新绘制选定路径的光线轨迹。通常,这是通
    发表于 03-07 08:55

    DS1678实时事件记录器技术手册

    DS1678为实时时钟(RTC)事件记录仪,用来记录每次触发/INT引脚的非周期、异步事件的时间和日期。该器件记录第一次事件发生时的秒、分、时、星期、日期、月、年及世纪信息,并开启16位历时
    的头像 发表于 02-27 15:27 763次阅读
    DS1678实时事件<b class='flag-5'>记录</b>器技术手册

    QCC3040蓝牙模块助力跑步机功能升级

    跑步机或者健身车中应用主端音频蓝牙模组的方案主要涉及到音频传输和无线控制,提供一个无缝、无线的运动体验。一、音频传输主端音频蓝牙模组ANS-BT302DM使用QCC3040方案,可以用于无线音频
    的头像 发表于 01-09 15:07 1072次阅读
    QCC3040蓝牙模块助力<b class='flag-5'>跑步</b>机功能升级