Encoder mysteriously missing count

I have a 360 cpr optical encoder (US Digital E4P), that I am using to try and control a DC motor through PID.

I am quite far along the way of getting that done, but am having some trouble with counting my encoder pulses.

Initially I used the Encoder library with both A and B channels connected to interrupt pins and thought it was working correctly as it was detecting about 60000 counts per second. However I found that if I marked the zero position and moved the encoder eround eratically up and down at high speed then returned it to zero that this zero point no longer lined up with the marked start position.

I assumed that somehow the arduino was loosing steps so I started using a dedicated encoder counter (Avago HCTL-2032) but I find I have the same problem.

With the encoder counter IC I can still move the encoder shaft around erratically and break the 0 point from the actual start point.

This leads me to think that there may be some problem with the encoder? As I don't think the number of CPS is too high for the Avago IC. Although I do notice that the error becomes larger if I spin the encoder faster, so this does suggest I am missing steps.

Any ideas?

Thanks!

Do you have the single-ended or differential version of the encoder?

There is nothing in the encoder data sheet about the nature of the encoder outputs, which is an inexcusable mistake.

They may be open collector, which means you need a suitable pullup resistor. Otherwise you may have read errors. Try 10K resistors to Vcc.

The encoder is single-ended. I will try placing these resistors.

Thanks,
Steve

It doesn't appear that placing 10k resistors to 5V, or to ground, solved the problems.

Wish I had an oscilloscope right now.

You didn't say where you got the encoder library. Try another.
If the wiring is correct and the encoder is working properly, you should never miss counts or lose position.

http://www.pjrc.com/teensy/td_libs_Encoder.html

I used this, but after I was having the accuracy problems I moved to this:

http://www.avagotech.com/docs/AV02-0096EN

Using this shield

Both systems seem to have accuracy issues so I was assuming it might be something else, like poor definition to the pulses so some don't get counted especially if they are very fast? The encoder generates something like 60 000 counts per second.

I will try a different library.

Would debouncing the A and B signals with capacitors help? Or would the encoder or counter IC already have something to do that?

S

catanimal:
The encoder generates something like 60 000 counts per second.

Did you say which Arduino you're using?

You might need a faster processor. Maybe one of the Arm based boards?

I'd think a Teensy or a Propeller could handle this.

I'm using the mega, I thought it might not be fast enough (although most people seem to think it should be up to it) so I switch to using a counter IC. But even the Avago counter IC still seems to be having issues, so I think the problem must be elsewhere?

Bouncing may be a problem, but you really need an oscilloscope to be sure. I haven't had this problem with any of the encoders I use (HP optical, and others from Pololu), so consider replacing the one you have. Considering the abysmal documentation, avoid US Digital.

US digital are meant to make pretty high quality encoders. We used them exclusively at the Robotics company I worked at. I will try and contact their support department but I doubt they will be that willing to help me once they work out I am just a hobbyist.

OK so I did a little more investigation.

The encoder is attached to the rear shaft of a geared dc motor, the ratio of the gearing is 14:1.

At the shaft the motor is able to go 4500 RPM (therefore 320 RPM out output shaft).

4500RPM/60 gives 75 revolutions per second at the encoder.

The encoder is 360 CPR with quadrature counting this is 1440 pulses (360*4) per rotation of the motor.

So if the motor is making 75 rotations per second and each rotation generates 1440 pulses then we are dealing with 108,000 increments of the counter per second.

I would have thought this would be within the capabilities of the Avago counter chip and of the E4P encoder but I may be wrong.

What I think may have happened during my tests is that I turned the gearbox output shaft by hand faster that the motor can actually go, so maybe taking the count frequency beyond the systems capabilities.

Contacted US Digital support and they tell me that the highest speed the encoders are rated for is 5000RPM so thinking that my 4500RPM motor may be close to the limit for them. Also perhaps I am able to exceed this speed when hand turning them (I am turning the geared output to back drive the motor so this is definitely possible.)

Another thing they suggested is that the encoder may not be aligned properly but I don't have the alignment tool to check!

Hope this may help someone else.
S

The encoder and gearbox combined lead to 5040 counts per revolution of the output shaft. Do you really need that high resolution?

