发作品签到
专业版

爱的奖惩氛围灯

工程标签

296
0
0
1

简介

设计一个既可以拿来做奖惩游戏,也可以当氛围灯或小夜灯使用的“愚”乐电子产品。这个可是智能语音控制的哦,科技感满满哈。

简介:设计一个既可以拿来做奖惩游戏,也可以当氛围灯或小夜灯使用的“愚”乐电子产品。这个可是智能语音控制的哦,科技感满满哈。
电子”愚“ 乐设计征集令

开源协议

TAPR Open Hardware License

(未经作者授权,禁止转载)
创建时间:2024-03-06 01:23:42更新时间:2024-04-01 01:43:30

描述

前言

一直想做一个奖惩游戏氛围灯。既可以用来做游戏,还可以当氛围灯使用那种哦。
醒着的时候可以用来成人互动游戏,也可以陪娃游戏哦,游戏内容可以通过面板随意定制哦,随便奖励或者惩罚,哈哈。
夜晚可以五彩斑斓、也可以呼吸灯、也可以烘托氛围哦。。。反正24小时不用闲着。哈哈,想一想都好玩哦。

就是下面这个哦,惩罚和奖励内容随意定制哦。

26fd4b7011f9f715ca74d3f79266899.jpg

语音控制功能

image.png

image.png

image.png

备注:有时候语音接收不是很灵敏,也可能是我普通话不标准。语音指令越少越好,否则指令越多反应越慢,越不灵敏。

硬件设计

采用立创EDA进行设计。

主控部分

采用STM32F103,为什么选这个呢,功能够用,资源很丰富呢,不信你看哦
c175a775e586a79ddbd448fc345b666.png

设计如下:

image.png

主要功能:

1-控制语音模块
2-控制LED显示效果
3-实现随机算法
4-实现电量检测
5-解析语音指令

WS2812显示

电路图

采用8个颗ws2812,由于可以串联,只需要一个IO就可以控制显示效果以及颜色变化,比起LED节约了很多MCU的IO资源。
image.png
注意:供电电压不要小于3.5V哦,亮度越大功耗越大呢。

ws2812介绍

采用了4颗WS2812B。通过PA7管脚进行颜色控制,这里采用SPI+DMA方式。PA7为MOSI,可以设置SPI为只发送模式,可以节省管脚。
WS2812 芯片采用单线通讯方式,采用归零码的方式发送信号.芯片在上电复位后,接受 DIN 打来的数据,接受够24Bit 后,DOUT 端开始转发数据,为下一个芯片提供输入数据。在转发之前 DOUT 口一直拉低,此时芯片不接受新的数据。芯片 OUTR,OUTG,OUTB 三个 PWM 输出口根据接受到的 24Bit数据,发出相应的不同占空比的信号,该信号周期在 4MS。如果 DIN 端输入信号为 RESET 信号,芯片将接受到的数据送显示,芯片将在该信号结束后重新接受新的数据,在接受完开始的 24Bit 数据后通过 DOUT 端口转发数据,芯片在没有接受到 RESET 信号前OUTR ,OUTG,OUTB 原输出保持不边,当接受到 80us 以上的低电平 RESET 码后,芯片将接受到 24Bit PWM 数据脉宽输出到 OUTR,OUTG,OUTB 上。
详细参数如下:
1. 电源输入电压:3.5-7.5V
2. OUT R/G/B 恒流值:12mA
3. Top SMD 内部集成高质量外控单线串行级联恒流 IC
4. 控制电 与芯片集成在 SMD 5050 元器件中,构成一个完整的外控像素点,色温效果均匀且一致性 路高
5. 内置数据整形电 ,任何一个像素点收到信号后经过波形整形再输出,保证线 波形畸变 会 加 路 路 不 累
6. 默认上电不亮灯
7. 灰度调节电路(256 级灰度可调)
8. 数据整形:接收完本单元数据自动将后续数据整形输出
9. 内置高精度和高稳定性振荡器
10. 单线数据传输,可无限级联
11. 数据协议兼容性高
12. 数据发送速率:800Kbps

语音模块

HLK-V20原理图

image.png
通过串口接收数据哦,默认115200波特率。
注意:唛头一定要选择好的,否则很不灵敏啊,喇叭差一点没有关系,只要响了就行。
唛头一定选好的!
唛头一定选好的!
唛头一定选好的!

HLK-V20说明

需要定制语音控制命令
我的控制命令如下:
95d9c139935b2ff7f647f2861e2f17d.png
每个模块都需要先下载语音定制指令,具体定制方法可以参考梁山派模块移植手册。
我的定制详见附件,大家可以直接下载使用哦。

电源部分

原理设计

