你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

TOF传感器无法正确识别物体

[复制链接]
憨客鱼 提问时间:2026-6-27 18:32 / 未解决

我采用VL53L8CX型号TOF传感器,来做手势识别,tof传感器检测到的数据取8X8矩阵数据,分为9个区域,检测到物体在哪个区域就显示对应的图片,现在的问题是,每次识别区域后,物体已经拿走了,图像还显示之前的图片,不回到原始位置图片,tof测距距离也不清0,总是保持上一位置,下面是代码,有没有大佬知道是什么原因?

/ USER CODE BEGIN Header / /**


  • @file : main.c
  • @brief : Main program body (Y Label=Value: Top?Bottom Y1-Y8 = g_ucRowSum[0]-7)

  • @attention
  • Copyright (c) 2023 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 "usart.h"

include "gpio.h"

include "tof.h"

include "MainFun.h"

include "53l8a1_ranging_sensor.h"

include <stdio.h>

include <string.h>

include <stdlib.h> // For srand()/rand() declarations (fixes C99 warning)

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

//PA0=BIN0(bit0);PA1=BIN1(bit1);PA2=BIN2(bit2);PA3=BIN3(bit3)

define POS_OUT_PORT GPIOA

define POS_OUT_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)

// Macro: Valid ranging distance range (adjust for your application)

define TOF_MIN_DISTANCE 70 // Minimum valid distance (mm)

define TOF_MAX_DISTANCE 200 // Maximum valid distance (mm)

define MATRIX_SIZE 8 // 8x8 matrix size (easily modifiable)

define Y_AXIS_THRESHOLD 2 // Y-axis trigger threshold: first row > 2 (top?bottom)

define INCREASE_TOLERANCE 1 // Allow up to 1 non-increasing step (anti-jitter)

define LOW_VALUE 2 // Low value threshold

define INCREASE_CHECK_CNT 2 // Required increasing count for low value validation

define VALUE_DIFF_THRESH 3 // Value difference threshold

// 8x8 grid area definition

define Y_TOP_ROW_MAX 3 // Y top 3 rows: Y1~Y3

define Y_MID_ROW_MIN 4 // Y middle 2 rows: Y4~Y5

define Y_MID_ROW_MAX 5

define Y_BOT_ROW_MIN 6 // Y bottom 3 rows: Y6~Y8

define X_LEFT_COL_MAX 3 // X left 3 columns: X1~X3

define X_MID_COL_MIN 4 // X middle 2 columns: X4~X5

define X_MID_COL_MAX 5

define X_RIGHT_COL_MIN 6 // X right 3 columns: X6~X8

define EYE_OPEN_TIME 25 // Eye open duration

define EYE_CLOSE_TIME 6 // Eye close duration

define CONFIRM_COUNT 2

//#define WEAK_VALID_THRESHOLD 6 // ȵӐЧϱ˘ʽ //#define WEAK_EXIT_FRAME 3 // Á¬и3֡ȵӐЧÁ¢¿̇勸 // Global variables unsigned char g_ucTofBinary[MATRIX_SIZE][MATRIX_SIZE]; // Original 8x8 binarized data unsigned char g_ucTransformedMatrix[MATRIX_SIZE][MATRIX_SIZE]; // Rotate+mirror matrix unsigned char g_ucRowSum[MATRIX_SIZE]; // Y-axis sum (Top?Bottom Y1-Y8 = [0]-[7]) unsigned char g_ucColSum[MATRIX_SIZE]; // X-axis sum (Left?Right X1-X8 = [0]-[7]) unsigned char g_ucTargetY; // Target Y (1-8, Top?Bottom) unsigned char g_ucTargetX; // Target X (1-8, Left?Right) static unsigned char g_NoTarget_Count = 0; unsigned char Matrix_Has_Data(void);

static unsigned int g_Blink_Timer = 0; // Blink timer static unsigned char g_Blink_Flag = 0; // Blink flag static unsigned char g_Last_Zone = 0xFF; // Last zone static unsigned char g_Zone_Confirm_Cnt = 0;// Zone repeat count //static unsigned char g_WeakValidCnt = 0; // ȵӐЧ֡¼Ɗý / USER CODE END Includes /

/ Private typedef -----------------------------------------------------------/ / USER CODE BEGIN PTD / RANGING_SENSOR_Capabilities_t Cap; RANGING_SENSOR_ProfileConfig_t Profile; RANGING_SENSOR_Result_t stTofDat;

// Structure to store positions of maximum values (shared for row/column) typedef struct { unsigned char count; // Number of maximum value positions unsigned char index[MATRIX_SIZE]; // Indices of maximum value positions } MaxPosition_t; / USER CODE END PTD /

/ Private define ------------------------------------------------------------/ / USER CODE BEGIN PD / // Sensor configuration macros (avoid redefinition warnings) //#undef TIMING_BUDGET //#undef RANGING_FREQUENCY //#define TIMING_BUDGET 50 // Ranging timing budget (ms) //#define RANGING_FREQUENCY 20 // Ranging frequency (Hz) / USER CODE END PD /

/ USER CODE BEGIN ה¶¨ҥλփʤ³öº¯ʽ / /**

  • @brief ½«0~9µćøӲ±຅תΪ4λ¶þ½øֆʤ³öµ½PA0~PA3

  • @param zone_num: 0=ΞĿ±꣬1~9¶ԓ¦9¸ö·ևø */ void Output_Pos_To_Master(unsigned char zone_num) { uint16_t out_level = 0; // ̡ȡzone_numµʹ룬ӳɤµ½PA0~PA3 out_level |= ((zone_num >> 0) & 0x01) << 0; out_level |= ((zone_num >> 1) & 0x01) << 1; out_level |= ((zone_num >> 2) & 0x01) << 2; out_level |= ((zone_num >> 3) & 0x01) << 3;

    // ψȫ²¿À­µͣ¬ԙɨփ¶ԓ¦¸ߵ熽 HAL_GPIO_WritePin(POS_OUT_PORT, POS_OUT_PINS, GPIO_PIN_RESET); HAL_GPIO_WritePin(POS_OUT_PORT, out_level, GPIO_PIN_SET); } / USER CODE END ה¶¨ҥλփʤ³öº¯ʽ /

//**** // Determine zone based on target X/Y coordinates and output zone code to master via PA0~PA3 IO //**** void Show_Image_By_Pos(void) { unsigned char current_zone = 0xFF; unsigned char valid_count = 0;

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); for (unsigned char row = 0; row < MATRIX_SIZE; row++) { for (unsigned char col = 0; col < MATRIX_SIZE; col++) { if (g_ucTransformedMatrix[row][col] == 1) valid_count++; } }

