STM32实战项目:从零打造GPS蓝牙自行车码表,掌握传感器、蓝牙、Flash存储等核心技术

一、 引言

骑行,作为一项绿色健康的运动方式,越来越受到人们的喜爱。而记录骑行数据,分析速度、里程等信息,则成为了许多骑行爱好者的追求。本篇文章将带你使用STM32单片机,DIY一款功能完备的自行车码表,记录你的每一次骑行轨迹!

二、 功能概述

本项目将实现以下功能:

  • 实时速度显示: 利用霍尔传感器采集车轮转速,计算并显示实时速度。
  • 里程统计: 记录单次和总里程,方便用户了解骑行距离。
  • 骑行时间记录: 记录单次骑行时间,方便用户掌握运动量。
  • 轨迹记录: 利用GPS模块获取经纬度信息,记录骑行轨迹,并在手机APP上进行查看。
  • 数据存储: 将骑行数据存储到外部Flash芯片,方便用户后续查看和分析。
  • LCD显示: 使用LCD屏幕实时显示速度、里程、时间等信息。
  • 蓝牙传输: 通过蓝牙模块将骑行数据传输至手机APP,实现更丰富的功能和数据分析。
三、 系统设计

3.1 硬件设计

本项目硬件部分主要由以下模块组成:

fddfc539cffa46c5b1233aae529bd8c1.png

  • 主控芯片: STM32F103C8T6,性价比高,性能满足项目需求。
  • 霍尔传感器: 用于检测车轮转速,可选择磁铁+霍尔传感器组合或一体式霍尔传感器。
  • GPS模块: 用于获取经纬度信息,记录骑行轨迹,可以选择支持GPS+北斗双模的模块,提高定位精度。
  • LCD显示屏: 用于显示速度、里程、时间等骑行数据,可以选择1602、OLED等类型。
  • 蓝牙模块: 用于与手机APP进行数据传输,可以选择HC-05、HM-10等蓝牙2.0模块,或CC2540、nRF51822等蓝牙4.0/BLE模块。
  • 外部Flash: 用于存储骑行数据,可以选择SPI接口的Flash芯片,容量根据需求选择。
  • 电源模块: 为整个系统提供电源,可以使用锂电池供电,并设计充电电路。

3.2 软件设计

软件部分主要包括以下几个模块:

6f7f80fcf8434779808181a15a8b4491.png

  • 传感器数据采集: 通过定时器中断读取霍尔传感器数据,计算车轮转速。
  • 数据处理: 对传感器数据进行滤波处理,计算实时速度、里程等信息。
  • 显示控制: 将处理后的数据格式化输出到LCD屏幕上。
  • 蓝牙通信: 通过蓝牙模块与手机APP进行数据交互,发送实时数据和接收控制指令。
  • 数据存储: 将骑行数据存储到外部Flash芯片,方便用户后续查看和分析。

四、 软件实现

本项目的软件部分基于STM32标准库进行开发,核心代码使用C语言编写,并结合STM32CubeMX进行初始化配置,简化开发流程。

4.1 霍尔传感器数据采集

霍尔传感器用于检测车轮转动,每次磁铁经过传感器时,会产生一个脉冲信号。我们利用STM32的定时器中断来捕捉这个脉冲信号,并计算车轮转速。

 
  1. // 定时器中断服务函数

  2. void TIM2_IRQHandler(void)

  3. {

  4. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // 判断定时器更新中断

  5. {

  6. // 读取霍尔传感器状态

  7. sensor_state = GPIO_ReadInputDataBit(SENSOR_GPIO_PORT, SENSOR_GPIO_PIN);

  8. // 判断上升沿,计算脉冲个数

  9. if (sensor_state == SET && last_sensor_state == RESET)

  10. {

  11. pulse_count++;

  12. // 计算时间差

  13. current_time = TIM_GetCounter(TIM2);

  14. time_diff = current_time - last_time;

  15. last_time = current_time;

  16. // 计算速度,避免除零错误

  17. if (time_diff > 0)

  18. {

  19. speed = (WHEEL_CIRCUMFERENCE * 3600.0) / (time_diff * TIM2_PRESCALER); // 单位:km/h

  20. }

  21. }

  22. last_sensor_state = sensor_state;

  23. TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位

  24. }

  25. }

在定时器中断服务函数中,我们首先读取霍尔传感器的状态。如果检测到上升沿,则认为车轮转动一圈,脉冲计数加一。同时,我们记录当前时间和上次时间,计算时间差,并根据预设的车轮周长和定时器预分频系数计算出实时速度。

4.2 数据处理

