做英文网站赚钱,wordpress管理登录,wordpress 前端表单,wordpress搜资料文章目录 前言介绍系统框架原项目地址本项目开发开源地址硬件PCB软件功能 详细内容硬件外壳制作WS2812级联及控制MAX30102血氧传感器0.96OLEDFreeRTOS 效果视频总结 前言
在好几年前#xff0c;我好像就看到了焊武帝 jiripraus在纪念结婚五周年时#xff0c;制作的一个心跳跟… 文章目录 前言介绍系统框架原项目地址本项目开发开源地址硬件PCB软件功能 详细内容硬件外壳制作WS2812级联及控制MAX30102血氧传感器0.96OLEDFreeRTOS 效果视频总结 前言
在好几年前我好像就看到了焊武帝 jiripraus在纪念结婚五周年时制作的一个心跳跟随心形灯感觉太浪漫了于是在假期的时候我也仿照做了一个虽然还有很多需要完善的地方但是大致功能已经实现了下面开源讲讲开源的项目。 介绍
系统框架
心脏的外壳采用紫铜丝或黄铜丝焊接1mm的铜丝较硬适合完成外部框架的搭建0.7mm的铜丝可塑性较好适合焊接内部的WS2812整个过程中吗焊接难度较大电子器件的固定难度也很大我内部借助了一些热熔胶固定有些丑可以参考 jiripraus的固定方法。
原作者采用的Arduino主控且没有借助PCB纯飞铜线完成内部电子器件的连接。
因为我想利用FreeRTOS学习一下实际项目编写所以将主控更换成了STM32F103C8T6当然编写了两套代码先编写了一套裸机开发测试能够完成所有功能、之后移植了一套FreeRTOS的都可以运行。
原项目地址
jiripraus项目地址Arduinohttps://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对应三原色每一色八位
输出码型通过下图判断因此每一位的高低都需要进行严格控制 大多数采用的是PWMDMA的模式通过传输一串数据控制不同占空比的PWM完成数据传输
HAL_TIM_PWM_Start_DMA(ws2812_TIM, ws2812_CHANNEL, (uint32_t *)Pixel_Buf,(Pixel_NUM1)*24);参考STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块PWMDMA方式
但有一点需要注意必须在PWM的完成回调函数中进行手动关闭DMA传输否则WS2812颜色不对应该就是DMA传输出错了
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{if(htim-Instancews2812_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-InstanceI2C1){__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-InstanceI2C2){__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(t0;t24;t){OLED_WR_Byte(CHI_24_24[3*no][t],OLED_DATA);} OLED_Set_Pos(x,y1); for(t0;t24;t){ OLED_WR_Byte(CHI_24_24[3*no1][t],OLED_DATA);}OLED_Set_Pos(x,y2); for(t0;t24;t){ OLED_WR_Byte(CHI_24_24[3*no2][t],OLED_DATA);}
}FreeRTOS
在移植操作系统的时候创建了两个任务一个完成WS2812和蜂鸣器的控制一个完成MAX30102和OLED的控制。
其中出现了一些跨任务的信号量尝试利用任务通知方式进行数据保护但是效果不佳最后还是利用了临界区保护在信号改写的地方进行了保护临界区时间太长系统会崩溃
效果视频 心跳跟随心形灯 总结
通过制作这个小项目还是学习了HAL的IIC配置PWM的DMA模式WS2812的控制OLED屏幕控制FreeRTOS也理解更多了一点当然还只是刚开始入门要学的东西还是有很多在这个小项目中还有很多bug和不完善的地方比如说MAX30102测量的心率不准等等但是目前打算就先这样结束先继续学习吧。