// ============================================================== // None Target: output code 0 (0000 on PA0-PA3) // ============================================================== if(valid_count <= 3) { // ΞĿ±꣬ʤ³ö±«0 Output_Pos_To_Master(0); g_NoTarget_Count++;

g_Last_Zone = 0xFF;
g_Zone_Confirm_Cnt = 0;
return;

} else { // Reset all status when valid target detected g_NoTarget_Count = 0; g_Blink_Timer = 0;

// if(valid_count <= WEAK_VALID_THRESHOLD) // { // g_WeakValidCnt++; // if(g_WeakValidCnt >= WEAK_EXIT_FRAME) // { // g_Last_Zone = 0xFF; // g_Zone_Confirm_Cnt = 0; // g_WeakValidCnt = 0; // } // } // else // { // g_WeakValidCnt = 0; // }

}

// ====================== 1. Determine X/Y zone ====================== // Row direction: up / middle / down unsigned char y_zone; if(g_ucTargetY <= Y_TOP_ROW_MAX) { y_zone = 1; // up } else if(g_ucTargetY >= Y_BOT_ROW_MIN) { y_zone = 3; // down } else { y_zone = 2; // middle }

// Column direction: left / middle / right unsigned char x_zone; if(g_ucTargetX <= X_LEFT_COL_MAX) { x_zone = 1; // left } else if(g_ucTargetX >= X_RIGHT_COL_MIN) { x_zone = 3; // right } else { x_zone = 2; // middle }

// ====================== 2. Assign current_zone (9 zone IDs) ====================== if(x_zone == 1 && y_zone == 1) current_zone = 1; // LeftUp ׳ɏ else if(x_zone == 1 && y_zone == 2) current_zone = 4; // Left ׳ else if(x_zone == 1 && y_zone == 3) current_zone = 7; // LeftDown ׳ς else if(x_zone == 3 && y_zone == 1) current_zone = 3; // RightUp Ӓɏ else if(x_zone == 3 && y_zone == 2) current_zone = 6; // Right Ӓ else if(x_zone == 3 && y_zone == 3) current_zone = 9; // RightDown Ӓς else if(x_zone == 2 && y_zone == 1) current_zone = 2; // MiddleUp ֐ɏ else if(x_zone == 2 && y_zone == 3) current_zone = 8; // MiddleDown ֐ς else current_zone = 5; // Middle ս֐

