Proximity Display Solution
基于接近感应的自动化系统,具备实时距离显示与继电器控制功能
你将学到和构建的内容
简介
Proximity Display Solution 集成了 LightRanger 3 Click、Relay 3 Click 和 8x8 G Click,构建了一个基于实时接近感应的自动化系统,具备距离可视化反馈和继电器控制功能。该方案非常适用于工业自动化、智能家居系统以及交互式显示应用,通过测量物体距离,将结果显示在 LED 点阵屏上,并根据预设阈值控制继电器的开关。如果测得的距离小于或等于 100mm,两个继电器将开启;否则保持关闭状态。系统对传感器数据进行平均处理以提升精度,并通过 UART 输出日志,配合直观的显示界面,确保操作响应快速且稳定,同时保持硬件结构的简洁性。
mikroBUS 1
LightRanger 3 Click
LightRanger 3 Click 是一款高精度测距 Click 板™,基于 ToF(飞行时间)测量原理。它搭载了 RF Digital 公司的 Simblee™ 兼容 RFD77402 测距模块,该模块集成完整的测量系统,使用非常简单,仅通过 I2C 接口和 INT 引脚与主控 MCU 进行通信。其核心组件包括 VCSEL(垂直腔面发射激光器),用于发射 850nm 波长的窄带红外调制光束,以及接收传感器,用于检测反射光。该模块可测量距离最长可达 2000mm,测量精度可达 ±10%。此外,该设备符合 Class 1 激光产品标准,在不可见红外光谱范围内运行,确保安全性。
mikroBUS 2
Relay 3 Click
Relay 3 Click 是一款双继电器 Click 板™,配备两个单刀双掷(SPDT)继电器,可由主控微控制器(MCU)的输出引脚控制。它提供了一种优雅且便捷的解决方案,可用于控制各种电源应用。该 Click 板™ 采用两个 SRD-5VDC-SL-C 继电器,这些密封式继电器需要 5V 线圈电压,工作时功耗约为 0.4W。它们能够切换高达 28VDC 的负载电压,并可承载高达 7A 的电流。Relay 3 Click 可广泛应用于基于 PLC(可编程逻辑控制器)的系统、远程开关控制以及其他类似应用场景。
mikroBUS 3
8x8 G Click
8x8 G Click 是一款 64 LED 矩阵显示 Click 板™,由 8 行 × 8 列的 SMD LED 组成。它具有 16 级数字亮度控制,可独立控制显示矩阵中的每个 LED,并在上电时自动清空显示以消除故障闪烁。此外,它只需使用一个电阻即可控制所有 LED 的电流,从而简化了电路设计。8x8 G Click 采用高速 SPI 通信协议,确保快速的显示响应,无延迟。
功能概述
开发板
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”替换为要显示的参数。

