Hi,
myself chitrarasan, i am a person new to arduino ,now I'm in a project where i have a motor which can run at 600 - 700 rpm. i like to know the position of the motor shaft with an orange incremental encoder and arduion uno , i wrote a simple code for measure the position. The concept of the code is
There is a start position in the circumference of the shaft which will be detected by a proximity sensor (working properly at all speeds) as soon as the start position is detected, the encoder will start the count. Then, as per the encoder value, two LEDs will go high and low. Then again, the start position will come the encoder value will reset and count from the beginning so the count is new in every rotation of the shaft.so that if a small error occurs in count, they will delete it in the next rotation .
int encoderPin1 = 2;// encoder input
int encoderPin2 = 3;//encoder out put
volatile int lastEncoded = 0;
volatile long encoderValue = 0;//variable containing encoder value
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
int led1 = 13;//led1
int led2 = 12; //led 2
int ir_on = 4;//proximity sensor input which is NPN type
int on;
int a = 0;
int b;
void setup()
{
Serial.begin (9600);
pinMode(ir_on, INPUT);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
}
void loop()
{
//Do stuff here
on = digitalRead(ir_on);
if (on == LOW)
{
b = 1;
encoderValue = 0;
}
if (b == 1)
{
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
Serial.println(encoderValue);
//delay(1000); //just here to slow down the output, and show it will work even during a delay
}
void updateEncoder()
{
if (on == HIGH)
{
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)/*The encoder has 2 digital pins that are either HIGH (1) or LOW (0) right? If we treat the pins as binary, we read them as 00, 01, 10, or 11. The sequence the encoder outputs while spinning clockwise is 00, 01, 11, 10 repeat.
Incremental Rotary encoder
So if you have a reading of 01, the next reading can either be 00 or 11 depending on the direction the knob is turned. So by adding the previous encoded value to the beginning of the current encoded value; we get 1 of 8 possible numbers (0001, 0010, 0100, 0111, 1000, 1011, 1110 & 1101) 1101, 0100, 0010 & 1011 all mean cockwise movement. 1110, 0111, 0001 & 1000 are all counter-clockwise.
So now we can say this: (sum is last reading + current reading)
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++; //clockwise movement
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --; //counter-clockwise movement*/
{
encoderValue ++;
}
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
{
encoderValue --;
}
lastEncoded = encoded;
}
//store this value for next time
// LEDs go high and low as per the encoder value value
if (encoderValue == 0)
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
if ((encoderValue >= 1 ) && (encoderValue <= 685))
{
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
}
if ((encoderValue > 685) && (encoderValue <= 2052))
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
if ((encoderValue > 2052 ) && (encoderValue <= 4104))
{
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
}
}
the code is working properly the only in slow speeds,but at higher speed the count is missing the numbers and going beyond encoders cpr value that is my encoder produces 4096 cpr per revolution but it counts 11,000 or more at very higher speed but my encoder is capable for 5000rpm so ,my hard ware is capable enough for my application ,so i cheked in other website it says the algorithum has to be optimised inorder to make it work for higher rpm.
and i have checked my proximity sensor and it works prity good at higher rpm.
encoder data sheet:
User-Manual-Orange-3806-OPTI-600-AB-OC-Rotary-Encoder-ROBU.IN_ (1).pdf (672.6 KB)