speed measurement of dc motor with encoder

hello,

I am trying to read the speed of a dc motor with encoder using arduino uno board. From the available information in arduino website I could write a program to read pulses using attachinterrupt. But in the program I used as well as in the examples I referred, they have used an encoder which gives either 12 pulse per rotation or 24 pulse for rotation. My actual motor's encoder gives 255 pulses for rotation. Can some one help me out with the situation and also tell me if there is a better way to write a program.

Here is my current program

It is just a test program to read the speed from the encoder

/* read a rotary encoder with interrupts
Encoder hooked up with common to GROUND,
encoder0PinA to pin 2, encoder0PinB to pin 4

*/

#define encoder0PinA 2
#define encoder0PinB 4

unsigned int encoder0Pos=0;
int newposition;
int oldposition;
int newtime;
int oldtime;
float vel;
void setup()
{

pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // turn on pullup resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // turn on pullup resistor
attachInterrupt(0, doEncoder, RISING); // encoDER ON PIN 2
Serial.begin (9600);
Serial.println("start"); // a personal quirk

}

void loop()
{
newposition = encoder0Pos;
newtime = (0.001*millis());
vel = (newposition-oldposition)/(newtime-oldtime);
Serial.print ("\n speed = ");
Serial.print (vel);
oldposition = newposition;
oldtime = newtime;
delay(1000);
}

void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
encoder0Pos++;
} else {
encoder0Pos--;
}

Serial.println (encoder0Pos, DEC);
}

Thanks in Advance

OK,
First, use the CODE tags when posting code to the forum. It is much more readable, and polite.

The number of pulses per rotation should not effect the code. At the most, you'd just have to change a couple of numbers to 255 to make it work. The code you posted doesn't care, it just reports the number of encoder ticks per second.

The proper declaration for the encoder position is:

volatile long encoder0Pos=0;

The 'volatile' keyword informs the compiler that the value could change behind its back (due to an interrupt in this case). Long instead of int because int is only 16 bits and that doesn't give you a lot of rotations before it rolls over. Also we want a signed number to handle roll over. What if your current encoder reading was 4, and then you moved 8 ticks back? Your delta would be 16K-4, which would give a huge velocity. OTOH, 4 - -4 is 8, which is what you want.

Likewise newposition and oldposition should be of type long.

The millis() function returns unsigned long, so newtime and oldtime should also be of that type.

As for velocity, you are calculating encoder ticks per second. Do you really need to know the fractional part of that? An int (or long) would do just as well, if we do the calculations right.

The setup function looks good.
The only thing to worry about in your main loop is the calculation of velocity. First of all, instead of multiplying by a fraction, use a little algebra and convert that to dividing by an integer. But you probably don't want to do that yet anyway, because it makes the calculation less accurate. You went to all the trouble of gathering the time in milliseconds, and then throw away 3 orders of magnitude of accuracy. The trick is to calculate value in high precision, and then convert to convenient units on the display. Also, I'm thinking that whatever this winds up in final form as, that delay statement won't always be there. Even if you leave it in, it decreases the response time of the velocity calculation. Plus the sketch isn't doing anything else while calling delay. But if you don't delay by at least 1 second, your velocity calculation is going to hit a divide by 0 situation. So use milliseconds to calculate the velocity. But dividing by milliseconds also loses significant digits from the velocity calculation. This can be fixed by doing the multiply before the division, which neatly gives us ticks per second again. Except this way we can handle sample intervals that are not exact multiples of 1 second.

Finally, do not put Serial print statements in your interrupt service routine (ISR). An ISR should be as short as possible. You are pushing it with two digitalRead statements as it is.

Leaving it looking something like this:

#define encoder0PinA  2
#define encoder0PinB  4

volatile long encoder0Pos=0;
long newposition;
long oldposition = 0;
unsigned long newtime;
unsigned long oldtime = 0;
long vel;

void setup()
{
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
  attachInterrupt(0, doEncoder, RISING);  // encoDER ON PIN 2
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk
}

void loop()
{
 newposition = encoder0Pos;
 newtime = millis();
 vel = (newposition-oldposition) * 1000 /(newtime-oldtime);
 Serial.print ("speed = ");
 Serial.println (vel);
 oldposition = newposition;
 oldtime = newtime;
 delay(250);
}

void doEncoder()
{
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
}

Enjoy,

The 'volatile' keyword informs the compiler that the value could change behind its back (due to an interrupt in this case)

Thanks a lot for the information but I have a small problem with the program. "volatile" keyword is not getting executed in my sketch. I am using arduino uno for programming. Can you tell me what might be the reason

No problem with 'volatile' keyword. Thanks a lot. My encoder is working great :slight_smile:

how can i control two encoder motor with connect metal detector sensor. Plzzz Explain with a programing

aquloveya:
how can i control two encoder motor with connect metal detector sensor. Plzzz Explain with a programing

I don't understand why you did not start a new Topic for your question as it does not seem to have anything in common with @madalan's problem.
You need to provide a lot more information.
Post links to the datasheet for the encoder motors.
Explain what the motors do for the metal detector.
Explain what you want your control system to be able to do.

What experience of Arduino projects do you have? Encoder motors are not the easiest thing to work with.

...R

hi
i read your code . i want to know that which encoder used for speed measurement?and what is circuit diagram or pin connection with encoder to arduino?