Close

Mwahahaha - No Mult!

A project log for anaQuad!

Reliably increase your quadrature-encoder's resolution using an ADC (or a bunch of comparators?)

eric-hertzEric Hertz 03/04/2016 at 11:102 Comments

Seriously! Only addition/subtraction, and sharp easily-detectable crossovers for each position...

And one of the difficulties of multiplication (which was my original plan, e.g. looking for channel A crossing channel B /2) is the fact that the measurements are not centered at 0, so the offset would've had to have been accounted-for (and scaled?) in such multiplications...

Here we just compare between A, ~A, B, ~B, A+N, B+N, ~A+M, and ~B+M.... The offset is unnecessary (though the amplitude is, for ~...).

Again, per the original plan, there's the specification/expectation that the update() function will be called at least once per transition, so knowing which transition was detected last, the only math that needs be executed in each call is that of the two nearest transitions, so worst-case scenario appears to be detecting position F, so say from position G...

switch(state)
{
  ...
  case G:
   //G->H
   if ( (1.35*AMPLITUDE - channelA) > channelA )
   {
     position++;
     state = H;
   }
   //G->F: 
   else if ( (1.35*AMPLITUDE + channelB) 
              < (AMPLITUDE - B))
   {
     position--;
     state = F;
   }
   break;
  case H: ....

AMPLITUDE is a constant, so 1.35*AMPLITUDE is also constant (and, ultimately, an integer), so worst-case scenario, one subtraction and comparison for G->H, which fails, then one addition and one subtraction and a comparison for G->F... and, plausibly, some math-reordering could occur, as well...? Subtract AMPLITUDE from each side, maybe? (Not sure 1.35 is right... just guessing).

Discussions

Eric Hertz wrote 03/04/2016 at 12:57 point

Though I didn't verify for certain that *every* case auto-aligns in the previous (double-resolution) case, it seems to be functioning properly... That is to say, when you start with the system in some unknown position, it seems to eventually figure out where it is and act accordingly... E.G. again, say the encoder's at position D, but the system boots up assuming it's at position A... several calls to the update() function will automatically cycle through until it reaches D (on the tests I ran).

This one, however... No. First check was position H... Say the encoder's just right of position H upon powerup, the system assumes it's at position A, and.... doesn't advance. It sticks thinking it's at position A.

Again, with the 2x system, I'm not *certain* it will automatically get to the right position, but *it might* whereas this one definitely won't. Scaling, on the other hand, *might* allow for it... I'm not sure. 

Again, part of the reason this is also a nice feature, besides the power-up initial-state-finding, is that it also means that if somehow a few transitions are missed (e.g. the processor was busy), it'll eventually catch up. In this case that might only be possible for a few steps, rather'n a whole bunch. hmmm....

Wherein the question of multiplication might come back into play... Shift-Left/Right is usually a single (cycle) instruction... and even multiplication itself might be, as well... But still the concern of the bottom of the sine-waves being at 0, rather than the center... so, still thoughts.

  Are you sure? yes | no

Eric Hertz wrote 03/04/2016 at 11:18 point

Nono, worst-case is position K, detecting either J or L

  Are you sure? yes | no