I have upgraded the motors in my robotic arm to sensored, brushless RC car motors. The hope was to reuse the Hall sensors to double as a rotary encoder, by tapping 2 Hall sensors and treating the 2 bits as a quadrature signal (a crude quadrature since 2 of the 4 states will be longer than the other 2).
This works when none of the motor phases are powered and I just rotate the motor manually. But once the stator coils are energized, the encoder no longer counts correctly: When running at low power, the counting is correct, but when running under high power, the count is monotonic (only increases or decreases) no matter if I run in reverse or forward.
I'm almost certain this is because of the stator coils overpowering the permanent magnets on the rotors. So is there still a way to use the Hall sensors as an encoder?
Sorry if this is an obvious question. I'd love to research this problem more if I had more time.
Update: I've measured the wave forms with my DSO quad and see the expected 120 degree separated signals (the measurement for phase C gets more inaccurate over time because I only had 2 probes, so I measured phases A & B first, then A & C, and then merged them.
When ESC speed is 0.1:
When ESC speed is 0.3:
Previously, I was using a hardware quadrature counter (EQEP module on a BeagleBone). At speed=0.3, this was counting backwards no matter if I do forward or reverse!
I then implemented quadrature counting on an LPC1114FN28 uController. The result was still bad at high speeds (count didn't change at all). The logic was:
void HandleGPIOInterrupt()
{
const uint8_t allowableTransitions[4][2] = {1, 2, 3, 0, 0, 3, 2, 1};
static int prevState = -1;
int state = phaseA | (phaseB * 2)
if (prevState != -1)
{
if (allowableTransitions[prevState][0] == state)
{
++rotations;
}
else if (allowableTransitions[prevState][1] == state)
{
--rotations;
}
}
prevState = state;
}
Then I got the idea to change the code to not update prevState until an expected state happens (to deal with glitches):
int state = phaseA | (phaseB * 2)
if (prevState != -1)
{
if (allowableTransitions[prevState][0] == state)
{
++rotations;
prevState = state;
}
else if (allowableTransitions[prevState][1] == state)
{
--rotations;
prevState = state;
}
else
{
// assume transition was a glitch
}
}
else
prevState = state;
Now the counting finally is correct in both directions, even at speeds higher than 0.3! But are there really glitches causing this? I don't see any in the waveforms?