软件支持
库描述
Proximity Display Solution 使用 NECTO Studio 开发,确保兼容 mikroSDK 的开源库和工具。该解决方案采用即插即用的设计,支持快速实施和测试,并与所有配备 mikroBUS™ 插座的开发板、入门套件和 mikromedia 板完全兼容。
示例描述
Proximity Display Solution 应用结合使用 LightRanger 3 Click、Relay 3 Click 和 8x8 G Click 来测量物体距离,并根据测量结果控制继电器和显示屏。为减少传感器噪声,系统对多次测量结果进行平均处理,测得的距离通过 8x8 G Click 显示,系统事件和距离数值通过 UART 进行日志记录。
关键功能:
initialize_light_ranger
- 初始化 LightRanger 3 Click 以进行距离测量。如果初始化失败,则记录错误并终止程序执行。initialize_relay_3
- 初始化 Relay 3 Click,用于控制外部设备initialize_8x8_g
- 初始化 8x8 G Click,用于显示距离数据。display_distance_on_8x8_g
- 将测量得到的距离转换并显示在 8x8 G Click 上。clear_display_on_8x8_g
- 清除 8x8 G Click 的显示内容。case_both_relays
- 根据距离阈值控制两个继电器的开关状态。measure_and_log_distance
- 捕获一次距离读数并通过 UART 记录。
应用初始化
初始化过程包括设置 UART 日志、配置所有 Click 板,并验证硬件是否就绪。如果初始化失败,系统将记录错误并终止执行。
应用任务
主应用循环持续执行以下任务:
1.进行多次距离测量,计算平均值,并通过 UART 记录结果。
2.在 8x8 G Click 上显示测量的距离,或在需要时显示提示信息。
3.根据平均距离控制继电器:若小于或等于 100mm,两个继电器开启;若超过 100mm,则两个继电器关闭。
4.记录距离测量结果和继电器状态。
开源
代码示例
完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio。 应用程序代码也可以在MIKROE的GitHub账户中找到。
/*
* Solution Name: Distance-Based Relay & Display Control
*
* Description:
* This embedded application uses LightRanger 3 Click, Relay 3 Click,
* and 8x8 G Click to measure the distance to an object and control relays
* and a display based on the measured distance.
*
* - If the average distance is <= 100 mm: Both relays turn ON.
* - If the average distance is > 100 mm: Both relays turn OFF.
*
* Distance measurements are averaged over multiple readings to reduce sensor noise
* and improve accuracy. The measured distance is displayed on the 8x8 G Click,
* and relay states are toggled automatically based on distance thresholds.
*
* The system utilizes the following Click boards:
* - LightRanger 3 Click: Measures the distance to a nearby object using
* a laser sensor.
* - Relay 3 Click: Controls external devices based on distance thresholds.
* - 8x8 G Click: Displays the measured distance or clears the screen
* when no action is needed.
*
* The `application_init` function initializes the logger and all Click boards,
* ensuring proper startup conditions. Any initialization failure is logged,
* and the system halts.
*
* The `application_task` function continuously measures the distance,
* calculates the average distance, updates the display, and toggles the relays
* based on the distance threshold.
*
* Hardware Setup:
* - MIKROBUS_1: 8x8 G Click
* - MIKROBUS_2: Relay 3 Click
* - MIKROBUS_3: LightRanger 3 Click
*
* Key Features:
* - Continuous distance monitoring with real-time relay control.
* - Multi-sample averaging to reduce sensor reading noise.
* - Distance display with automatic clearing when no action is needed.
* - UART logging for measurement data and system events.
* - Automatic relay switching based on distance threshold.
*
* 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: 2025
*/
// ------------------------------------------------------------------- INCLUDES
#include "log.h"
#include "board.h"
#include "c8x8g.h"
#include "relay3.h"
#include "lightranger3.h"
#include "conversions.h"
// ------------------------------------------------------------------ VARIABLES
static log_t logger;
static c8x8g_t c8x8g;
static relay3_t relay3;
static lightranger3_t lightranger3;
static int case_both_relays_switch = 0;
// ---------------------------------------------- PRIVATE FUNCTION DECLARATIONS
/**
* @brief Toggle Both Relays On/Off
*
* This function toggles the state of both relays connected to the Relay 3 Click board.
* It uses a state switch (`case_both_relays_switch`) to alternate between turning both
* relays ON and OFF.
*
* - When `case_both_relays_switch` is `0`, both relays are turned ON, and a message is
* logged via UART.
* - When `case_both_relays_switch` is `1`, both relays are turned OFF, and a corresponding
* message is logged.
*
* The function updates the `case_both_relays_switch` variable to track the current state,
* flipping its value between `0` and `1` on each call.
*
* This function can be used in scenarios where relays need to be toggled at regular intervals
* or based on specific conditions (e.g., distance threshold crossing).
*
* @note The function relies on a global variable `case_both_relays_switch` to manage state.
*/
static void case_both_relays ( );
// ----------------------------------------------- PUBLIC FUNCTION DECLARATIONS
/**
* @brief Initializes the LightRanger 3 Click board.
*
* Configures the LightRanger 3 Click board and performs device initialization.
* If the sensor fails to initialize, the function logs an error and halts
* execution.
*
* @note The LightRanger 3 Click is connected to MIKROBUS_4.
*/
void initialize_light_ranger( void );
/**
* @brief Initializes the Relay 3 Click board.
*
* Configures the Relay 3 Click board and performs device initialization.
* If the Relay fails to initialize, the function logs an error and halts
* execution.
*
* @note The Relay 3 Click is connected to MIKROBUS_3.
*/
void initialize_relay_3( void );
/**
* @brief Initializes the 8x8 G Click board.
*
* Configures the 8x8 G Click board and performs device initialization.
* If the 8x8 G Click fails to initialize, the function logs an error and halts
* execution.
*
* @note The 8x8 G Click is connected to MIKROBUS_2.
*/
void initialize_8x8_g( void );
/**
* @brief Display Distance on 8x8 G Click.
*
* Converts the measured distance to a string and displays it on the 8x8 G Click board.
* The distance is shown in millimeters (e.g., "123mm").
*
* @param[in] distance The measured distance value in millimeters.
*/
void display_distance_on_8x8_g( uint16_t distance );
/**
* @brief Clears the display on 8x8 G Click.
*
* Clears the display and shows a message.
*/
void clear_display_on_8x8_g( void );
/**
* @brief Measures and logs the distance using the LightRanger 3 Click.
*
* Takes a single distance measurement, retrieves the distance value,
* and logs it via UART. This function is useful for quick,
* real-time distance readings.
*/
void measure_and_log_distance( void );
// ------------------------------------------------------ APPLICATION FUNCTIONS
static void case_both_relays ( )
{
if ( case_both_relays_switch == 0 )
{
relay3_relay_on( &relay3, RELAY3_BOTH_RELAYS );
log_printf( &logger, " Both relays ON. \r\n" );
case_both_relays_switch++;
}
else if ( case_both_relays_switch == 1 )
{
relay3_relay_off( &relay3, RELAY3_BOTH_RELAYS );
log_printf( &logger, " Both relays OFF. \r\n" );
case_both_relays_switch--;
}
}
void application_init( void )
{
log_cfg_t log_cfg;
// Logger initialization
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, "Application Init" );
// initialize_button_play();
initialize_light_ranger();
initialize_relay_3();
initialize_8x8_g();
log_info( &logger, "Initialization Complete, Starting Application Task" );
}
void initialize_light_ranger( void )
{
lightranger3_cfg_t lightranger3_cfg;
lightranger3_cfg_setup( &lightranger3_cfg );
LIGHTRANGER3_MAP_MIKROBUS( lightranger3_cfg, MIKROBUS_3 );
lightranger3_init( &lightranger3, &lightranger3_cfg );
if ( lightranger3_device_init( &lightranger3 ) != 0 )
{
log_error( &logger, "LightRanger Click initialization failed!" );
for ( ; ; ); // Halt execution
}
log_info( &logger, "LightRanger Click initialized successfully." );
}
void initialize_relay_3( void ) {
relay3_cfg_t relay3_cfg;
relay3_cfg_setup( &relay3_cfg );
RELAY3_MAP_MIKROBUS( relay3_cfg, MIKROBUS_2 );
relay3_init( &relay3, &relay3_cfg );
}
void initialize_8x8_g( void ) {
c8x8g_cfg_t c8x8g_cfg;
c8x8g_cfg_setup( &c8x8g_cfg );
C8X8G_MAP_MIKROBUS( c8x8g_cfg, MIKROBUS_1 );
err_t init_flag = c8x8g_init( &c8x8g, &c8x8g_cfg );
if ( init_flag == SPI_MASTER_ERROR ) {
log_info( &logger, " Application Init Error. " );
log_info( &logger, " Please, run program again... " );
for ( ; ; );
}
c8x8g_default_cfg ( &c8x8g );
}
void display_distance_on_8x8_g( uint16_t distance )
{
char distance_str[ 5 ];
uint16_to_str(distance, distance_str);
// Show distance in mm (up to 9999 mm)
c8x8g_display_string( &c8x8g, distance_str );
}
void clear_display_on_8x8_g( void )
{
c8x8g_display_byte( &c8x8g, ' ' );
}
void application_task( void )
{
// Continuously measure distance
uint32_t distance_sum = 0;
uint8_t num_measurements = 5;
for ( uint8_t i = 0; i < num_measurements; i++ )
{
lightranger3_take_single_measurement( &lightranger3 );
distance_sum += lightranger3_get_distance( &lightranger3 );
Delay_ms( 100 ); // Small delay between measurements
}
uint16_t average_distance = ( uint16_t )( distance_sum / num_measurements );
log_printf( &logger, "Average Distance: %u mm\r\n", average_distance );
// Display the distance on 8x8 G Click
display_distance_on_8x8_g( average_distance );
// Control relays based on distance threshold
if ( average_distance <= 100 && case_both_relays_switch == 0 )
{
log_printf( &logger, "Distance <= 100 mm! Turning both relays ON.\r\n" );
case_both_relays();
}
else if ( average_distance > 100 && case_both_relays_switch == 1 )
{
log_printf( &logger, "Distance > 100 mm! Turning both relays OFF.\r\n" );
case_both_relays();
}
else {
// Clear display.
clear_display_on_8x8_g();
}
}
void measure_and_log_distance( void )
{
lightranger3_take_single_measurement( &lightranger3 );
uint16_t distance = lightranger3_get_distance( &lightranger3 );
log_printf( &logger, "Distance: %u mm\r\n", distance );
}
int main( void )
{
#ifdef PREINIT_SUPPORTED
preinit();
#endif
application_init();
while ( 1 )
{
application_task();
}
return 0;
}
额外支持
资源
类别:Human-Machine Interface (HMI)