@#$%
http://www.farrellf.com/projects/hardware/2012-05-20_Brushless_Motors_as_Rotary_Encoders/
Brushless Motors as Rotary Encoders
May 20, 2012
Brushless motors can be used as rotary encoders.
When the rotor is turned the three coils will produce AC waveforms,
When the rotor is turned the three coils will produce AC waveforms,
each one-third out of phase with the next coil.
로터가 돌아갈때, 3개 코일들은 will 만들어낸다 AC 웨이브폼을,
각 1/3 out of phase with the next coil.
The period and amplitude depend on how fast the rotor is turned.
주기 and 진폭은 달려있다 on 얼마나 빨리 the 로터가 돌아갔는지.
Spinning the rotor faster will result in shorter periods and higher amplitudes.
Spinning the rotor faster will result in shorter periods and higher amplitudes.
돌리기 the roter를 더빨리 는 will 결과를 낳을것이다 in 더짧은 주기들을 and 더높은
Feeding those waveforms into op amps does the trick.
먹이기 those 웨이브폼들을 into op 앰프에 does the 트릭을 한다.
For this test I displayed a number on an LCD and used a buzzer to play a 5KHz tone for each clockwise movement and a 1KHz tone for each counter-clockwise movement.
The motor is from an old floppy disk drive.
The motor is from an old floppy disk drive.
이 첫테스트를 위해 난 디스플레이했다. a 넘버를 on an LCD상에
and 난 사용했다 a 버저를 to 플레이하기위해 a 5KHz 톤을 for 각 시계방향 이동을 and a 1KHz 톤을 for 각 반시계방향 이동을 위해.
The 모터는 from 오래된 플로피디스크.
The op amps are used to turn each AC waveform into a square wave that can be interrupted by the microcontroller:
오피앰프가 사용된다 to 각 AC웨이브폼을 into a 스퀘어 웨이브로 that can be 인터럽트되는 by the 마이크로컨트롤러에 의해:
If an op amp is used as a simple comparator (waveform going to one input,
with the other input tied to ground)
there will be problems if you spin the rotor slowly or very fast.
The slightest amount of noise will cause glitches.
(The output will swing high or low when it shouldn't.)
with the other input tied to ground)
there will be problems if you spin the rotor slowly or very fast.
The slightest amount of noise will cause glitches.
(The output will swing high or low when it shouldn't.)
만약 an op 앰프가 사용되면 as a 심플 비교기 (웨이브폼 going to 하나의 입력으로가는,
with the other 입력과 묶인 to GND에)
there will be 문제가 될수있다. if you 스핀하면 rotor를 매우느리게 or 매우빠르게.
The 매우작은 량 of 노이즈 will 유발할것이다. glitches를.
A little positive feedback adds hysteresis to the circuit.
This is simply a threshold which must be crossed
in order to get the output to swing high or low.
For my particular motor I needed the threshold to be approximately 70mV.
If the threshold is too low noise can still get through
and cause problems.
If the threshold is too high you will not be able to sense slow rotations.
The sweet spot will be different for every motor.
작은 (+) 피드맥은 더한다. 히스테리시스를 to the 회로에.
이건 간단히 a threshold(=기준점)이다. which must be 지나가야만하는
in order to 얻기위해 the 출력을 to 스윙하기위해 높게 or 낮게.
For 내 특정 모터에선, 난 필요했다. the threshold가 to be 대략 70mV가 되기위해.
If the threshold가 너무 낮다면 noise는 can sill get though(=통과)할수있다.
and cause 문제들을 야기할수있다.
If the threshold 가 너무 높으면, 넌 will not be able to 감지할 수 없다. 느린 회전들을.
그 sweet spot은 will be 다를것이다. for 매 모터마다.
Positive feedback supplies part of the op amp output back into the non-inverting input. A voltage divider is used to provide the feedback,
one end goes to the op amp output
and the other end goes to ground.
양의 피드백은 공급한다. part of the op amp 출력을 back into the 비반전 입력으로.
A 전압 분배기는 사용된다. to 제공하기위해 the 피드백을,
one end는 간다. to the op amp 출력으로
and the other end는 간다. to GND로.
To get 70mV when the output is high I needed two resistors with a 54.3:1 ratio.
To find the x:1 ratio, use: x = (output high voltage) / (desired mV) * 1000.
To minimize current flow the two resistors should add up to more than 1K.
The op amps I used will output about 3.8V
when supplied with 5V
so I used some 27K and 470 resistors that I had laying around
which gave a 66mV threshold.
To 얻기위해 70mV를 when the 출력이 high일때 난 필요했다. 2개 저항들이 with a 54.3:1비율이.
To 찾기위해 the x:1 비율을, 사용해라: x=(출력 고전압) / (원하는 mV) * 1000.
To 최소화시키기위해 전류 흐름을 the 2개 저항들은 should 추가해야한다. up to 1K이상.
The op amps 내가 사용한 will 출력할것이다. about 3.8V에 대해
when 공급됬을때 with 5V
so 난 사용했다. some 27K and 470 저항들을 that 내가 had 나돌아나니게한 주변에
which 준 a 66mV threshold(=기준점)를.
When an op amp input has a voltage below the negative supply voltage,
most op amps will effectively short that input to ground through a diode.
Since the motor is only being spun by hand
this will not be a problem but some current limiting resistors should be in series with all motor leads to be on the safe side.
Also keep the op amp voltage limits in mind
when using larger motors
or if you will be spinning the rotor at a significant speed.
When an op 앰프 입력이 갖고있을때 a 전압 below the 음의 공급 전압 아래의,
대부분의 op 앰프들은 will 효과적으로 short될것이다. that 입력 to GND through a 다이오드를 통한.
Since the 모터는 only being spun돌아가게될것이기때문에 by 손으로
이건 will not be a 문제가되지않을것이다. but some 전류 제한하는 저항들을 should be in 직렬로 with all 모터는 인도한다. to be on the 안전한 쪽으로.
(since 현재형, ~미래형)
Also keep the op 앰프 전압 제한들을 in mind에 담아라.
when 사용하는중일때 더큰 모터들을
or if 네가 will be 돌리고있는중일때 the rotor를 at a 상당한 스피드로.
I initially set up three op amps, one for each coil. This resulted in noticeable glitching at low speeds. The resistors I used for positive feedback have a 5% tolerance, resulting in the threshold for each coil being slightly different. I'm fairly certain that was the cause of the problem but I may be wrong. There is still a little glitching when using just two coils but it occurs far less often.
Here's the final schematic and code:
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
#include
LiquidCrystal lcd(9,7,6,5,4,3); // RS, Enable, D4, D5, D6, D7
int count = 0;
byte currentA, currentB, previousA, previousB = 0;
void setup() {
lcd.begin(16, 2);
previousA = currentA = digitalRead(10);
previousB = currentB = digitalRead(11);
}
void loop() {
previousA = currentA;
previousB = currentB;
currentA = digitalRead(10);
currentB = digitalRead(11);
if(previousA == LOW && previousB == LOW && currentA == HIGH && currentB == LOW) { // clockwise
count++;
tone(2, 5000, 2);
} else if(previousA == HIGH && previousB == HIGH && currentA == LOW && currentB == HIGH) { // clockwise
count++;
tone(2, 5000, 2);
} else if(previousA == LOW && previousB == LOW && currentA == LOW && currentB == HIGH) { // counter-clockwise
count--;
tone(2, 1000, 2);
} else if(previousA == HIGH && previousB == HIGH && currentA == HIGH && currentB == LOW) { // counter-clockwise
count--;
tone(2, 1000, 2);
}
lcd.setCursor(0, 0);
lcd.print(count);
lcd.print(" ");
}
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
with the other 입력과 묶인 to GND에)
there will be 문제가 될수있다. if you 스핀하면 rotor를 매우느리게 or 매우빠르게.
The 매우작은 량 of 노이즈 will 유발할것이다. glitches를.
A little positive feedback adds hysteresis to the circuit.
This is simply a threshold which must be crossed
in order to get the output to swing high or low.
For my particular motor I needed the threshold to be approximately 70mV.
If the threshold is too low noise can still get through
and cause problems.
If the threshold is too high you will not be able to sense slow rotations.
The sweet spot will be different for every motor.
작은 (+) 피드맥은 더한다. 히스테리시스를 to the 회로에.
이건 간단히 a threshold(=기준점)이다. which must be 지나가야만하는
in order to 얻기위해 the 출력을 to 스윙하기위해 높게 or 낮게.
For 내 특정 모터에선, 난 필요했다. the threshold가 to be 대략 70mV가 되기위해.
If the threshold가 너무 낮다면 noise는 can sill get though(=통과)할수있다.
and cause 문제들을 야기할수있다.
If the threshold 가 너무 높으면, 넌 will not be able to 감지할 수 없다. 느린 회전들을.
그 sweet spot은 will be 다를것이다. for 매 모터마다.
Positive feedback supplies part of the op amp output back into the non-inverting input. A voltage divider is used to provide the feedback,
one end goes to the op amp output
and the other end goes to ground.
양의 피드백은 공급한다. part of the op amp 출력을 back into the 비반전 입력으로.
A 전압 분배기는 사용된다. to 제공하기위해 the 피드백을,
one end는 간다. to the op amp 출력으로
and the other end는 간다. to GND로.
To get 70mV when the output is high I needed two resistors with a 54.3:1 ratio.
To find the x:1 ratio, use: x = (output high voltage) / (desired mV) * 1000.
To minimize current flow the two resistors should add up to more than 1K.
The op amps I used will output about 3.8V
when supplied with 5V
so I used some 27K and 470 resistors that I had laying around
which gave a 66mV threshold.
To 얻기위해 70mV를 when the 출력이 high일때 난 필요했다. 2개 저항들이 with a 54.3:1비율이.
To 찾기위해 the x:1 비율을, 사용해라: x=(출력 고전압) / (원하는 mV) * 1000.
To 최소화시키기위해 전류 흐름을 the 2개 저항들은 should 추가해야한다. up to 1K이상.
The op amps 내가 사용한 will 출력할것이다. about 3.8V에 대해
when 공급됬을때 with 5V
so 난 사용했다. some 27K and 470 저항들을 that 내가 had 나돌아나니게한 주변에
which 준 a 66mV threshold(=기준점)를.
When an op amp input has a voltage below the negative supply voltage,
most op amps will effectively short that input to ground through a diode.
Since the motor is only being spun by hand
this will not be a problem but some current limiting resistors should be in series with all motor leads to be on the safe side.
Also keep the op amp voltage limits in mind
when using larger motors
or if you will be spinning the rotor at a significant speed.
When an op 앰프 입력이 갖고있을때 a 전압 below the 음의 공급 전압 아래의,
대부분의 op 앰프들은 will 효과적으로 short될것이다. that 입력 to GND through a 다이오드를 통한.
Since the 모터는 only being spun돌아가게될것이기때문에 by 손으로
이건 will not be a 문제가되지않을것이다. but some 전류 제한하는 저항들을 should be in 직렬로 with all 모터는 인도한다. to be on the 안전한 쪽으로.
(since 현재형, ~미래형)
Also keep the op 앰프 전압 제한들을 in mind에 담아라.
when 사용하는중일때 더큰 모터들을
or if 네가 will be 돌리고있는중일때 the rotor를 at a 상당한 스피드로.
I initially set up three op amps, one for each coil. This resulted in noticeable glitching at low speeds. The resistors I used for positive feedback have a 5% tolerance, resulting in the threshold for each coil being slightly different. I'm fairly certain that was the cause of the problem but I may be wrong. There is still a little glitching when using just two coils but it occurs far less often.
Here's the final schematic and code:
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
#include
LiquidCrystal lcd(9,7,6,5,4,3); // RS, Enable, D4, D5, D6, D7
int count = 0;
byte currentA, currentB, previousA, previousB = 0;
void setup() {
lcd.begin(16, 2);
previousA = currentA = digitalRead(10);
previousB = currentB = digitalRead(11);
}
void loop() {
previousA = currentA;
previousB = currentB;
currentA = digitalRead(10);
currentB = digitalRead(11);
if(previousA == LOW && previousB == LOW && currentA == HIGH && currentB == LOW) { // clockwise
count++;
tone(2, 5000, 2);
} else if(previousA == HIGH && previousB == HIGH && currentA == LOW && currentB == HIGH) { // clockwise
count++;
tone(2, 5000, 2);
} else if(previousA == LOW && previousB == LOW && currentA == LOW && currentB == HIGH) { // counter-clockwise
count--;
tone(2, 1000, 2);
} else if(previousA == HIGH && previousB == HIGH && currentA == HIGH && currentB == LOW) { // counter-clockwise
count--;
tone(2, 1000, 2);
}
lcd.setCursor(0, 0);
lcd.print(count);
lcd.print(" ");
}
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
@#$%