1-通过Type-C进行充电
2-通过TP5400进行充电与升压到5V。为何要进行升压,因为WS2812供电必须在3.6V以上。
3-LDO采用TLV74333转3.3V,因为MCU供电不能超过3.6V。
4-USB插入检测,PB12管脚高电平时有输入。
5-锂电池直接2.54排针接插。
6-SW1开关控制锂电池是否供电。

image.png

TP5400

image.png
image.png

锂电池规格

需要淘宝购买哦,1300mah,如下:
image.png

PCB设计

采用立创EDA进行设计。双层板,1.6mm,FR-4板材。76X76mm



image.png

3D外壳设计

采用立创EDA进行设计。
image.png



底盖:
image.png
顶盖:
image.png



实物图 ![image.png](//image.lceda.cn/pullimage/Z8h3R4Cd3jF6nEjhvpQKftIEb7kghqm0ZQtlI3Vd.png)

面板设计

采用立创EDA进行设计。
image.png

实物如下:
image.png

程序设计

开发工具和环境

采用CubeMX与Keil5结合的方式,使用C语言进行开发。
CubeMX配置如下:
14ce6adcb2841138b3b5252d2801cfc.png

设计思路

1-电量采样,通过ADC进行数据采集。
2-语音模块数据接收
3-指令分析
4-显示效果算法实现
 
HLK-V20模块在梁山派模块开发中均有详细资料。
我的语音定制详见附件。 

关于代码

驱动程序

基本都是常见外设,串口实现等,不再细说。

主程序

各种效果在这里完成,具体代码如下:

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "RGB_SPI.h"
#include "stdlib.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
volatile uint32_t cnt=1;

volatile RGB_InitStruce Set_Color;
volatile uint8_t Flag_Game=0;
volatile uint8_t Num_Color=0;
volatile uint8_t Num_100ms=0;

volatile uint8_t myBrightness=6;
volatile uint16_t adc_value=0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void Roll(void);

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SPI1_Init();
MX_ADC1_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */

	HAL\_TIM\_Base\_Start\_IT\(&htim3\);
	Set\_Color=WHITE;
	Num\_Color=1;
	

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
HAL_ADC_Start(&hadc1);
if(USART_RX_STA&0x8000)
{
uint16_t len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
USART_RX_STA=0;
if(len==1)
{
Flag_Game=0;
switch(USART_RX_BUF[0]){
case 'y'://游戏开关
Flag_Game=1;
Num_100ms=0;
break;
case 'k'://开灯
Num_Color=1;//白色
//Set_Color=WHITE;
break;
case 'g'://关灯
Num_Color=0;
//Set_Color=BLACK;
break;
case 'h'://换颜色
Num_Color++;
if(Num_Color>9) Num_Color=1;
break;
case 'W'://white
Num_Color=1;
break;
case 'R'://red
Num_Color=2;
break;
case 'G'://green
Num_Color=3;
break;
case 'B'://blue
Num_Color=4;
break;
case 'Y'://yellow
Num_Color=5;
break;
case 'V'://violet
Num_Color=6;
break;
case 'C'://cyan
Num_Color=7;
break;
case 'F'://colorful
Num_Color=8;
break;
case 'S'://随机颜色
Num_Color=9;
break;
case 'M'://最大亮度
myBrightness=20;
break;
case 'm'://最小亮度
myBrightness++;
if(myBrightness>20) myBrightness=20;
break;
case '+'://亮度增大
Num_Color=7;
break;
case '-'://亮度减小
myBrightness--;
if(myBrightness<1) myBrightness=1;
break;
case 'z'://亮度适中
myBrightness=5;
break;
default:break;
}
}
// HAL_UART_Transmit(&huart2,USART_RX_BUF,len,10); //发送接收到的数据
// while(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_TC)!=SET); //等待发送结束
}

	if\(Flag\_Game==1\)
	\{
		srand\(uwTick\);
		Num\_100ms\+\+;
		if\(Num\_100ms<=20\)
		\{
			Roll\(\);
		\}else\{
			Num\_100ms=0;
			
			for \(uint8\_t i = 0 ; i < RGB\_NUM ; i\+\+ \)
			\{
				RGB\_Set\_Buf\(i\,BLACK\);
			\}				
			RGB\_Set\_Buf\(rand\(\)%8\,VIOLET\);
			RGB\_Send\_Handler\(RGB\_NUM\);
			Flag\_Game=2;
		\}				
		
	\}
	if\(Flag\_Game==0\)\{								
			switch\(Num\_Color\)\{
			case 1://开灯
				//白色	
				Set\_Color=WHITE;
				break;
			case 0://关灯
				Set\_Color=BLACK;
				break;
			case 2://red
				Set\_Color=RED;
				break;
			case 3://green
				Set\_Color=GREEN;
				break;
			case 4://blue
				Set\_Color=BLUE;
				break;
			case 5://yellow
				Set\_Color=YELLOW;
				break;
			case 6://violet
				Set\_Color=VIOLET;
				break;
			case 7://cyan
				Set\_Color=CYAN;
				break;
			case 8://colorful
					Num\_100ms\+\+;
					RGB\_Set\_Buf\(cnt%8\,WHITE\);
					RGB\_Set\_Buf\(\(cnt\+1\)%8\,VIOLET\);
					RGB\_Set\_Buf\(\(cnt\+2\)%8\,RED\);
					RGB\_Set\_Buf\(\(cnt\+3\)%8\,GREEN\);
					RGB\_Set\_Buf\(\(cnt\+4\)%8\,BLUE\);
					RGB\_Set\_Buf\(\(cnt\+5\)%8\,VIOLET\);
					RGB\_Set\_Buf\(\(cnt\+6\)%8\,CYAN\);
					RGB\_Set\_Buf\(\(cnt\+7\)%8\,YELLOW\);				
				if\(Num\_100ms==50\)
				\{
					Num\_100ms=0;
					RGB\_Send\_Handler\(RGB\_NUM\);
				\}
				break;
			case 9://随机颜色	
				if\(\(cnt%10\)==0\)
				\{
					RGB\_InitStruce temp\_color;
					srand\(uwTick\);
					for \(uint8\_t i = 0 ; i < RGB\_NUM ; i\+\+ \)
					\{
													
						temp\_color\.R=rand\(\)%10;
						temp\_color\.G=rand\(\)%10;
						temp\_color\.B=rand\(\)%10;							
						RGB\_Set\_Buf\(i\,temp\_color\);
					\}
					RGB\_Send\_Handler\(RGB\_NUM\);
				\}
				
				break;
			default:break;									
		\}
		if\(Num\_Color<8\)\{
			for \(uint8\_t i = 0 ; i < 8 ; i\+\+ \)
				\{
					RGB\_Set\_Buf\(i\,Set\_Color\);
				\}			
			RGB\_Send\_Handler\(RGB\_NUM\);	
		\}	
	\}
	if\(HAL\_OK==HAL\_ADC\_PollForConversion\(&hadc1\,10\)\) 
	\{
		adc\_value=HAL\_ADC\_GetValue\(&hadc1\);
		if\(adc\_value<2066\)
		\{
			for \(uint8\_t i = 0 ; i < RGB\_NUM ; i\+\+ \)
			\{
				RGB\_Set\_Buf\(i\,BLACK\);
			\}				
			RGB\_Set\_Buf\(0\,RED\);
			RGB\_Send\_Handler\(RGB\_NUM\);
		\}
	\}
	
		HAL\_SuspendTick\(\);
		HAL\_PWR\_EnterSLEEPMode\(0\,PWR\_SLEEPENTRY\_WFI\);
		HAL\_ResumeTick\(\);
		

}
/* USER CODE END 3 */
}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}

