心跳跟随的心形灯(STM32(HAL)+WS2812+MAX30102)
文章目录
- 前言
- 介绍
- 系统框架
- 原项目地址
- 本项目开发开源地址
- 硬件PCB
- 软件功能
- 详细内容
- 硬件外壳制作
- WS2812级联及控制
- MAX30102血氧传感器
- 0.96OLED
- FreeRTOS
- 效果视频
- 总结
前言
在好几年前,我好像就看到了焊武帝 jiripraus在纪念结婚五周年时,制作的一个心跳跟随心形灯,感觉太浪漫了,于是在假期的时候,我也仿照做了一个,虽然还有很多需要完善的地方,但是大致功能已经实现了,下面开源讲讲开源的项目。
介绍
系统框架
心脏的外壳采用紫铜丝或黄铜丝焊接,1mm的铜丝较硬,适合完成外部框架的搭建,0.7mm的铜丝可塑性较好,适合焊接内部的WS2812,整个过程中吗,焊接难度较大,电子器件的固定难度也很大,我内部借助了一些热熔胶固定,有些丑,可以参考 jiripraus的固定方法。
原作者采用的Arduino主控,且没有借助PCB,纯飞铜线完成内部电子器件的连接。
因为我想利用FreeRTOS学习一下实际项目编写,所以将主控更换成了STM32F103C8T6,当然编写了两套代码,先编写了一套裸机开发,测试能够完成所有功能、之后移植了一套FreeRTOS的,都可以运行。
原项目地址
jiripraus项目地址(Arduino):https://www.instructables.com/Beating-LED-Heart/
本项目开发开源地址
裸机开发软件下载(STM32版本):https://download.csdn.net/download/zerokingwang/88173336
FreeRTOS开发软件下载(STM32版本):https://download.csdn.net/download/zerokingwang/88173410
硬件PCB(立创开源)下载链接:https://oshwhub.com/zeroking/my_heart_
所有文件上传到github了,也可以到github下载:https://github.com/VioletJA/MY_HEART
硬件PCB
绘制了包括STM32F103C8T6的最小系统、蜂鸣器、TP4059锂电池充电电路、OLED接口、MAX30102接口等。
软件功能
在没有手指触碰到MAX30102模块时,WS2812进行彩虹灯变换,当手指触碰到时,跟随检测到的心跳进行红色闪烁及蜂鸣器模拟心跳。
详细内容
硬件外壳制作
在3D打印的器件上进行焊接,我先用胶带固定好铜丝,然后再各个连接点进行焊接。
心形3D打印件:https://www.cgtrader.com/items/865899/download-page
WS2812焊接:最好黏在胶带上,固定好大致位置后再进行焊接,我没有找到其他好方法,焊接极其耗时。
WS2812级联及控制
当发送一串数据时,第一个24bits的数据给D1,第n个24bits的数据给第n。(24bit对应三原色,每一色八位)
输出码型通过下图判断,因此每一位的高低都需要进行严格控制
大多数采用的是PWM+DMA的模式,通过传输一串数据,控制不同占空比的PWM完成数据传输
HAL_TIM_PWM_Start_DMA(&ws2812_TIM, ws2812_CHANNEL, (uint32_t *)Pixel_Buf,(Pixel_NUM+1)*24);
参考:STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)
但有一点需要注意,必须在PWM的完成回调函数中进行手动关闭DMA传输,否则WS2812颜色不对(应该就是DMA传输出错了)
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==ws2812_TIM.Instance)HAL_TIM_PWM_Stop_DMA(&ws2812_TIM, ws2812_CHANNEL);
}
其他详细的代码控制都在开源代码中了
MAX30102血氧传感器
参考:【stm32】手把手用cubemx配置血氧传感器(MAX30102)
采用的是中断处理,每次模块发送一个下降沿中断,STM32接收到后进行数据处理。
模块采用IIC进行控制与数据读取,普通采用HAL配置硬件IIC就能够实现,但是在我用STM32F103C6T6进行测试的时候,HAl生成的代码中,IIC引脚不会自动设置为高速,导致运行会出现HAL_ERROR的问题,然而在STM32F103C8T6就已经纠正了这个错误。
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(i2cHandle->Instance==I2C1){__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);__HAL_RCC_I2C1_CLK_ENABLE();else if(i2cHandle->Instance==I2C2){__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);__HAL_RCC_I2C2_CLK_ENABLE();}
}
0.96OLED
在屏幕调试中,由于1616的字看上去太小了,于是我调整为2424的大小,这个时候,网上的一些库就不够用了,需要看懂是如何完成一个汉字的显示。
利用PCtoLCD2002完成取字模,一般设置如下
数据如下:
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x08,0x10,0x70,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x80,0xC0,0xF8,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xC0,0x04,0x18,0xF0,0xE0,0x00,0x00},
{0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x1F,0x18,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x1F,0x08,0x00,0x00,0x00,0x00,0x00},/*"心",0*/
网上一般说取数据是按照一行一行来的,一个数据代表的是8位,不足8位的按照8位算。
但是我实际测试,是按列算的,例如第一个数据0x00,表示第一列中的前八个点全没有点亮,第二个0x00代表的是第二列数据的前8个也全部没有点亮,当前8行的所有列都完成后,计算中间8行,一列一列,之后计算下面8行(24*24的数据)
例如下图:
而我们采用的低位在前时:
当第一个格子点亮时,对应的就是0x01
在OLED汉字显示的函数中,需要将汉字分为三上中下,完成三次打印,组成一个完整的汉字
//显示24*24汉字
void OLED_ShowCHinese24(uint8_t x,uint8_t y,uint8_t no)
{ uint8_t t;OLED_Set_Pos(x,y); for(t=0;t<24;t++){OLED_WR_Byte(CHI_24_24[3*no][t],OLED_DATA);} OLED_Set_Pos(x,y+1); for(t=0;t<24;t++){ OLED_WR_Byte(CHI_24_24[3*no+1][t],OLED_DATA);}OLED_Set_Pos(x,y+2); for(t=0;t<24;t++){ OLED_WR_Byte(CHI_24_24[3*no+2][t],OLED_DATA);}
}
FreeRTOS
在移植操作系统的时候,创建了两个任务,一个完成WS2812和蜂鸣器的控制,一个完成MAX30102和OLED的控制。
其中出现了一些跨任务的信号量,尝试利用任务通知方式进行数据保护,但是效果不佳,最后还是利用了临界区保护,在信号改写的地方进行了保护(临界区时间太长,系统会崩溃)
效果视频
心跳跟随心形灯
总结
通过制作这个小项目,还是学习了HAL的IIC配置,PWM的DMA模式,WS2812的控制,OLED屏幕控制,FreeRTOS也理解更多了一点,当然还只是刚开始入门,要学的东西还是有很多,在这个小项目中,还有很多bug和不完善的地方,比如说MAX30102测量的心率不准等等,但是目前打算就先这样结束,先继续学习吧。
相关文章:

