pololu/vl53l1x-arduino

set custom ROI

riodoro1836 opened this issue · 5 comments

is it possible to set a custom ROI with a smaller number of SPADs, to reduce the FoV ?

thx and regards

Disclaimer: I'm also playing with this at this very moment. I don't know much about it yet, but have found things you might find useful.

The library doesn't seem to implement the functions for this, but they do seem not very difficult to implement based on the reference API.

There ROI is implemented as follows:

VL53L1X_ERROR VL53L1X::VL53L1X_SetROI(uint8_t X, uint8_t Y, uint8_t opticalCenter)
{
	VL53L1X_ERROR status = 0;

	status =VL53L1_RdByte(Device, VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD, &opticalCenter);
	if (X > 16)
		X = 16;
	if (Y > 16)
		Y = 16;
	if (X > 10 || Y > 10){
		opticalCenter = 199;
	}
	status = VL53L1_WrByte(Device, ROI_CONFIG__USER_ROI_CENTRE_SPAD, opticalCenter);
	status = VL53L1_WrByte(Device, ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE,
		       (Y - 1) << 4 | (X - 1));
	return status;
}

VL53L1X_ERROR VL53L1X::VL53L1X_GetROI_XY(uint16_t *ROI_X, uint16_t *ROI_Y)
{
	VL53L1X_ERROR status = 0;
	uint8_t tmp;

	status = VL53L1_RdByte(Device,ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE, &tmp);
	*ROI_X = ((uint16_t)tmp & 0x0F) + 1;
	*ROI_Y = (((uint16_t)tmp & 0xF0) >> 4) + 1;
	return status;
}

Where you'd only need VL53L1X_SetROI then modified to work with the pololu API. The second function is merely the getter for the X and Y positions of the ROI you had set.
I might make a patch for that soon as i want this too, no promises though.

I needed to change the ROI for a project I am working on. @markg85 Thanks for pointing me in the right direction.

I ended up adding the following three functions to VL53L1X.cpp. Disclaimer: this has not been throughly tested, but I wanted to share what I have so far incase it can help someone else.

void VL53L1X::getROIxy(uint16_t *ROI_X, uint16_t *ROI_Y)
{
    uint8_t roi;
    roi = readReg(ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE);
    *ROI_X = ((uint16_t)roi & 0x0F) + 1;
    *ROI_Y = (((uint16_t)roi & 0xF0) >> 4) + 1;
}
void VL53L1X::getROICenter(uint16_t *ROI_Center)
{
    uint8_t center;
    center = readReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD);
    *ROI_Center = center;
}
void VL53L1X::SetROI(uint8_t X, uint8_t Y)
{
    uint8_t OpticalCenter;
    OpticalCenter = readReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD);
    
    if (X > 16) 
    {
        X = 16;
    }
    
    if (Y > 16)
    {
        Y = 16;
    }

    if (X > 10 || Y > 10)
    {
        OpticalCenter = 199;
    }
	
    writeReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD, OpticalCenter);
    writeReg(ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE, (Y - 1) << 4 | (X - 1));
}

Hi @PaulAtST, did You sucesfully update register in your VL53L1X ?
I sending updated values of ROI and nex when I read register, I got default value again.
sensor.writeReg(VL53L1X::ROI_CONFIG__MODE_ROI_XY_SIZE, 0xAA);

but
uint8_t roi = sensor.readReg(VL53L1X::ROI_CONFIG__MODE_ROI_XY_SIZE);
return always 0x85

@markg85 and @PaulAtST, thanks for looking into this and sharing what you did. I just published an update to the library that adds a set of functions for working with the ROI. It is based on and very similar to the ULD API functions like what you posted.

@brzezinol, if you're still having trouble, it looks like you might be accessing the wrong register. I don't think the API uses ROI_CONFIG__MODE_ROI_XY_SIZE to configure the ROI; it uses ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE.

Hi @kevin-pololu,

Thank you for adding that! Just makes my code require one less custom branch to work :)