yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
STM32-BoardCar📖
0. Get started quickly
  • 0.ReadMe
  • 1. Installation Instructions
  • 2. Version configuration
  • 3. Smart car installation video
  • 4. Precautions for use
1. Introduction to STM32 development board
  • 1. Learn about STM32
  • 2. Introduction to STM32 development board
  • 3. Development board pin assignment
  • 4. Introduction to HAL library and LL library
2. Setting up and using the development environment
  • 1. Common development tools
  • 2. STM32CubeMX Install - Use
  • 3. STM32CubeIDE Install - Use
  • 4. Common Driver Installation
  • 5. Program download and simulation
  • 6. Engineering experience and migration
3. Development board basic tutorial
  • 1. RGB searchlight (GPIO)
  • 2. Buzzer control (GPIO)
  • 3. Button control (EXTI)
  • 4. Serial communication (UASRT)
  • 5. Voltage detection (ADC)
  • 6. Internal temperature sensor(ADC)
  • 7. Independent watchdog(IWDG)
  • 8. Window watchdog(WWDG)
  • 9. Basic timer (TIM6)
  • 10. Universal Timer (TIM3)
  • 11. Advanced timers (TIM1)
  • 12. I2C Communication (IIC)
  • 13. Off-chip Flash (SPI)
  • 14. On-chip Flash (Flash)
  • 15. DMA:USART
  • 16. DMA:SPI
  • 17. DMA:I2C
  • 18. USB communication
  • 19. USB analog U disk
  • 20. FreeRTOS
4. Car expansion tutorial
  • 1. Servo control
  • 2. Basic use of ultrasonic steering gear gimbal
  • 3. Motor control
  • 4. OLED display light sensitivity value
  • 5. Infrared sensor
  • 6. Four-way tracking module
  • 7. Infrared remote control
  • 8. Ultrasonic ranging
  • 9. PS2 controller test
  • 10.K230 Vision Module
  • 11.AI voice interaction integration module
5. Robot car tutorials
  • 1. Car line patrol
  • 2. Ultrasonic follow
  • 3. Ultrasonic obstacle avoidance
  • 4. Ultrasonic obstacle avoidance (servo gimbal version)
  • 5. Infrared sensor obstacle avoidance
  • 6. Infrared remote control
  • 7. PS2 handle remote control
  • 8.K230 face tracking on PTZ
  • 9.K230 color tracking
  • 10.K230 Color Line Patrol
  • 11.K230 QR code command
  • 12.K230 machine code tracking
  • 13.K230 road sign indication action (voice)
  • 14.K230 color response (voice)
  • 15.K230 gesture control (voice)
  • 16.K230 Rock-Paper-Scissors Game (Voice)
6. Operation video
  • 1-How to install STM32CubeIDE software
  • 2-How to create Demo project
  • 3-How to download code into STM32 robot car
  • 4-How to open and compile a code file for STM32
  • 5-About IR control and Charge battery
Download
  • Code
  • SCH
  • Software File
  • STM32 Chip DataSheet
  • Installation manual
Download ZIP

Welcome to STM32-BoardCar repository

13.K230 road sign indication action (voice)

k230 road sign indication action

k230 road sign indication action1. Software-hardware environment2. Brief principle1. Hardware schematic2. Physical connection diagram3. Communication protocol3. Partial code analysis4. Experimental phenomenonRoad sign image

This tutorial is a comprehensive experiment combining multiple peripherals. You can first understand a single peripheral and then conduct this experiment.

1. Software-hardware environment

  • STM32F103CubeIDE

  • STM32 robot development board

k230 module: external

  • Type-C data cable or ST-Link

Download or simulate the development board

2. Brief principle

1. Hardware schematic

20231028102757858

2. Physical connection diagram

Motor1 -> upper left motor (left front wheel of the car) Motor3 -> upper right motor (right front wheel of the car)

Motor2 -> lower left motor (left rear wheel of the car) Motor4 -> Lower right motor (right rear wheel of the car)

Motor wiring

2023103103

Voice module wiring

Intelligent voice interaction moduleSTM32
5V5V
GNDGND
TX1PC11
RX1PC10

2025-06-10_18-53-59

K230 wiring (Note: The wiring in the figure below is for position reference only. We are equipped with K230 dual-head PH2.0 4Pin all-black wire, with fool-proof design, no need to worry about wiring problems)

PixPin_2025-06-10_19-15-08

3. Communication protocol

