Servers by jDrones

Understanding Wheel Encoder Parameters

I’ve installed my wheel encoders on my robot and am starting to set parameters per the wiki page on wheel encoders. I did not have much success this evening. I encountered a few issues:

  1. My rpm1 and rpm2 values are all over the place. I started with my robot up on chocks and driving both at a very slow speed and the rpm1 and rpm2 values matched each other pretty well, but went randomly negative and positive the whole time.

  2. Sometimes when I increased the throttle too much, the wheels would “lock up” and stay at that speed. Mission planner status values would turn static. If I disarmed and rearmed the Pixhawk, things would turn responsive again.

  3. Randomly I would get a “Bad Logging” error. I took the SD card out and reformatted it (lost a bunch of logs in the process, I’m a fool for not saving them) but still got the error. However, I think I was logging the whole time with that message. I’m not sure though.

Relevant parameters:

WENC_CPR = 28800
WENC_POS_X = 0.08
WENC_POS_Y = -0.249
WENC2_CPR = 28800
WENC2_POS_X = 0.08
WENC2_POS_Y = 0.249
WENC2_RADIUS = 0.127

Graph of rpm1 and rpm2:

Bin file here.

Any ideas on why the rpm readings are so erratic?

I guess you are overloading the pixhawk with 28800 CPR. Even at 1 rpm you get 480 impulses per second for one encoder.
Do you really need a resolution of 0.0125°?
This is a rover with wheelslip and all not a CNC machine.

Hi Sebastian,

Thanks for the response. No, I definitely don’t need that level of resolution, but for the same cost I could have purchased an encoder with 32CPR or 900CPR, so I opted to go with the higher resolution one. I mounted it to the input shaft of a 32:1 gearbox, which is where the 28800 number came from, 900 x 32. In hindsight I should have realized that was going to be awfully high.

I was able to connect the encoder to an Arduino Uno and had the motor running at 60-70RPM and it would read the encoders fine. So I guess my question is what is the upper CPR limit the Pixhawk can accept? When I was testing on the bench I had my motor hooked up to a 12V battery, but on my robot I supply the motor with 24V, so maximum operating speed is ~120RPM. So maybe the limit is somewhere in between those numbers?

An interesting side note, looking at the datasheet for the encoders I bought, the maximum rpm is 20,000 for a 900CPR encoder. But running the encoder at 60RPM results in 28,800 counts per tire revolution, which is beyond the rated limit of the encoder. But at that speed the encoder still worked okay on the bench with the Arduino. Maybe the encoder gets wonky at a speed between 60RPM and 120RPM.

What is odd to me is that even running the motor at a speed that the encoder and Pixhawk should definitely be able to read still results in the behavior I’m experiencing. I rebooted everything last night and started moving my wheels at a very slow speed, about ~1-3RPM, and right from the beginning rpm1 and rpm2 readings were all over the place. I’ll probably buy some lower CPR encoders and see if that improves things any.

Yeah… with that resolution you could make a 3D printer with your rover :slight_smile:

Its not fair to compare a single task running on baremetal to a multitask running on chibios, but you could certainly use a smaller size Arduino board as a ‘‘divide by N’’ front end to the FC.

It is again just a guess, but my DIY encoders stopped working/behaved erratically after I changed from Nuttx to Chibios. I really was lost at first, but then I had a bright moment and put a pullup resistor between VCC and signal. That cured the issue immediatly. If you have a 10kohm resistor at hand, you could try if it helps. For testing, I just pushed the legs of the resistor in the back of the servo connector, between VCC and signal.

1 Like

@count74, that’s very interesting. We’ve had a number of small fixes go into master related to setting output pins to be pull-ups. I wonder if master still requires the 10kOhm resistors or not…

Sebastian, did you put a 10kOhm resistor between both A and B and Vcc? Just making sure I understand.

Yes. Both signal lines go to seperate input pins, so both need to be pulled to a specific state. If pullup does not work, you can also try to pull the input pin down, with the resistor between signal and GND.

@count74 , I put a 10 kOhm resistor between both A and B signal lines and Vcc, but still got funky values like the graph above. I only tried it on one of the encoders, and the reported values were slightly off from the other encoder in addition to being all over the place. I also tried pulling them down to ground, with the same effect.

I received some 32CPR encoders in the mail today and tried them out with similar results (did not try the pull up/down resistor, will do that soon). However, this time the RPM values matched actual speed, but kept switching positive and negative. I forgot to grab the SD card from the Pixhawk so I don’t have logs to post yet.

@rmackay9 might be able to answer this question for me: are the rpm1 and rpm2 values in the HUD actual sensor outputs? Or are they massaged by the EKF before being reported? It was raining here today and so I had the robot up on chocks in the garage so the wheels could spin freely while the robot sat there. I am wondering if the EKF maybe inferred the rotation direction and kept switching positive and negative to jive with the other sensors reporting no robot translation or rotation. I probably have no idea what I’m talking about.

The more I think about it, I’m wondering if I didn’t just cross wire my A and B signals between encoders. When I rotated one wheel but not the other, both encoders reported oscillating RPM values close to zero. I hooked these 32CPR encoders up to the Arduino and got great rotation measurements just like I did with the 900CPR encoders.

Will do more testing this week.


The rpm values are reported from the wheel encoder driver. So these are the values being fed into the EKF. The RPM values are pretty low level though so if they aren’t working, certainly the position estimation (in the EKF) also won’t work. hope that helps

Thanks @rmackay9, that makes sense. I’m going to feel silly if it’s a wiring issue.

Alright guys, I am embarrassed. Had the encoders cross wired. Everything works great now. Thanks for the help!

I was using the 32CPR encoders when I figured out they were cross wired, I think I will swap them out with the 900CPR encoders to see how well (or even if) they perform, just out of curiosity.


Just to clarify, are you connecting the encoder AB to the FMU PWM OUT port of the Pixhawk 4?

@Reuben_Finch, I have a Pixhawk 1 so I set it up like they have it shown in the wiki on Aux Out 3, 4, 5, and 6. I think A and B for the left encoder goes on Aux Out 3 and 4. I hope that answers your question.

Thanks Drew,

Just to help any future users, ensure that you’re testing with a known working build. I was testing the encoders with a 3.6.1 dev build that doesn’t work. 3.5 works.


Hello, I have also tried rover 3.6, but the encoder is not ok, may I ask what is the solution?

Hello, I tried the rover 3.6 firmware and found that the encoder is not ok. Is it my parameter setting problem? Is there any solution?


Encoders on Rover-3.6 should definitely work. Can you provide a dataflash log file?

Thought I would add some information I discovered using my 900CPR encoders. My 32CPR encoders were working pretty well but I managed to fry them by reversing the polarity on the + and - pins.

So I decided to try out the 900CPR encoders. They work when the wheels are rotating at low RPMs, but once you hit a certain ceiling, the B/E LED on the right side of the Pixhawk turns blue and the wheels continue spinning at whatever rate they were prior to the LED coming on.

I’m guessing (someone can probably correct me) that the encoders are pulsing fast enough to hose up the Pixhawk? Everything in Mission Planner freezes up once the B/E LED comes on, too. Any ideas what might cause this? Once I hit the emergency stop on my rover and the wheels stop spinning, Mission Planner unfreezes, the B/E LED on the Pixhawk turns off, and everything goes back to normal.

Servers by jDrones