Switch-Triggered Voice Playback Solution
通过旋转开关驱动的语音播放系统,实现语音反馈与直观导航功能
你将学到和构建的内容
简介
Switch-Triggered Voice Playback 解决方案集成了 Rotary Switch Click 和 Speaker 2 Click,构建了一个直观的分区语音反馈系统。该方案专为菜单导航、工业控制面板、用户界面及辅助功能应用而设计,将旋转开关的位置与预设语音提示进行映射,使用户在旋转开关时能够实时接收到相应的语音提示。通过持续监测开关位置并实时播放相应音频文件,该系统为需要动手操作与语音反馈的交互应用提供了高响应性和良好的用户体验。
mikroBUS 1
Rotary Switch Click
Rotary Switch Click 是一款紧凑型附加板,适用于需要精确旋转输入的应用。该板基于 Same Sky 的 RDS6-16S-1065-1-SMT,这是一款具有 16 个档位的表面贴装型旋转 DIP 开关,采用凹槽帽设计。该开关支持 360 度连续旋转,具有 2.54mm 引脚间距、接触电阻 80mΩ 和最大操作扭矩 700gf*cm,确保多达 10,000 步的稳定操作。该板支持 MIKROE 创新的 Click Snap 设计,使旋转开关在断开主板时仍可独立运行,为各种应用实现提供更大灵活性。Rotary Switch Click 通过德州仪器的 TCA9536(4 位 I2C I/O 扩展器)与主 MCU 通信,从而简化了旋转开关状态的检测和读取过程。该模块非常适合工业设备、消费电子和汽车系统,在需要模式切换和用户自定义配置的高要求环境中,提供了多功能、耐用的旋转输入解决方案。
mikroBUS 2
Speaker 2 Click
Speaker 2 Click 是一款紧凑型附加板,适用于高品质音频播放和语音提示应用。该板采用 Nuvoton 的 ISD2360 三通道数字 ChipCorder® 芯片,集成了非易失性闪存用于音频存储与回放。ISD2360 支持最长达 64 秒的语音存储,具备数字解压、独立多通道播放功能,并内建 Class D 扬声器驱动器,可直接驱动板载的 AS01508AO-SC-R 扬声器。该模块通过标准 SPI 接口与主控 MCU 通信,具备可配置的 I/O 引脚和内建程序验证机制,在外部组件极少的情况下确保系统运行可靠。板上还提供可切换的逻辑电压选择(3.3V 或 5V)以及用于独立数字供电的跳线设置。Speaker 2 Click 非常适合嵌入式系统中需要清晰语音提示、音效或预录消息的场景,如自动化系统、消费类电子产品和工业控制设备。
功能概述
开发板
Clicker 4 for STM32F4 是一款紧凑型开发板,专为快速构建自定义设备而设计。它配备 STM32F407VGT6 MCU、四个 mikroBUS™ 插座(用于 Click board™ 连接)、电源管理等功能,使其成为快速应用开发的理想选择。核心采用 STM32F407VGT6 MCU,该芯片基于 Arm® Cortex®-M4 32 位处理器,运行频率高达 168 MHz,提供充足的计算能力以满足高负载任务需求。除了两个 1x20 排针接口外,四个 mikroBUS™ 插座可支持庞大且不断增长的 Click boards™ 生态系统。开发板上清晰标记的功能区域提供直观、易用的界面,加快开发进程。Clicker 4 不仅能加速原型设计,还可直接集成到项目中,无需额外的硬件修改。四个 4.2mm(0.165”)的安装孔位于角落,便于使用螺丝固定,实现简便安装。
微控制器概述
MCU卡片 / MCU