Experimental routineStart symbolmsgEnd symbol
Road sign recognition$ #

msg: go_straight, turn_right, hoking

MCU part:

Receive the data sent by k230 through the serial port, and parse and process each byte of the data. After we extract the valid data into the array. Process the returned signpost information, and then the MCU takes corresponding actions according to the parsed signpost

3. Partial code analysis

  • yb_protocol.c

​x
//*
 * @Brief: 数据分析 Data analysis
 * @Note: 解析传入的数据帧,提取字段值并处理
 *        Parse the incoming data frame, extract field values and process them
 * @Parm: 传入接受到的一个数据帧和长度 Pass in a received data frame and length
 * @Retval: 无返回值 No return value
 */
void Pto_Data_Parse(uint8_t *data_buf, uint8_t num)
{
    uint8_t pto_head = data_buf[0];
    uint8_t pto_tail = data_buf[num-1];
    // 验证帧头和帧尾 Verify frame header and footer
    if (!(pto_head == PTO_HEAD && pto_tail == PTO_TAIL)) {
        return;
    }

    uint8_t data_index = 1;
    uint8_t field_index[PTO_BUF_LEN_MAX] = {0};
    int i = 0;

    // 处理分隔符,将逗号替换为字符串结束符,记录字段位置
    // Process delimiters, replace commas with string terminators and record field positions
    for (i = 1; i < num-1; i++) {
        if (data_buf[i] == ',') {
            data_buf[i] = 0;
            field_index[data_index] = i;
            data_index++;
        }
    }

    // 处理无分隔符的情况,整个数据作为标签处理
    // Handle the case without delimiters, treat the entire data as a label
    if (data_index == 1) {
        uint8_t len = num - 2;
        memcpy(lubiao, (char*)data_buf+1, len);
        lubiao[len] = '\0';  // 确保字符串以'\0'结尾 Ensure the string ends with '\0'
    }
    else { // 处理多字段情况 Process multiple fields
        for (i = 0; i < data_index; i++) {
            uint8_t start = field_index[i] + 1;
            uint8_t len;
            
            if (i == data_index - 1) {
                // 最后一个字段,长度计算到帧尾前
                // Last field, length calculated up to before the frame footer
                len = (num - 1) - start;
            } else {
                // 中间字段,长度为下一个分隔符位置减去当前起始位置
                // Middle field, length is the next delimiter position minus the current start position
                len = field_index[i + 1] - start;
            }
            
            // 根据字段索引和总数处理不同类型的数据
            // Process different types of data based on field index and total count
            if (i == 6 && data_index == 7) {
                memcpy(msg, (char*)data_buf + start, len);
                msg[len] = '\0';  // 确保字符串以'\0'结尾 Ensure the string ends with '\0'
            }
            else if (i == 2 && data_index == 3) {
                memcpy(game, (char*)data_buf + start, len);
                game[len] = '\0';  // 确保字符串以'\0'结尾 Ensure the string ends with '\0'
            }
            else {
                // 其他字段转换为整数值
                // Convert other fields to integer values
                values[i] = Pto_Char_To_Int((char*)data_buf + start);
            }
        }
        
        // 帧长度验证,检查协议定义的长度与实际长度是否一致
        // Frame length verification, check if the protocol-defined length matches the actual length
        uint8_t pto_len = values[0];
        if (pto_len != num) {
            printf("pto_len error:%d , data_len:%d\n", pto_len, num);
            return;
        }

        // 提取协议ID Extract protocol ID
        pto_id = values[1];
    }

    // 提取坐标和尺寸信息 Extract coordinate and dimension information
    int x = values[2];
    int y = values[3];
    int w = values[4];
    int h = values[5];

    // 打印坐标和尺寸信息 Print coordinate and dimension information
    printf("dmcode:x:%d, y:%d, w:%d, h:%d,\n", x, y, w, h);

    // 打印游戏信息 Print game information
    printf("msg:%s\n", game);

    // 调试信息已注释 Debug information commented out
    // printf("game:%d\n", pto_id);
    // printf("msg:%s\n", msg);
}
  • app_motor.c