为了提高数据准确性,我们需要对原始的传感器数据进行滤波处理,去除噪声干扰。同时,我们还需要根据速度计算里程,并进行其他数据统计。

 
  1. // 数据处理函数

  2. void data_process(void)

  3. {

  4. // 使用滑动平均滤波器对速度进行滤波

  5. filtered_speed = (int)(0.9 * filtered_speed + 0.1 * speed);

  6. // 计算里程,单位:km

  7. distance += (float)filtered_speed * TIME_INTERVAL / 3600.0;

  8. // ...其他数据处理,如时间统计、最大速度记录等

  9. }

这里我们使用简单的滑动平均滤波器对速度进行平滑处理。当然,你也可以根据实际情况选择其他滤波算法,例如卡尔曼滤波等。

4.3 显示控制

为了直观地显示骑行数据,我们使用LCD屏幕进行实时显示。

 
  1. // LCD显示函数

  2. void display_data(void)

  3. {

  4. // 清屏

  5. LCD_Clear(Black);

  6. // 显示速度

  7. LCD_SetCursor(0, 0);

  8. LCD_Printf("Speed: %2d.%d km/h", (int)filtered_speed, (int)(filtered_speed * 10) % 10);

  9. // 显示里程

  10. LCD_SetCursor(0, 1);

  11. LCD_Printf("Dist: %d.%d km", (int)distance, (int)(distance * 10) % 10);

  12. // ...显示其他数据,如时间、平均速度等

  13. }

在LCD显示函数中,我们首先清屏,然后使用LCD库函数将速度、里程等信息格式化输出到LCD屏幕上。

4.4 蓝牙通信

为了实现更丰富的功能,例如数据记录、轨迹显示等,我们可以使用蓝牙模块将骑行数据传输到手机APP。

 
  1. // 蓝牙数据发送函数

  2. void bluetooth_send_data(void)

  3. {

  4. // 数据打包

  5. uint8_t data_packet[PACKET_SIZE];

  6. data_packet[0] = 0xAA; // 数据头

  7. data_packet[1] = (uint8_t)(filtered_speed >> 8);

  8. data_packet[2] = (uint8_t)filtered_speed;

  9. // ...打包其他数据,如里程、时间等

  10. // 通过蓝牙发送数据

  11. HAL_UART_Transmit_DMA(&huart1, data_packet, sizeof(data_packet));

  12. }

在蓝牙数据发送函数中,我们首先定义一个数据包,将需要发送的数据按照一定的协议格式进行打包。这里我们使用了简单的协议,数据包开头为固定的数据头,后面跟着各个数据项。数据打包完成后,我们使用HAL库函数 HAL_UART_Transmit_DMA 将数据通过蓝牙模块发送出去。

4.5 数据存储

为了保存骑行数据,方便用户后续查看和分析,我们可以使用外部Flash芯片进行数据存储。

 
  1. // 数据存储函数

  2. void data_store(void)

  3. {

  4. // 将骑行数据写入Flash

  5. uint32_t address = FLASH_START_ADDR + data_counter * sizeof(RideData);

  6. RideData data;

  7. data.speed = filtered_speed;

  8. data.distance = distance;

  9. // ...存储其他数据

  10. // 使用HAL库函数将数据写入Flash

  11. if (HAL_FLASH_Unlock() == HAL_OK)

  12. {

  13. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (uint32_t *)&data, sizeof(RideData)/4) == HAL_OK)

  14. {

  15. data_counter++; // 数据计数加一

  16. HAL_FLASH_Lock();

  17. }

  18. else

  19. {

  20. // 处理写入错误

  21. }

  22. }

  23. else

  24. {

  25. // 处理解锁错误

  26. }

  27. }

在数据存储函数中,我们首先定义一个结构体 RideData 用于存储一次骑行的数据,例如速度、里程、时间等。然后,我们使用HAL库函数 HAL_FLASH_Unlock 解锁Flash,使用 HAL_FLASH_Program 将数据写入指定地址,最后使用 HAL_FLASH_Lock 锁定Flash。

五、 手机APP设计

为了更方便地查看和分析骑行数据,我们可以开发配套的手机APP。APP可以通过蓝牙接收码表发送的数据,并实现以下功能:

  • 实时数据显示: 实时显示速度、里程、时间、轨迹等信息。
  • 历史数据查看: 查看历史骑行记录,并进行数据分析。
  • 轨迹地图显示: 在地图上显示骑行轨迹,并可以分享到社交平台。
  • 设置参数: 设置车轮周长、时间格式等参数。

手机APP的开发可以使用Java、Kotlin、Swift等语言,并选择合适的蓝牙库进行开发。

六、 总结

本文介绍了基于STM32的自行车码表的设计与实现,涵盖了硬件设计、软件实现、手机APP设计等方面。通过本项目的学习,可以掌握STM32单片机开发、传感器应用、蓝牙通信、数据存储等知识。当然,你也可以根据自己的需求,扩展更多功能,例如心率监测、踏频测量、导航等,打造一款功能更强大的智能自行车码表!

相关知识点链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值