// ====================== 3. Zone confirmation: stable 2 frames then output IO code ====================== if(current_zone == g_Last_Zone) { g_Zone_Confirm_Cnt++; if(g_Zone_Confirm_Cnt >= CONFIRM_COUNT) { // Έ¶¨2֡º󊤳ö¶ԓ¦ǸӲ±຅ցPA0-PA3 Output_Pos_To_Master(current_zone); } } else { // ǸӲǐ»»ʱ£¬¼ƊýƷɨ1£¬µ«ʇȧ¹û¾ɇøӲʇӒɏzone3£¬ֱ½Ӈ偣˸ if(g_Last_Zone == 3) { g_Last_Zone = current_zone; g_Zone_Confirm_Cnt = 0; // Ӓɏǐ»»Á¢¿̽⋸£¬²»Ӄµȴý¼Ɗý } else { g_Last_Zone = current_zone; g_Zone_Confirm_Cnt = 1; } }

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); }

//**** // Matrix transformation: Clockwise rotation (90? + Horizontal mirror flip // Input: Original TOF matrix | Output: Transformed matrix (matches physical layout) //**** void Transform_Matrix(void) { unsigned char row, col; unsigned char tempMatrix[MATRIX_SIZE][MATRIX_SIZE];

// Step 1: Clockwise rotate 90 degrees for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { tempMatrix[row][col] = g_ucTofBinary[MATRIX_SIZE - 1 - col][row]; } }

// Step 2: Horizontal mirror flip (left-right reverse) for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { g_ucTransformedMatrix[row][col] = tempMatrix[row][MATRIX_SIZE - 1 - col]; } } }

//**** // Check if transformed matrix contains any valid data (any pixel = 1) //**** unsigned char Matrix_Has_Data(void) { for(unsigned char row = 0; row < MATRIX_SIZE; row++) { for(unsigned char col = 0; col < MATRIX_SIZE; col++) { if(g_ucTransformedMatrix[row][col] == 1) { return 1; // Matrix has valid data } } } return 0; // Matrix is all zeros (no object detected) }

//**** // Check if Y-axis row sum shows an increasing trend from top to bottom // Return: 1 = increasing trend, 0 = no increasing trend //**** unsigned char Check_Y_Axis_Increasing(void) { unsigned char nonZeroStart = 0xFF; unsigned char decreaseCount = 0;

// 1. Find first non-zero row (valid data start row) for(unsigned char i = 0; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { nonZeroStart = i; break; } }

// No valid data, return 0 directly if(nonZeroStart == 0xFF) { return 0; }

// 2. Check increasing trend from valid start row (allow minor tolerance) for(unsigned char i = nonZeroStart; i < MATRIX_SIZE - 1; i++) { // Current row sum < next row sum: normal increasing, skip if(g_ucRowSum[i] < g_ucRowSum[i+1]) { continue; } // Current row sum > next row sum: decrease, count +1 else if(g_ucRowSum[i] > g_ucRowSum[i+1]) { decreaseCount++; // Exceed tolerance: judge as no increasing trend if(decreaseCount > INCREASE_TOLERANCE) { return 0; } } // Equal: keep stable, no count }

// Decrease count within tolerance: judge as increasing trend return 1; }

//**** // Verify if rows below low-value row meet required strict increasing count // Param: startRow - low value start row | Return: 1 = pass, 0 = fail //**** unsigned char Verify_Low_Value_Increase(unsigned char startRow) { unsigned char increaseCnt = 0; unsigned char currentRow = startRow;

// Start row out of range: fail directly if(startRow >= MATRIX_SIZE - 1) { return 0; }

// Traverse following rows, count strict increasing times while(currentRow < MATRIX_SIZE - 1 && increaseCnt < INCREASE_CHECK_CNT) { // Strict increasing (current < next) if(g_ucRowSum[currentRow] < g_ucRowSum[currentRow + 1]) { increaseCnt++; } currentRow++; }

// Pass if required increasing count reached return (increaseCnt >= INCREASE_CHECK_CNT) ? 1 : 0; }

