Inconsistent results from the ultrasonic sensor

I use RobotC 4.27 (the latest) with my VEX IQ (“brain” at 1.13, distance sensor “up to date”) and I am getting inconsistent results from the ultrasonic sensor when I set the max range to anything 1500 or over. So, for example, when I set the max range to 1200 I get accurate readings for distances of 1010 and 689 in the RobotC debugger. If I change the max range to 1500 without changing the position of the robot with respect to a flat wall I get a reading of 1252. If I set the max range back to 1200 without moving the robot I get the correct value of 689 again.

Eli at VEX was kind enough to send me another sensor but the results are the same. Has anyone seen anything like this?

Hey Reisswolf,

I’ve done some investigating with the distance sensor and found some results for you.

  1. The distance sensor defaults at “initialization” to a value of 610mm - approximately 24 inches. This is per VEX’s specifications for the sensor.

  2. It’s a known issue that the sensor will get “ghosts” (fake reflections) when the Maximum is set too high. It looks like via your investigation that this value seems to be around 1500mm (~60 inches) - I’ve played around with the sensor quite a bit and found a similar value as well… Unfortunately there isn’t any easy way to enhance this behavior…

  3. But with that being said… there are ways you can play around with things like the SNR Threshold and Brightness (reflectivity) thresholds to try and enhance the distance - these are not typically things we’d recommend most users to do. Here’s some data

Signal-to-Noise Ratio (SNR) is a 1-byte (0-255) value with a scale of 0.37628 dB/cnt (236 = 0dB reference). To convert from counts to dB, use dB = (SNR – 236) * 0.37628.

Brightness is a measure of object reflectivity. It is also a 1-byte (0-255) value with a scale of 0.37628 dB/cnt (236 = 0dB reference). To convert from counts to dB, use dB = (SNR – 236) * 0.37628.

Filter Factor is the amount of filtering the signal back from the sensor receives.

Value - Filtering (F) - Time Constant
0 - 1 - 0 ms
1 - 0.5 - 58 ms
2 - 0.25 - 115 ms
3 - 0.125 - 173 ms
4 - 0.0625 - 230 ms
5 - 0.03125 - 288 ms
6 - 0.015625 - 350 ms
7 - 0.0078125 - 400 ms

Higher “F” values mean faster results, but won’t be as accurate. Lower “F” values will make your sensor more “sensitive”, but won’t be as quick to respond.

Lastly, here’s the program I used to debug/diagnose the distance sensor - along with some interactivity… you can use the “Global Variables” debugger window to set “bLockDistanceRange” to false, and then use the “nMaximumDistance” variable to adjust the maximum dynamically in your program. It’ll output all of the requisite information on the debugger screen and also the VEX IQ LCD.

Note: To modify a global variable, just click in the “value” column for that specific variable and type in a new value and press “enter” (or click away from the text box) to send the new value.


#pragma config(Sensor, port8,  distanceMM,     sensorVexIQ_Distance)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma debuggerWindows("Debugstream")

TDistanceInfo distanceDebugData;
int nMaximumDistance = 4000;
int nMaximumDistanceSent = 0;
bool bLockDistanceRange = true;

task displayDistanceData
{
    while(true)
    {
        clearDebugStream();
        getDistanceAdvanced(distanceMM, distanceDebugData);
        writeDebugStreamLine("---- Config Data ----");
        writeDebugStreamLine("Minimum Dist: %d", distanceDebugData.nMinimumDistance);
        writeDebugStreamLine("Maximum Dist: %d", distanceDebugData.nMaximumDistance);
        writeDebugStreamLine("SNR Threshold: %d", distanceDebugData.nSNRThreshold);
        writeDebugStreamLine("Brightness: %d", distanceDebugData.nBrightnessThreshold);
        writeDebugStreamLine("Filter Factor: %d", distanceDebugData.nFilterFactor);
        writeDebugStreamLine("Transmit Power: %d", distanceDebugData.nTransmitPower);
        writeDebugStreamLine("---- Largest Object Data ----");
        writeDebugStreamLine("Distance in MM: %d", distanceDebugData.nBrightestTargetDistance);
        writeDebugStreamLine("SNR in DB: %d", distanceDebugData.nBrightestTargetSNR);
        writeDebugStreamLine("Brightness in DB: %d", distanceDebugData.nBrightestTargetBrightness);
        writeDebugStreamLine("---- Closest Object Data ----");
        writeDebugStreamLine("Distance in MM: %d", distanceDebugData.n1stStrongestTargetDistance);
        writeDebugStreamLine("SNR in DB: %d", distanceDebugData.n1stStrongestTargetSNR);
        writeDebugStreamLine("Brightness in DB: %d", distanceDebugData.n1stStrongestTargetBrightness);
        writeDebugStreamLine("---- 2nd Closest Object Data ----");
        writeDebugStreamLine("Distance in MM: %d", distanceDebugData.n2ndStrongestTargetDistance);
        writeDebugStreamLine("SNR in DB: %d", distanceDebugData.n2ndStrongestTargetSNR);
        writeDebugStreamLine("Brightness in DB: %d", distanceDebugData.n2ndStrongestTargetBrightness);
        
        displayTextLine(0, "1st Closest: %d", getDistanceValue(distanceMM));
        displayTextLine(1, "2nd Closest: %d", getDistanceSecondStrongest(distanceMM));
        displayTextLine(2, "Largest Obj: %d", getDistanceMostReflective(distanceMM));
        displayTextLine(3, "Max Range: %d", getDistanceMaxRange(distanceMM));
        displayTextLine(4, "Min Range: %d", getDistanceMinRange(distanceMM));
        sleep(100);
    }
}



task main()
{
    startTask(displayDistanceData);

    while(true)
    {
        if((nMaximumDistance != nMaximumDistanceSent) && (bLockDistanceRange == false))
        {
            nMaximumDistanceSent = nMaximumDistance;
            setDistanceMaxRange(distanceMM, nMaximumDistance);
        }

        sleep(50);
    }
}