I did some tests with my US sensors and found that both indeed return the wrong distance occasionally. However, in my case these are not the small distances returned too large, but the 128+ distances returned too small. The difference, as janjachnik point out, being 128 (-128 in my case).
I took a look at the firmware code to see how the US sensor is controlled. It is basically a I2C sensor with some special timing requirements and non-standard clock-pulse between write and read. Fortunately, the firmware has been designed to support this kind of special I2C sensors without a dedicated firmware implementation. So, you can write your own driver in C or Python running on the RPi.
Here is my python implementation for the Lego US sensor:
from BrickPi import *
I2C_PORT = PORT_1
I2C_SPEED = 8 #define US_I2C_WAIT 7
I2C_DEVICE_INDEX = 0
LEGO_US_I2C_ADDR = 0x02
LEGO_US_CMD_REG = 0x41
LEGO_US_CMD_OFF = 0x00
LEGO_US_CMD_SS = 0x01
LEGO_US_CMD_CONT = 0x02
LEGO_US_CMD_EVNT = 0x03
LEGO_US_CMD_RST = 0x04
LEGO_US_DATA_REG = 0x42
BrickPi.SensorType[I2C_PORT] = TYPE_SENSOR_I2C_9V
BrickPi.SensorI2CSpeed[I2C_PORT] = I2C_SPEED
BrickPi.SensorI2CDevices[I2C_PORT] = 1
BrickPi.SensorSettings[I2C_PORT][I2C_DEVICE_INDEX] = BIT_I2C_MID | BIT_I2C_SAME
BrickPi.SensorI2CAddr[I2C_PORT][I2C_DEVICE_INDEX] = LEGO_US_I2C_ADDR
BrickPi.SensorI2CWrite [I2C_PORT][I2C_DEVICE_INDEX] = 1
BrickPi.SensorI2CRead [I2C_PORT][I2C_DEVICE_INDEX] = 1
BrickPi.SensorI2COut [I2C_PORT][I2C_DEVICE_INDEX] = LEGO_US_DATA_REG
print "BrickPiSetupSensors failed."
sys.exit( 0 )
result = BrickPiUpdateValues()
if not result:
if(BrickPi.Sensor[I2C_PORT] & (0x01 << I2C_DEVICE_INDEX)):
dist = BrickPi.SensorI2CIn[I2C_PORT][I2C_DEVICE_INDEX]
Note that the I2C_SPEED value is actually a ‘speed limit’. A higher value increases the wait time between writes and reads from the sensor. In the firmware implementation it is set to 7. By increasing it to 8, I found that the wrong distance readings were gone.
I hope this helps for you too. Please, post your results.