//**** // Preprocess low-value rows (value difference + next row zero check) // Param: topRow - low value start row | Return: final selected row (0-7), 0xFF = fail //**** unsigned char Preprocess_Low_Value_Row(unsigned char topRow) { // 1. Check if next row is 0 (no subsequent data) if(topRow >= MATRIX_SIZE - 1 || g_ucRowSum[topRow + 1] == 0) { return 0xFF; // No value in next row, discard current row }

// 2. Calculate difference between next row and current low value unsigned char valueDiff = g_ucRowSum[topRow + 1] - g_ucRowSum[topRow];

// 3. Difference >=3: discard current, search new valid row from next if(valueDiff >= VALUE_DIFF_THRESH) { unsigned char newTopRow = 0xFF; // Find first non-zero row from next row for(unsigned char i = topRow + 1; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { newTopRow = i; break; } } // New row still low value: recursive process; else return directly if(newTopRow != 0xFF) { if(g_ucRowSum[newTopRow] <= LOW_VALUE) { return Preprocess_Low_Value_Row(newTopRow); // Recursive process new low value row } else { return newTopRow; // Not low value: return directly } } return 0xFF; // No new valid row } // 4. Difference <3: perform secondary increasing verification else { if(Verify_Low_Value_Increase(topRow)) { return topRow; // Pass verification, keep current row } else { return 0xFF; // Fail verification, discard current row } } }

//**** // Get top valid row of Y-axis under increasing trend (integrate low-value preprocess + force discard top row sum =1) // Return: valid row index (0-7), 0xFF = fail //**** unsigned char Get_Top_Y_In_Increasing(void) { unsigned char topRow = 0xFF;

// 1. Find first non-zero row (valid data start row) for(unsigned char i = 0; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { topRow = i; break; } }

// No valid data if(topRow == 0xFF) { return 0xFF; }

// ====================== Universal anti-jitter: discard top valid row if =1 ====================== // Loop check: if current top valid row ==1, discard and continue searching downward while(topRow != 0xFF && g_ucRowSum[topRow] == 1) { // Find new valid row from next row (>0) unsigned char newTop = 0xFF; for(unsigned char i = topRow + 1; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { newTop = i; break; } }

// No next row found: overall invalid
if(newTop == 0xFF)
{
    return 0xFF;
}

// Continue checking if new top is also 1
topRow = newTop;

} // ==========================================================================

// 2. Check if low value if(g_ucRowSum[topRow] <= LOW_VALUE) { // Low value row preprocess (value diff + next row 0 + secondary check) return Preprocess_Low_Value_Row(topRow); } else { return topRow; // Not low value: return directly } }

//**** // Calculate up/down side sum for max position judgment (for X-axis now) // - Edge positions: double the only adjacent value // - Normal positions: sum up + down values //**** unsigned int Calc_Side_Sum(unsigned char *sumArray, unsigned char idx) { unsigned int sideSum = 0;

// Edge case: first position (idx=0) if(idx == 0) { sideSum = sumArray[idx+1] 2; // Double the only adjacent value } // Edge case: last position (idx=7 for 8x8 matrix) else if(idx == MATRIX_SIZE - 1) { sideSum = sumArray[idx-1] 2; // Double the only adjacent value } // Normal case: sum up + down values else { sideSum = sumArray[idx-1] + sumArray[idx+1]; }

return sideSum; }

//**** // General max position finding logic (NOW FOR X-AXIS: side sum comparison) // Handles multiple max values via side sum comparison, then middle/random selection //**** unsigned char Find_Target_X_Pos_General(unsigned char *sumArray) { MaxPosition_t maxPos; unsigned char maxValue = 0; unsigned int maxSideSum = 0; unsigned char targetIdx = 0; unsigned char i;

// Step 1: Find maximum value and collect all positions with this value maxPos.count = 0; // First pass: find the maximum value in the array for(i = 0; i < MATRIX_SIZE; i++) { if(sumArray[i] > maxValue) { maxValue = sumArray[i]; } }

// Second pass: collect all indices that have the maximum value for(i = 0; i < MATRIX_SIZE; i++) { if(sumArray[i] == maxValue) { maxPos.index[maxPos.count++] = i; } }

// If only one max value exists: return it directly if(maxPos.count == 1) { return maxPos.index[0]; }

// Step 2: Multiple max values exist ? compare up/down side sums unsigned int sideSumArray[MATRIX_SIZE] = {0}; unsigned char maxSideSumCount = 0; unsigned char maxSideSumIndex[MATRIX_SIZE] = {0};