Consider putting a lower resolution encoder on the motor shaft or putting the encoder you have on the gearbox output shaft.

I'm using it for a motion control head for super macro photography so was going for as accurate as possible, this is one of the only reasonably priced motors off the shelf motors I found so had to go with the given specs.

I am also trying to make the motion control head appropriate for realtime non macro camera movement so I need the high speeds for that also.

So if the motor is making 75 rotations per second and each rotation generates 1440 pulses then we are dealing with 108,000 increments of the counter per second.

I don't know about your hardware counter ic, but this is definitely faster than any interrupt driven quadrature reading software I have tested. The failure point is somewhere between 95K and 100K counts/second when reading full quadrature.

You can get twice the speed by reading only half the quadrature and still pick up direction. You may have enough resolution with the 360x4 to be OK in this mode.

EDIT: I just noticed you are using a MEGA, and this code is written for an UNO. I'm not certain of the pin changes required, but it maybe its that 8 and 9 become pin 53 and 52 and the pins/ports and interrupt vectors will transpose.

//Pin change interrupts on one pin of encoder pair A and B
//reads only half of quadrature states available

//PORTB pins; 
#define encoderPinA 8 //PB0
#define encoderPinB 9 //PB1


//variables changed within interrupt make volatile
volatile long encoderCount;

long lastEncoderValue = 0; 
int interval = 1000;
unsigned long prevDisplay;

void setup() { 

  Serial.begin (115200);
  Serial.println("Half of Quadrature Counts");

  pinMode(encoderPinA, INPUT_PULLUP); 
  pinMode(encoderPinB, INPUT_PULLUP);


  //enable pin change interrupts and set pin masks; 
  //interrupt pin selection or wires from encoder can be switched for correct cw/ccw

  PCICR |= (1<<PCIE0);//enable group interrupts on PORTB PCINT[7:0]
  PCMSK0 |= (1<<PCINT0);//enable interrupt pin 8
  //PCMSK0 |= (1<<PCINT1);//enable interrupt pin 9

}

void loop() {

  if (millis() - prevDisplay >= interval)
  {
    prevDisplay += interval;
    noInterrupts();
    long copyEncoderCount = encoderCount;
    encoderCount = 0;
    interrupts();
    
    Serial.println(copyEncoderCount);
    
  }

}

ISR (PCINT0_vect)//handle pin change interrupt for d8 to D13, triggered by 8
{ 
  if( bitRead(PINB,0)== bitRead(PINB,1)) //compare Pin 8 and 9
  {
    encoderCount++;
  } 
  else 
  {
    encoderCount--;
  }
}

"High speeds" and "as accurate as possible" are completely meaningless phrases.

What sort of positioning accuracy (in for example, mm or microns) and what sort of translational speed (meters/sec, mm/sec) do you really need?

It's rotational (pan tilt) so we are talking about degrees per second.

For wide landscape shots I want the unit to be able to do a full rotation as quickly as possible, hopefully less than 4 seconds, so I can possibly program it to do whip pans etc...

In terms of the rotational resolution required (number of points per full rotation of the camera) I have found from tests that to get smooth motion on close macro I need more than 50000 positions per rotation. I found this by making a prototype head driven by stepper motors geared to this number of PPR and still noticing stepping during macro video.

In the new head I have the motors hooked up to each axis by a 5:1 belt reduction so I get 50405 points per rotation.
With 4 times quadrature decoding I can get 5040
5*4 points per rotation. This comes to around 100,000 PPR for each axis.

There is no motor speed torque curve given for the motor I'm using, but I estimate it should be able to make the camera do a full rotation in less than 2 seconds.

Here is a CAD model of the setup, I am using it at the moment with 47:1 steppers, which provide small enough movements to not see stepping, but are unable to achieve high speeds, that is why I want to switch to DC encoded motors.

http://stevenbrace.co.uk/virtualrealityRENDERS/pantiltvr/untitled_VR.47.html

That encoder uses TTL levels, it won't interface directly, you'll need a 74HCT14 or similar
to convert its levels to normal CMOS.

You might if lucky get away with adding 1k pull-ups to each signal.

[ Am I really the first person to actually check the datasheet for something as basic as
VOH and VOL? ]