LightRanger 3 Click with Clicker 4 for STM32F4

Published Mar 24, 2025

Click board™

LightRanger 3 Click
Relay 3 Click
8x8 G Click

Dev. board

Clicker 4 for STM32F4

Compiler

NECTO Studio

MCU

STM32F407VGT6

Proximity Display Solution

Proximity-based automation with real-time distance display and relay control

What you'll learn and build

Intro

The Proximity Display Solution integrates LightRanger 3 Click, Relay 3 Click, and 8x8 G Click to deliver a real-time proximity-based automation system with visual distance feedback and relay control. Ideal for industrial automation, smart home systems, and interactive displays, this solution measures object distance, displays the value on an LED matrix, and toggles relays based on a predefined threshold. If the measured distance is 100mm or less, both relays are turned ON; otherwise, they remain OFF. With averaged sensor readings to improve accuracy, UART logging, and intuitive display output, this system ensures responsive and reliable operation with minimal hardware complexity.

mikroBUS 1

LightRanger 3 Click

LightRanger 3 Click is an accurate distance measurement Click board™ based on a ToF (Time of Flight) measurement principle. The Simblee™ enabled RFD77402 rangefinder module from RF Digital is a complete measurement stack on the chip. It is surprisingly easy to work with, as this highly integrated range finder module exposes the only I2C interface and INT pin to the host controller. It features the VCSEL, a Vertical Cavity Surface Emitting Laser, used to emit a narrow band of a harmless modulated light beam in the IR range (850 nm), and a receive sensor, which can detect the reflected light. It can measure distances up to 2000mm, with up to 10% accuracy. The device is rated Class 1 LASER product, operating in the IR (invisible) spectrum range.

LightRanger 3 Click front-background image

mikroBUS 2

Relay 3 Click

Relay 3 Click is a dual relay Click board, featuring two single-pole double-throw relays which can be operated by output pins of the host microcontroller (MCU). It offers an elegant and easy solution for controlling a wide range of power applications. Two SRD-5VDC-SL-C relays used on this Click board™ are hermetically sealed relays which require 5V across their coils while consuming about 0.4W while active. They allow up to 28VDC across the connected load, while conducting up to 7A. Relay 3 click can be used in various PLC-based systems, as a remote ON/OFF switch, and other similar applications.

Relay 3 Click front-background image

mikroBUS 3

8x8 G Click

8x8 G Click is a 64 LED matrix display Click board™, composed of SMD LEDs organized in 8 rows by 8 columns. It has a digital brightness control in 16 steps, it can control every LED in the display matrix independently, it blanks the display on power up to eliminate glitches and it requires a single resistor to control the current through all the LEDs at once, which simplifies the design. 8x8 G click uses a fast SPI communication protocol, allowing fast display response and no lag.

8x8 G Click front-background image

Features overview

Development board

Clicker 4 for STM32F4 is a compact development board designed for quickly building custom gadgets. It features an STM32F407VGT6 MCU, four mikroBUS™ sockets for Click board™ connectivity, power management, and more—making it ideal for rapid application development. At its core, the STM32F407VGT6 MCU, powered by an Arm® Cortex®-M4 32-bit processor running up to 168 MHz, ensures ample processing power for demanding tasks. Alongside two 1x20 pin headers, its four mikroBUS™ sockets provide access to a vast and growing range of Click boards™. Clearly marked sections offer an intuitive, user-friendly interface for faster development. Clicker 4 not only accelerates prototyping but can also be integrated directly into projects without additional hardware modifications. Four 4.2mm (0.165”) mounting holes at each corner enable easy installation with screws.

Clicker 4 for STM32F4 front image

Microcontroller Overview

MCU Card / MCU

default

Architecture

ARM Cortex-M4

MCU Memory (KB)

10

Silicon Vendor

STMicroelectronics

Pin count

100

RAM (Bytes)

100

Step by step

Project assembly

Clicker 4 for STM32F4 front image hardware assembly

Start by selecting your development board - Clicker 4 for STM32F4

Clicker 4 for STM32F4 front image hardware assembly
LTE IoT 5 Click front-background image hardware assembly
Calypso Click front-background image hardware assembly
Thermo 21 Click front-background image hardware assembly
Board mapper by product7 hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
Necto image step 5 hardware assembly
NECTO Output Selection Step Image hardware assembly
Necto image step 6 hardware assembly
Clicker 4 for STM32F4 HA MCU Step hardware assembly
Necto image step 8 hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Necto PreFlash Image hardware assembly

Track your results in real time

Application Output

1. Application Output - In Debug mode, the 'Application Output' window enables real-time data monitoring, offering direct insight into execution results. Ensure proper data display by configuring the environment correctly using the provided tutorial.

2. UART Terminal - Use the UART Terminal to monitor data transmission via a USB to UART converter, allowing direct communication between the Click board™ and your development system. Configure the baud rate and other serial settings according to your project's requirements to ensure proper functionality. For step-by-step setup instructions, refer to the provided tutorial.

3. Plot Output - The Plot feature offers a powerful way to visualize real-time sensor data, enabling trend analysis, debugging, and comparison of multiple data points. To set it up correctly, follow the provided tutorial, which includes a step-by-step example of using the Plot feature to display Click board™ readings. To use the Plot feature in your code, use the function: plot(*insert_graph_name*, variable_name);. This is a general format, and it is up to the user to replace 'insert_graph_name' with the actual graph name and 'variable_name' with the parameter to be displayed.

Software Support

Library Description

Proximity Display Solution is developed using the NECTO Studio, ensuring compatibility with mikroSDK's open-source libraries and tools. Designed for plug-and-play implementation and testing, this solution is fully compatible with all development, starter, and mikromedia boards featuring a mikroBUS™ socket.

Example Description
The Proximity Display Solution application is using 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. Distance measurements are averaged over multiple readings to reduce sensor noise, and the measured distance is displayed on the 8x8 G Click. System events and distance values are logged via UART.

Key functions:

  • initialize_light_ranger - Initializes the LightRanger 3 Click for distance measurement. Logs an error and halts execution if initialization fails.

  • initialize_relay_3 - Initializes the Relay 3 Click for controlling external devices.

  • initialize_8x8_g - Initializes the 8x8 G Click for displaying distance measurements.

  • display_distance_on_8x8_g - Converts and displays the measured distance on the 8x8 G Click.

  • clear_display_on_8x8_g - Clears the 8x8 G Click display.

  • case_both_relays - Toggles both relays ON or OFF based on the distance threshold.

  • measure_and_log_distance - Captures a single distance reading and logs it via UART.

Application Init
The initialization sequence sets up UART logging, configures all Click boards, and verifies hardware readiness. If an error occurs during initialization, an error message is logged, and execution halts.

Application Task
The main application loop continuously performs the following tasks:

1. Takes multiple distance readings, averages them, and logs the result via UART.

2. Updates the 8x8 G Click display with the measured distance or shows a release message.

3. Controls relays based on the average distance: turns both relays ON if the average distance is 100mm or less; turns both relays OFF if the average distance goes above 100mm.

4. Logs distance measurements and relay states.

Open Source

Code example

The complete application code and a ready-to-use project are available through the NECTO Studio Package Manager for direct installation in the NECTO Studio. The application code can also be found on the MIKROE GitHub account.

/*
 * 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;
}

Additional Support

Resources

Love this project?

'Buy This Kit' button takes you directly to the shopping cart where you can easily add or remove products.