心跳跟随的心形灯(STM32(HAL)+WS2812+MAX30102)
文章目录 前言介绍系统框架原项目地址本项目开发开源地址硬件PCB软件功能 详细内容硬件外壳制作WS2812级联及控制MAX30102血氧传感器0.96OLEDFreeRTOS 效果视频总结 前言 在好几年前,我好像就看到了焊武帝 jiripraus在纪念结婚五周年时,制作的一个心跳跟…...

5. 服务发现
当主机较少时,在抓取配置中手动列出它们的IP地址和端口是常见的做法,但不适用于较大规模的集群。尤其不适用使用容器和基于云的实例的动态集群,这些实例经常会变化、创建或销毁的情况。 Prometheus通过使用服务发现解决了这个问题࿱…...
算法备案背后的原因:确保技术透明度与公正
随着现代技术的发展,算法逐渐渗透到我们日常生活的各个方面,从金融决策到个性化的商品推荐,再到医疗诊断和司法系统。然而,这种无所不在的应用也带来了一系列的社会和伦理问题,尤其是在算法的透明度和公正性上。这正是…...

Linux centos 常用命令 【持续更新】
一、查看文件信息 indoe和目录项 # df命令查看每个硬盘分区的inode总数和已经使用的数量 df -i# 查看inode的大学 xfs_growfs /dev/sda1|grep "isize"# 查看文件的indoe号码 ls -istat查看文件信息 # 文件的详细信息 stat anaconda-ks.cfg # -t参数是在一行内输出…...

《使用 VMware 在 Windows 上搭建 Linux 系统的完整指南》
《使用 VMware 在 Windows 上搭建 Linux 系统的完整指南》 1、准备工作1.1 安装 VMware 软件1.2 下载 Linux 发行版镜像文件1.3 安装SSH工具 2、创建新的虚拟机2.1 VMware页面2.2 打开VMware页面并点击创建新的虚拟机,选择自定义2.3 选择系统兼容性,默认…...