// Calculate side sum for each max position for(i = 0; i < maxPos.count; i++) { sideSumArray[i] = Calc_Side_Sum(sumArray, maxPos.index[i]);

// Track the maximum side sum value
if(sideSumArray[i] > maxSideSum)
{
    maxSideSum = sideSumArray[i];
    maxSideSumCount = 0;
    maxSideSumIndex[maxSideSumCount++] = i;
}
else if(sideSumArray[i] == maxSideSum)
{
    maxSideSumIndex[maxSideSumCount++] = i;
}

}

// If only one max side sum exists: return the corresponding index if(maxSideSumCount == 1) { targetIdx = maxPos.index[maxSideSumIndex[0]]; } // Step 3: Side sums are equal ? select middle position (or random for even count) else { // Odd count: select exact middle index if(maxPos.count % 2 == 1) { targetIdx = maxPos.index[maxPos.count / 2]; } // Even count: randomly select between the two middle indices else { static unsigned char seed = 0; seed++; srand(seed);

    unsigned char mid1 = maxPos.count / 2 - 1;
    unsigned char mid2 = maxPos.count / 2;
    targetIdx = (rand() % 2) ? maxPos.index[mid1] : maxPos.index[mid2];
}

}

return targetIdx; }

//**** // Y-axis position search function (integrate all logic) // - Increasing trend detected: select top valid row (low-value preprocess) // - No increasing trend: keep original threshold logic //**** unsigned char Find_Target_Y_Pos_Threshold(unsigned char *sumArray) { unsigned char targetRow = 0xFF;

// Step 1: Check if Y-axis increasing trend exists if(Check_Y_Axis_Increasing()) { // Increasing trend: try get top valid row (include low-value preprocess) targetRow = Get_Top_Y_In_Increasing(); if(targetRow != 0xFF) { return targetRow; } }

// Step 2: No increasing trend / preprocess fail: use original logic (find first row above threshold) for(unsigned char row = 0; row < MATRIX_SIZE; row++) { if(sumArray[row] > Y_AXIS_THRESHOLD) { return row; // Return first qualified Y-axis index (0-7 ? Y1-Y8) } }

// Step 3: No row above threshold: use general max value logic return Find_Target_X_Pos_General(sumArray); }

//**** // TOF sensor initialization (hardware reset + configuration + start ranging) //**** void Tof_Device_Init(void) { unsigned char status; unsigned int Id;

// Hardware reset sequence TOF_RST_HIGH; HAL_Delay(5); TOF_RST_LOW;

TOF_LPN_LOW; HAL_Delay(5); TOF_LPN_HIGH;

// Initialize VL53L8A1 sensor status = VL53L8A1_RANGING_SENSOR_Init(VL53L8A1_DEV_LEFT);

if (status != BSP_ERROR_NONE) { //printf("VL53L8A1_Init failed (0x%02X)\r\n", status); return; }

// Read sensor ID and capabilities (optional, for debugging) VL53L8A1_RANGING_SENSOR_ReadID(VL53L8A1_DEV_LEFT, &Id); VL53L8A1_RANGING_SENSOR_GetCapabilities(VL53L8A1_DEV_LEFT, &Cap);

// Configure 8x8 continuous ranging mode Profile.RangingProfile = RS_PROFILE_8x8_CONTINUOUS; Profile.TimingBudget = TIMING_BUDGET; Profile.Frequency = RANGING_FREQUENCY; Profile.EnableAmbient = 0; Profile.EnableSignal = 0; VL53L8A1_RANGING_SENSOR_ConfigProfile(VL53L8A1_DEV_LEFT, &Profile);

// Start continuous blocking ranging mode // status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_LEFT, RS_MODE_BLOCKING_CONTINUOUS); status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_LEFT, RS_MODE_ASYNC_ONESHOT);
if (status != BSP_ERROR_NONE) { //printf("VL53L8A1_Start failed (0x%02X)\r\n", status); return; }

//printf("TOF Sensor Initialized Successfully!\r\n"); }

//**** // Binarization: Convert raw ranging data to 0/1 matrix + apply transformation //****

void Tof_Binarization(void) { unsigned char row, col; unsigned int distance; unsigned int idx = 0;

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // Traverse all 8x8 pixels (original TOF output order) for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { // Read raw distance value (with boundary check to avoid overflow) if(idx < sizeof(stTofDat.ZoneResult)/sizeof(stTofDat.ZoneResult[0])) { distance = stTofDat.ZoneResult[idx].Distance[0]; } else { distance = 0; // Default to invalid if index out of bounds } idx++;

    // Binarization logic
    if((distance >= TOF_MIN_DISTANCE) && (distance <= TOF_MAX_DISTANCE))
    {
        g_ucTofBinary[row][col] = 1;
    }
    else
    {
        g_ucTofBinary[row][col] = 0;
    }
}

}

// Apply matrix transformation (rotate + mirror) Transform_Matrix();

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); }