建筑
ARM Cortex-M4
MCU 内存 (KB)
10
硅供应商
STMicroelectronics
引脚数
100
RAM (字节)
100
一步一步来
项目组装
实时跟踪您的结果
应用程序输出
1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程。

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持
库描述
Switch-Triggered Voice Playback Solution 使用 NECTO Studio 开发,确保兼容 mikroSDK 的开源库和工具。该解决方案采用即插即用的设计,支持快速实施和测试,并与所有配备 mikroBUS™ 插座的开发板、入门套件和 mikromedia 板完全兼容。
示例描述
Switch-Triggered Voice Playback 解决方案通过集成 Rotary Switch Click 和 Speaker 2 Click,构建一个基于旋转开关位置动态播放预录语音提示的系统。Rotary Switch Click 读取旋转编码器的数值,并将当前位置映射为逻辑语音区域。每个区域对应一个预设语音文件,当用户旋转进入新的区域时,Speaker 2 Click 播放对应语音,实现语音引导。该方案适用于菜单导航、工业控制面板、用户界面和无障碍辅助应用,提供基于开关输入的语音反馈。
关键功能:
rotaryswitch_init
- 初始化 Rotary Switch Click,用于读取编码器位置。rotaryswitch_default_cfg
- 应用默认配置,以实现稳定的开关读取。rotaryswitch_get_position
- 读取当前旋转位置值(0–255)。speaker2_init
- 初始化 Speaker 2 Click,用于语音播放。speaker2_default_cfg
- 配置默认语音播放设置。speaker2_play_voice
- 播放与当前旋转区域关联的预设语音提示。log_printf
- 通过 UART 打印旋转区域与语音播放状态,用于调试和监控。
应用初始化
初始化 UART 日志功能以获取实时反馈。接着初始化并配置 Rotary Switch Click,使其可读取从 0 到 255 的旋转位置值。然后初始化 Speaker 2 Click,使其支持多段语音提示播放功能。如果任何外设初始化失败,系统将记录错误并进入安全停机状态。
应用任务
主应用任务在一个连续循环中运行,定期读取旋转开关的当前位置。根据读取到的旋转值(范围为 0 到 255),将其划分为七个等分区域并计算当前语音区域。如果检测到当前区域与上次记录的区域不同,系统将通过 UART 记录当前旋转位置与激活区域,并使用 Speaker 2 Click 播放对应的语音提示。播放完成后系统记录播放命令是否成功执行。该循环每 20 毫秒执行一次,确保应用程序具有高度响应性与实时性。
开源
代码示例
完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio。 应用程序代码也可以在MIKROE的GitHub账户中找到。
/*
* Solution Name: Switch-Triggered Voice Playback Solution
*
* Description:
* This embedded application maps rotary switch positions to pre-defined
* voice prompts using the Rotary Switch Click and Speaker 2 Click boards.
* As the user rotates the switch, the system dynamically triggers playback
* of corresponding voice files via the onboard speaker.
*
* The system utilizes the following Click boards:
* - Rotary Switch Click: A 256-position rotary encoder used to determine
* the current user-selected value or range.
* - Speaker 2 Click: Plays pre-recorded voice prompts based on the selected
* rotary switch position.
*
* The `application_init` function initializes both Click boards and sets up
* the UART logger for status tracking and debugging.
*
* The `application_task` function continuously reads the rotary switch
* position and maps it to one of seven logical zones using configurable
* macro definitions. Each zone is assigned to a specific voice file, played
* back via Speaker 2 Click. The mapping ensures flexibility and clean logic
* through macros like `ROTARY_SWITCH_MAX_RANGE`, `SPEAKER_2_NUM_SOUNDS`,
* and `SPEAKER_2_ZONE_WIDTH`.
*
* Hardware Setup:
* - MIKROBUS_1: Rotary Switch Click (Rotary input)
* - MIKROBUS_2: Speaker 2 Click (Voice playback)
*
* Key Features:
* - Rotary position-to-voice mapping via modular macros
* - Configurable number of voice zones and resolution
* - Dynamic playback of pre-recorded voice prompts
* - UART-based logging for rotary position and playback status
*
* Development Environment:
* - [NECTO Studio](https://www.mikroe.com/necto)
* - [mikroSDK v2.0](https://www.mikroe.com/mikrosdk) framework
* - MIKROE [Click boards](https://www.mikroe.com/click-boards) Add-ons
*
* Author: Branko Jaksic
* Date: April, 2025
*/
// ------------------------------------------------------------------- INCLUDES
#include "log.h"
#include "board.h"
#include "speaker2.h"
#include "rotaryswitch.h"
// ------------------------------------------------------------- PRIVATE MACROS
#define ROTARY_SWITCH_MAX_RANGE 256
#define SPEAKER_2_NUM_SOUNDS 7
#define SPEAKER_2_ZONE_WIDTH ( ROTARY_SWITCH_MAX_RANGE / SPEAKER_2_NUM_SOUNDS )
// ------------------------------------------------------------------ VARIABLES
static log_t logger;
static speaker2_t speaker2;
static rotaryswitch_t rotaryswitch;
// ----------------------------------------------------- USER-DEFINED CONSTANTS
static const uint16_t speaker2_voice_map[SPEAKER_2_NUM_SOUNDS] = {
SPEAKER2_VP9_ONE,
SPEAKER2_VP10_TWO,
SPEAKER2_VP11_THREE,
SPEAKER2_VP12_FOUR,
SPEAKER2_VP13_FIVE,
SPEAKER2_VP14_SIX,
SPEAKER2_VP15_FAST_BEEP
};
// ------------------------------------------------------ APPLICATION FUNCTIONS
void application_init ( void )
{
log_cfg_t log_cfg; /**< Logger config object. */
speaker2_cfg_t speaker2_cfg; /**< Click config object. */
rotaryswitch_cfg_t rotaryswitch_cfg; /**< Click config object. */
/**
* Logger initialization.
* Default baud rate: 115200
* Default log level: LOG_LEVEL_DEBUG
* @note If USB_UART_RX and USB_UART_TX
* are defined as HAL_PIN_NC, you will
* need to define them manually for log to work.
* See @b LOG_MAP_USB_UART macro definition for detailed explanation.
*/
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, " Application Init " );
// Click initialization.
rotaryswitch_cfg_setup( &rotaryswitch_cfg );
ROTARYSWITCH_MAP_MIKROBUS( rotaryswitch_cfg, MIKROBUS_1 );
if ( I2C_MASTER_ERROR == rotaryswitch_init( &rotaryswitch,
&rotaryswitch_cfg ) )
{
log_error( &logger, " Communication init." );
for ( ; ; );
}
if ( ROTARYSWITCH_ERROR == rotaryswitch_default_cfg ( &rotaryswitch ) )
{
log_error( &logger, " Default configuration." );
for ( ; ; );
}
// Click initialization.
speaker2_cfg_setup( &speaker2_cfg );
SPEAKER2_MAP_MIKROBUS( speaker2_cfg, MIKROBUS_2 );
if ( SPI_MASTER_ERROR == speaker2_init( &speaker2, &speaker2_cfg ) )
{
log_error( &logger, " Communication init." );
for ( ; ; );
}
if ( SPEAKER2_ERROR == speaker2_default_cfg ( &speaker2 ) )
{
log_error( &logger, " Default configuration." );
for ( ; ; );
}
log_info( &logger, " Application Task " );
}
void application_task ( void )
{
static uint8_t prev_rotary_position = 0xFF; // Initially invalid
uint8_t rotary_position = 0;
if ( ROTARYSWITCH_OK == rotaryswitch_get_position( &rotaryswitch,
&rotary_position ) )
{
uint8_t current_zone = rotary_position / SPEAKER_2_ZONE_WIDTH;
if ( current_zone >= SPEAKER_2_NUM_SOUNDS )
{
current_zone = SPEAKER_2_NUM_SOUNDS - 1;
}
// Calculate current zone boundaries
uint8_t zone_min = current_zone * SPEAKER_2_ZONE_WIDTH;
uint8_t zone_max = ( ( current_zone + 1 ) * SPEAKER_2_ZONE_WIDTH ) - 1;
if ( current_zone == SPEAKER_2_NUM_SOUNDS - 1 )
{
zone_max = ROTARY_SWITCH_MAX_RANGE - 1;
}
// Check if rotary moved into a NEW range (new zone boundaries)
if ( ( rotary_position >= zone_min && rotary_position <= zone_max ) &&
!( prev_rotary_position >= zone_min &&
prev_rotary_position <= zone_max ) )
{
prev_rotary_position = rotary_position;
log_printf( &logger, " Rotary position: %u -> Zone %u (%u - %u)\r\n",
rotary_position, current_zone, zone_min, zone_max );
if ( SPEAKER2_OK == speaker2_play_voice( &speaker2,
speaker2_voice_map[ current_zone ] ) )
{
log_printf( &logger, " Voice played: %u\r\n\n", current_zone );
}
else
{
log_error( &logger,
" Failed to play voice for zone %u\r\n\n",
current_zone );
}
}
}
Delay_ms( 20 );
}
int main ( void )
{
/* Do not remove this line or clock might not be set correctly. */
#ifdef PREINIT_SUPPORTED
preinit();
#endif
application_init( );
for ( ; ; )
{
application_task( );
}
return 0;
}
// ------------------------------------------------------------------------ END
额外支持
资源
类别:Human-Machine Interface (HMI)