[BrickPi+] Would like to improve motor encoder readings from Python

I have a raspberry pi 3, and want to provide odometry data to a slam algorithm so my robot can navigate. Both motors will be running continuously at the same speed. My code takes the value from BrickPi.Encoder for both motor ports.
I find that for 100 successful readings (BrickPiUpdateValues() returns 0), they’ll be 50 readings with either, or both encoder values are 0.
Further they’ll be 7000 times that BrickPiUpdateValues() returns non 0.
Should I resign myself to “that’s as good as its gonna get”, or are there any suggestions for how to do better?
Thanks in advance,
Rolly

Hey rolly, can you post a snippet of the code? Are you polling all of the motors (all four?) and how frequently are you polling them?

I’m only driving 2 motors (running continuously) & am polling as fast as I can (slower didn’t eliminate the errors). The code follows.
ImotorTest.py (2.2 KB)

Hey @rolly, just looking at your code, one tip here: I would re-enable line 32, and have at least a 100 ms wait built in.

We’re having the same issue. The Java build ended up being too laborious to get up an running, so we switched to Python… and the encoders are returning 0 quite often.

100ms refresh seems too slow for us… do we really have to go that slow to avoid bad readings?

I’m attaching our code.

The UpdateValues function is returning 0 (because the If statement just below is running), but the line:

print "Motor " + i + " encoder: " + curr_val[i]

Is printing a legitimate encoder value for a bit, then turns to all 0s for a long while before finally coming back to encoder values again.

Thanks!

LEGO-Multi_Motor_Encoder_Test-ABK.py (12.3 KB)

Without the delay, averaged over 5 runs, running till I got 100 good readings, the results were:
86,000 times BrickPiUpdateValues() had a non zero return code,
22 times BrickPi.Encoder[leftMotor] read as 0,
24 times BrickPi.Encoder[rightMotor] read as 0.

With time.sleep(.1), averaged over 5 runs, running till I got 100 good readings, the results were:
63 times BrickPiUpdateValues() had a non zero return code,
60 times BrickPi.Encoder[leftMotor] read as 0,
51 times BrickPi.Encoder[rightMotor] read as 0

I can live with these, rather disappointing results - ignore any readings if BrickPiUpdateValues() return s nonzero, and ignore encoder readings if any of them are 0.
I was hoping someone from Dexter would lead me to dead on readings.

Your motorRotateDeg() is much more sophisticated than BrickPi’s motorRotateDegree().
When its not being afflicted with repeated 0s, its much more precise (why don’t you post it as a solution to the “problem-with-motorrotatedegree” thread).

What does an encoder reading of 0 signify
& what’s the best thing to do if you get one
(call BrickPiUpdateValues() immediately to get a replacement encoder reading)?

Hey rolly, I will try to have a look at the code and see if I can spot what’s going on. It should be performing better than you say it is, not sure what’s going on.