大数据Flink(六十):Flink 数据流和分层 API介绍
文章目录 Flink 数据流和分层 API介绍 一、Flink 数据流...

软件测试面试题——如何测试App性能?
为什么要做App性能测试? 如果APP总是出现卡顿或网络延迟的情况,降低了用户的好感,用户可能会抛弃该App,换同类型的其他应用。如果APP的性能较好,用户体验高,使用起来丝滑顺畅,那该应用的用户粘…...

玩转C链表
链表是C语言编程中常用的数据结构,比如我们要建一个整数链表,一般可能这么定义: struct int_node {int val;struct int_node *next;}; 为了实现链表的插入、删除、遍历等功能,另外要再实现一系列函数,比如:…...
MySQL表的基础的增删改查
增(insert into) 插入所有列的数据 不写具体列名要确保字段都对应正确 -- 假设你有一个名为 "employees" 的表,有多个列 INSERT INTO employees VALUES (101, Alice, Manager, 50000);插入指定列的数据 -- 假设你有一个名为 "students" 的表&…...
数字化车间
一、数字化车间概述 数字化车间是以现代化信息、网络、数据库、自动识别等技术为基础,通过智能化、数字化、MES系统信息化等手段融合建设的数字化生产车间,精细地管理生产资源、生产设备和生产过程。随着工业4.0概念的提出,未来的工业和制造…...

基础堆排序
目录 基础堆排序 一、概念及其介绍 二、适用说明 三、过程图示 基础堆排序...

ISC 2023 | 赛宁网安验证评估 重磅发布
8月9日-10日,第十一届互联网安全大会(简称ISC 2023)在北京国家会议中心隆重举办。作为本次大会的战略合作伙伴(最高级别),赛宁网安主办 “安全验证评估论坛”,邀请邬江兴院士与业界专家共同…...

浅谈AI浪潮下的视频大数据发展趋势与应用
视频大数据的发展趋势是多样化和个性化的。随着科技的不断进步,人们对于视频内容的需求也在不断变化。从传统的电视节目到现在的短视频、直播、VR等多种形式,视频内容已经不再是单一的娱乐方式,更是涉及到教育、医疗、商业等各个领域。 为了满…...

github 无语的问题,Host does not existfatal: Could not read from remote repository.
Unable to open connection: Host does not existfatal: Could not read from remote repository. image.png image.png image.png Please make sure you have the correct access rights and the repository exists. 如果github desktop和git pull 和git clone全部都出问题了&…...

机器学习基础之《特征工程(4)—特征降维—案例》
一、探究用户对物品类别的喜好细分 1、找到用户和物品类别的关系 数据如下: (1)order_products__prior.csv:订单与商品信息 字段:order_id,product_id,add_to_cart_order,reordered…...
docker 删除镜像文件
docker 容器里面太多镜像,D盘满了 四 查看和移除镜像 1 查看镜像 docker images 2 移除镜像命令 docker rmi 镜像名称 # 只输入前四位即可 五 实际有效操作 清除所有不使用的资源 docker system prune 这个命令将会删除所有不使用的镜像、容器和数据卷等资…...

ArcGIS Pro 基础安装与配置介绍
ArcGIS Pro ArcGIS Pro作为ESRI面向新时代的GIS产品,它在原有的ArcGIS平台上继承了传统桌面软件(ArcMap)的强大的数据管理、制图、空间分析等能力,还具有其独有的特色功能,例如二三维融合、大数据、矢量切片制作及发布…...
剑指 Offer 13. 机器人的运动范围
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如&am…...

技术应用:Docker安全性的最佳实验|聊聊工程化Docker
🔥 技术相关:《技术应用》 ⛺️ I Love you, like a fire! 文章目录 首先,使用Docker Hub控制访问其次,保护密钥写在最后 不可否认,能生存在互联网上的软件都是相互关联的,当我们开发一款应用程序时&#x…...

【Tomcat】Tomcat部署及优化
Tomcat 它是一个免费、开源的web应用服务器;基于java代码开发的软件;处理动态请求和基于Java代码的页面开发; 可以在html当中写入Java代码,Tomcat可以解析html页面当中的Java代码,执行动态请求以及动态页面 缺点&#…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...