something like:
The circuit building turned out pretty well. The HDD had a BLDC with 3 pins(whye windings) so i used the following scheme, but only the first two Op-Amps. One of the windings(pin) is a reference to the other two windings and used to determine direction. Signal 1 and 2 go to digital ports 2 and 3 on the Arduino for a 3 pin motor.
VCC(5v) and GND also need to be connected. |
Code that someone posted that is more efficient, but i don't understand: Reading Encoder Gray code 2 bit
Pics:
Encoder and needed LM324N IC. Also the joystick breakout cable is there. |
#define EncPinA 2
#define EncPinB 3
volatile unsigned int EncPos = 0;
void setup()
{
pinMode(EncPinA, INPUT);
digitalWrite(EncPinA, HIGH);
pinMode(EncPinB, INPUT);
digitalWrite(EncPinB, HIGH);
attachInterrupt(0, EncA, CHANGE); // encoder pin on interrupt 0 (pin 2)
attachInterrupt(1, EncB, CHANGE); // encoder pin on interrupt 1 (pin 3)
Serial.begin (115200);
}
void loop()
{
//FREE for a MIDI interface(turntables?) or something!
}
void EncA(){
// look for a low-to-high on pin A
if (digitalRead(EncPinA) == HIGH) {
// check pin B to see which way encoder is turning
if (digitalRead(EncPinB) == LOW) {
EncPos = EncPos - 1; // CW
}
else {
EncPos = EncPos + 1; // CCW
}
}
else // must be a high-to-low edge on pin A
{
// check pin B to see which way encoder is turning
if (digitalRead(EncPinB) == HIGH) {
EncPos = EncPos - 1; // CW
}
else {
EncPos = EncPos + 1; // CCW
}
}
Serial.println (EncPos, DEC);
// use for debugging - remember to comment out
}
void EncB(){
// look for a low-to-high on pin B
if (digitalRead(EncPinB) == HIGH) {
// check pin A to see which way encoder is turning
if (digitalRead(EncPinA) == HIGH) {
EncPos = EncPos - 1; // CW
}
else {
EncPos = EncPos + 1; // CCW
}
}
// Look for a high-to-low on pin B
else {
// check pin B to see which way encoder is turning
if (digitalRead(EncPinA) == LOW) {
EncPos = EncPos - 1; // CW
}
else {
EncPos = EncPos + 1; // CCW
}
}
}
It would be faster to read directly from the registers. I did like this in a similar setup:
ReplyDeletevoid leftencoder()
{
if((PIND & B00100100) == 0 || (PIND & B00100100) == 36)//pin 2 == pin 5
leftTachPos--;
else
leftTachPos++;
}
void rigthencoder()
{
if((PIND & B01001000) == 0 || (PIND & B01001000) == 72)//pin 3 == pin 6
rightTachPos--;
else
rightTachPos++;
}
it seemed to work ok with regular digital read, but it would probably make a big difference when im using multiple encoders on a racing wheel/pedals im testing. thanks
ReplyDelete"(PIND & B00100100) == 0"
ok since PORTD maps to Arduino digital pins 0 to 7, you are testing digital pin 2 and 5 to see if they are LOW, correct?
(PIND & B00100100) == 36
What is this; why 36?
http://www.arduino.cc/en/Reference/PortManipulation doesnt say anything about reading ports...
this is great though: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37871 ill read up
Hi, nice tutorial.
ReplyDeleteFor someone, like me, who doesn't have an oscilloscope, how can I decode which pin is which? Also, why do you connect the fourth pin to the opamp if you don't need it?
Thanks.
you can see in the image of my setup with the two opamps on the breadboard, that i didn't use that last wire. the three are there in the scheme to show what is needed for more precision/etc.
Deleteif the output is going the opposite way that you would like, just swap the two enocder wire.
Great article Lot's of information to Read...Great Man Keep Posting and update to People..Thanks Difference between ssd and hdd
ReplyDeleteit is enough 2 Comparators. after interrupt on one rising pin the second pin says if it clockwise is.
ReplyDelete