//**** // Calculate Y/X axis sums (Y: Top?Bottom Y1-Y8 = [0]-[7] | X: Left?Right X1-X8 = [0]-[7]) //**** void Tof_Calc_Target_Pos(void) { unsigned char row, col;

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 1. Calculate Y-axis sum (DIRECT mapping: Top?Bottom Y1-Y8 = g_ucRowSum[0]-[7]) memset(g_ucRowSum, 0, sizeof(g_ucRowSum)); for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { g_ucRowSum[row] += g_ucTransformedMatrix[row][col]; } }

// 2. Calculate X-axis sum (DIRECT mapping: Left?Right X1-X8 = g_ucColSum[0]-[7]) memset(g_ucColSum, 0, sizeof(g_ucColSum)); for(col = 0; col < MATRIX_SIZE; col++) { for(row = 0; row < MATRIX_SIZE; row++) { g_ucColSum[col] += g_ucTransformedMatrix[row][col]; } }

// 3. Calculate target position (convert 0-7 index ? 1-8 coordinate) g_ucTargetX = 0xFF; g_ucTargetY = 0xFF;

// Only calculate valid coordinates if matrix has data (any 1) if(Matrix_Has_Data()) { // X-axis: Use side sum comparison logic g_ucTargetX = Find_Target_X_Pos_General(g_ucColSum) + 1; // Y-axis: Use integrated logic g_ucTargetY = Find_Target_Y_Pos_Threshold(g_ucRowSum) + 1; }

//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); }

//**** // Serial port print function //**** /***** void Tof_Print_Data(void) { unsigned char row, col; unsigned char hasYOverThreshold = 0; unsigned char printYLabel;

// Check if any Y-axis row sum exceeds threshold for(row = 0; row < MATRIX_SIZE; row++) { if(g_ucRowSum[row] > Y_AXIS_THRESHOLD) { hasYOverThreshold = 1; break; } }

// Print header + transformed matrix printf("=====================\r\n");

// Print matrix rows with Y1-Y8 top?bottom for(row = 0; row < MATRIX_SIZE; row++) { printYLabel = row + 1; // row0=Y1, row1=Y2 ... row7=Y8 for(col = 0; col < MATRIX_SIZE; col++) { printf("%d ", g_ucTransformedMatrix[row][col]); } printf(" | Y%d Sum: %d\r\n", printYLabel, g_ucRowSum[row]); }

// Print X-axis sum results printf("X-axis Sum (Side Sum Logic): "); for(col = 0; col < MATRIX_SIZE; col++) { printf("%d ", g_ucColSum[col]); } printf("\r\n");

// Print Y-axis sum results (highlight rows > threshold) printf("Y-axis Sum (Threshold=%d): ", Y_AXIS_THRESHOLD); for(row = 0; row < MATRIX_SIZE; row++) { if(g_ucRowSum[row] > Y_AXIS_THRESHOLD) { printf("[%d] ", g_ucRowSum[row]); // Highlight qualified Y rows } else { printf("%d ", g_ucRowSum[row]); } } printf("\r\n");

// Print final detection result if(!Matrix_Has_Data()) { printf("Result: No object (Empty matrix)\r\n"); } else { printf("Result: Object Position [X=%d, Y=%d]\r\n", g_ucTargetX, g_ucTargetY); } printf("=====================\r\n\r\n"); } */ //**** // Main TOF processing function (data read ? binarization ? calculation ? print) //**** void Pro_Tof_Fun(void) { unsigned char status;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);

status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_LEFT, &stTofDat);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
if(status != BSP_ERROR_NONE) { printf("Read TOF data failed (0x%02X)\r\n", status); // HAL_Delay(200); return; }

Tof_Binarization();

Tof_Calc_Target_Pos();

//Tof_Print_Data();

Show_Image_By_Pos();

HAL_Delay(50); }

收藏 评论0 发布时间:2026-6-27 18:32

举报

0个回答

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版