cancel
Showing results for 
Search instead for 
Did you mean: 

在同一条i2c总线轮询使用两个vl53l1x出现只有一个有反应的问题

eneeen
Associate II

这是我的代码,我之前以前改地址成功了的,这里就开始测量数据

while (1) {
        // 获取当前时间作为起始时间
        clock_gettime(CLOCK_MONOTONIC, &start_time);  // 获取起始时间
       
        for (i = 0; i < 2; i++) {  // 轮询两个传感器
            Timeout = 0;
            dataReady = 0;

            // 检查数据是否准备好
            error = VL53L1X_CheckForDataReady(Devs[i], &dataReady);
            if (error != 0) {
                printf("Error checking data readiness for sensor %d\n", i);
                continue;  // 如果检查失败,跳过这个传感器
            }

            // 等待数据准备就绪或超时
            while (dataReady == 0 && Timeout == 0) {
                usleep(1000);  // 每次等待 1 毫秒,防止 CPU 空转
                clock_gettime(CLOCK_MONOTONIC, &current_time);  // 获取当前时间
               
                // 检查是否超时
                unsigned long elapsed_time_ms = (current_time.tv_sec - start_time.tv_sec) * 1000 + (current_time.tv_nsec - start_time.tv_nsec) / 1000000;
               
                if (elapsed_time_ms >= MAX_WAIT_TIME_MS) {
                    Timeout = 1;  // 超时标志
                    printf("Timeout waiting for data on sensor %d\n", i);
                } else {
                    // 如果还没超时,继续检查数据准备状态
                    error = VL53L1X_CheckForDataReady(Devs[i], &dataReady);
                    if (error != 0) {
                        printf("Error checking data readiness for sensor %d\n", i);
                        break;
                    }
                }
            }

            if (Timeout == 0) {
                // 数据准备好,清除中断并读取结果
                error = VL53L1X_ClearInterrupt(Devs[i]);
                if (error != 0) {
                    printf("Error clearing interrupt for sensor %d\n", i);
                    continue;
                }

                error = VL53L1X_GetDistance(Devs[i], &Distance);
                if (error != 0) {
                    printf("Error getting distance for sensor %d\n", i);
                    continue;
                }

                error = VL53L1X_GetRangeStatus(Devs[i], &RangeStatus);
                if (error != 0) {
                    printf("Error getting range status for sensor %d\n", i);
                    continue;
                }

                // 打印当前传感器的数据
                printf("sensor %d: distance = %5d, status = %2d\n", i, Distance, RangeStatus);
            }
        }

        // 超时处理:如果超时发生,重置所有传感器
        if (Timeout == 1) {
             if (set_gpio_value(gpio_set[0], 0) < 0) {
        printf("Failed to set XSHUT GPIO to high\n");
     
        return false;
         if (set_gpio_value(gpio_set[1], 0) < 0) {
        printf("Failed to set XSHUT GPIO to high\n");
     
        return false;
    }
    }
        }

        // 触发下次测距
        for (i = 0; i < 2; i++) {
            error = VL53L1X_ClearInterrupt(Devs[i]);  // 清除中断
            if (error != 0) {
                printf("Error clearing interrupt for sensor %d\n", i);
            }

            // 第一次测量时跳过(可以根据需求调整)
            if (first_range) {
                error = VL53L1X_ClearInterrupt(Devs[i]);
                first_range = 0;  // 设置为非第一次测量
            }
        }

        usleep(1000);  // 等待一段时间再进行下次操作
    }
 
 
这是运行时候的结果,不知道为什么这里无论是sensor0还是senser1都是同一个传感器的数据,我用手挡住另外一个传感器都没有反应的,只有其中一个有反应并有数据输出
QQ截图20250206165222.png
5 REPLIES 5
John E KVAM
ST Employee

I just spent 2 hours on the phone with a guy. And it was the I2C address, and he had the same symptoms as you.

  • Choose I2C addresses that are EVEN numbers. The odd numbers are the read addresses. Default is 0x52. For his 3 sensors we chose 0x62, 0x72 and 0x82. (Although 0x54, 0x56 and 0x58 would work as well.)
  • Put all sensor into reset. 
  • Bring out the first one, initialize it (this step waits until the sensor is booted), then change its address. 

Then repeat for the other sensor.

Do NOT put them back into reset. Doing this will undo everything. 

At this point you should be good to go. 

And if you don't get a response from the other sensors, it's because they have been reset or their addresses are conflicting. 

-john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

你好,我想我知道是什么原因了!

我选择了0x62,0x64的地址,并且也是按照你说的步骤进行改地址操作的,并且也是成功的,但是现在在运行获取数据的时候,只有位于后面改地址的传感器有反应,并且我还参考了st官网上的使用9个2d lidar例程。

经过后面测试我发现是初始化i2c的原因,他覆盖了之前初始化的i2c端口。

但是我也有个问题,难道每次轮询不同地址的lidar都要再去进行初始化i2c端口吗?你有办法可以优化吗?还是可以有其他的解法?

QQ截图20250207095655.png

并且我还有一个问题就是,每次轮询不同地址的Lidar都要初始化i2c端口,这样做会太频繁更改了,程序也会崩溃的

John E KVAM
ST Employee

After getting each sensor on a different address, you do NOT have to change anything. Don't re-initialize the sensors or the I2C bus. The sensors will be just fine. 

Simply change the 'dev' address in the first argument to the address of the sensor you want to control.

That should be enough.

(Please consider translating your text to English before you post it. Makes it easier on the rest of the community. Otherwise, you will only get Chinese speakers and I to respond.)

 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Thanks for the reminder.

I think my problem has not been solved yet. The I2C bus initialized at the beginning is at address 0X29. If it is not initialized and updated to the new device address later, the program will not be able to proceed.

Do you mean the 'dev' of the following function? I don't think it works. I always change i2c_Addr. Before modifying the device address, it is 0x29. After modifying it, I initialize and change i2c_Addr to the new device address (0x31, 0x32) for communication.

You can see that the red circle in my code is used to change the new i2c port for communication.

 

QQ截图20250211112842.png

QQ截图20250211113925.pngQQ截图20250211114157.pngQQ截图20250211114227.png