xxxxxxxxxx
//控制小车运行,输入的参数分别为x、y、z三个轴上的速度值
//Control the movement of the car. The input parameters are the speed values on the x, y, and z axes.
void wheel_Ctrl(int16_t V_x, int16_t V_y, int16_t V_z)
{
    float robot_APB = Motion_Get_APB();
//    speed_lr = -V_y;
    speed_lr = 0;
    speed_fb = V_x;
    speed_spin = (V_z / 1000.0f) * robot_APB;
    if (V_x == 0 && V_y == 0 && V_z == 0)
    {
        Motion_Stop(STOP_BRAKE);
        return;
    }

    speed_L1_setup = speed_fb + speed_lr - speed_spin;
    speed_L2_setup = speed_fb - speed_lr - speed_spin;
    speed_R1_setup = speed_fb - speed_lr + speed_spin;
    speed_R2_setup = speed_fb + speed_lr + speed_spin;

    if (speed_L1_setup > 1000)
        speed_L1_setup = 1000;
    if (speed_L1_setup < -1000)
        speed_L1_setup = -1000;
    if (speed_L2_setup > 1000)
        speed_L2_setup = 1000;
    if (speed_L2_setup < -1000)
        speed_L2_setup = -1000;
    if (speed_R1_setup > 1000)
        speed_R1_setup = 1000;
    if (speed_R1_setup < -1000)
        speed_R1_setup = -1000;
    if (speed_R2_setup > 1000)
        speed_R2_setup = 1000;
    if (speed_R2_setup < -1000)
        speed_R2_setup = -1000;

    Motion_Set_Speed(speed_L1_setup, speed_L2_setup, speed_R1_setup, speed_R2_setup);
}
  • app_irtracking.c

xxxxxxxxxx
// 路标逻辑控制 - Road Sign Logic Control
void Car_lubiao(void)
{
    // 蜂鸣器鸣笛 - Buzzer Honking
    if (strcmp("honking", lubiao) == 0 )  
    {
        Set_Buzzer(1);    // 开启蜂鸣器 - Turn on buzzer
        HAL_Delay(500);   // 延时500毫秒 - Delay 500ms
        Set_Buzzer(0);    // 关闭蜂鸣器 - Turn off buzzer
    }
    // 直行 - Go Straight
    else if (strcmp("go_straight", lubiao) == 0 )
    {
        // 小车前进 - Car moves forward
        Motion_Set_Speed(250,250,250,250);
        HAL_Delay(1000);  // 延时1秒 - Delay 1s
        HAL_Delay(1000);  // 延时1秒 - Delay 1s
        wheel_State(0,0); // 停止车轮 - Stop wheels
    }
    // 右转 - Turn Right
    else if (strcmp("turn_right", lubiao) == 0 )
    {
        Motion_Set_Speed(500,500,0,0);    // 准备右转 - Prepare right turn
        HAL_Delay(1000);                  // 延时1秒 - Delay 1s
        Motion_Set_Speed(250,250,250,250);// 右转后前进 - Move forward after turning
        HAL_Delay(1000);                  // 延时1秒 - Delay 1s
        wheel_State(0,0);                 // 停止车轮 - Stop wheels
    }
}

4. Experimental phenomenon

Turn on the power switch, wait for the system to initialize, the screen will display the camera image, start to recognize road signs, and make corresponding actions. Note: Connect our AI voice interaction integration module and then there will be voice broadcast after recognizing the road sign! Users who have not purchased the voice module do not have to worry. When the voice module is not connected, K230 can still implement this case, but there is no voice broadcast function.

guidedetect

Voice module command words

Command wordsFunction typeBroadcast sentenceBroadcast modeSend protocolReceive protocol
RIGHT-TURN-SIGN-DETECTEDCommand wordsRecognize the right turn sign the car turns rightByAA 55 FF 61 FBAA 55 FF 61 FB
HORN-SIGN-DETECTEDCommand wordsRecognize the horn sign the car honksByAA 55 FF 62 FBAA 55 FF 62 FB
FORWARD-SIGN-DETECTEDCommand wordsRecognize the forward sign the car moves forwardByAA 55 FF 63 FBAA 55 FF 63 FB

Voice module firmware burning

x
Burning the CI1302_EN_ SingleMic_V00916_UART1_115200_2M.bin file we provide can realize all cases related to the intelligent voice interaction module of this car. Only one burning is required. For the burning method, see [Voice Interaction Control Tutorial] [Section 6] Voice Module Firmware Burning

K230 Code Burning

Required tools: K230, SD card, CanMV IDE K230

We find the detct_guide.py file in the project folder, then drag it to CanMV IDE K230, and then choose to save the opened script as main.py to CanMV

PixPin_2025-06-10_19-59-03

Road sign image

go_straight:

0

turn_right:

1

honking:

2

K230 machine code tracking
K230 color response (voice)

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文