/* USER CODE BEGIN 4 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
cnt++;
}
}

void Roll(void)
{
uint8_t jsq=(cnt%8);
for (uint8_t i = 0 ; i < 8 ; i++ )
{
RGB_Set_Buf(i,BLACK);
}
switch(jsq)
{
case 0:
RGB_Set_Buf(jsq,RED);RGB_Send_Handler(RGB_NUM);
break;
case 1:
RGB_Set_Buf(jsq,GREEN);RGB_Send_Handler(RGB_NUM);
break;
case 2:
RGB_Set_Buf(jsq,BLUE);RGB_Send_Handler(RGB_NUM);
break;
case 3:
RGB_Set_Buf(jsq,WHITE);RGB_Send_Handler(RGB_NUM);
break;
case 4:
RGB_Set_Buf(jsq,CYAN);RGB_Send_Handler(RGB_NUM);
break;
case 5:
RGB_Set_Buf(jsq,VIOLET);RGB_Send_Handler(RGB_NUM);
break;
case 6:
RGB_Set_Buf(jsq,YELLOW);RGB_Send_Handler(RGB_NUM);
break;
case 7:
RGB_Set_Buf(jsq,CYAN);RGB_Send_Handler(RGB_NUM);
break;
default:break;
}
}

/* USER CODE END 4 */

/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

附件代码可以直接使用哦。
 
 

效果演示



由于文件大小限制,可以打开如下链接查看。 [https://www.bilibili.com/video/BV1Gm411C7Bj/?vd_source=24f1befd6441a33d7b240715cb07c7b5](https://www.bilibili.com/video/BV1Gm411C7Bj/?vd_source=24f1befd6441a33d7b240715cb07c7b5)


设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
语音指令下载.zip
7
2
MCU代码.rar
5
3
语音控制.mp4
1
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航