Campus Corn´elio Proc´opio Coordena¸c˜ao de Eletrot´ecnica
Sensor ´
optico em quadratura: leitura via Arduino
Autor: Prof. Alessandro N. Vargas
Objetivo
Entender o funcionamento do Sensor baseado em encoder rotativo por quadratura, e aprender como determinar a posi¸c˜ao de um motor quando acoplado a este Sensor.
1
Introdu¸
c˜
ao
Os sensores baseados em encoders ´opticos s˜ao disposi-tivos eletrˆonicos-mecanicos capazes de gerar pulsos lu-minosos, que s˜ao lidos por um sensor ´optico. Quando ocorre o movimento rotacional de um eixo, pequenas janelas permitem a passagem da luz emitida por um LED, enquanto as paredes absorvem a luz (veja ima-gem). No outro lado do dispositivo, h´a um sensor que recebe a luz do LED e envia para um microcontro-lador. O microcontrolador ent˜ao gera uma tens˜ao de +5V somente durante o intervalo de tempo enquanto a luz atravessa a janela, e gera 0V quando n˜ao h´a luz. Por isso, enquanto o eixo do encoder ´optico est´a sendo rotacionado, pulsos de +5V ou 0V s˜ao constantemente gerados.
1.1 Como funciona o encoder de quadratura
O encoder de quadratura tem esse nome porque ele ´e composto de dois canais, e a posi¸c˜ao das janelas faz com que o sinal emitido sempre esteja defasado de 90 graus.
Na verdade, o c´odigo do disco dentro do encoder cont´em dois canais, normalmente cha-mados de Canal A e Canal B. As pistas/trilhas desses canais s˜ao defasados em 90 graus conforme a imagem.
Em aplica¸c˜oes onde a detec¸c˜ao de dire¸c˜ao ´e necess´aria, o microcontrolador pode deter-minar a dire¸c˜ao do movimento com base na rela¸c˜ao de fase entre os Canais A e B. Como ilustrado na figura abaixo, quando o codificador de quadratura est´a rodando no sentido dos ponteiros do rel´ogio, o seu sinal mostrar´a o sentido do canal A, gerando a contagem de um pulso, e o inverso ocorrer´a quando o codificador de quadratura girar no sentido anti-hor´ario. Al´em da dire¸c˜ao, a posi¸c˜ao tamb´em pode ser monitorada com um codificador de quadra-tura produzindo outro sinal conhecido como “ marker ”, “index ” ou “Z channel ”. Este sinal Z, produzido uma vez por revolu¸c˜ao completa do codificador de quadratura, ´e freq ˜A1
4entemente
usado localize uma posi¸c˜ao espec´ıfica durante uma rota¸c˜ao de 360 graus.
1.2 Quando usar codificadores de quadratura
Os codificadores de quadratura s˜ao usados na detec¸c˜ao e no comprimento da posi¸c˜ao bidirecional, sempre em aplica¸c˜oes de medi¸c˜ao e/ou posi¸c˜ao angular.
No entanto, em alguns aplicativos start-stop unidirecionais, ´e importante ter informa¸c˜oes bidirecionais (Canal A & B) mesmo se a rota¸c˜ao reversa do eixo n˜ao for antecipada. Um erro em contagem poderia ocorrer com um codificador de canal unico devido `a vibra¸c˜ao da m´aquina, mas tal erro ´e evitado quando usamos dois canais.
Utilizando um codificador de quadratura, o contador monitora a transi¸c˜ao em sua rela¸c˜ao com o estado do canal oposto, e pode gerar informa¸c˜oes de posi¸c˜ao confi´aveis, portanto alcan¸cando maior resolu¸c˜ao com encoders em quadratura
Quando mais resolu¸c˜ao ´e necess´aria na aplica¸c˜ao, ´e possivel que o contador conte as bordas traseiras do trem de pulso do codificador de quadratura de um canal, e disto se dobra (x2) o numero de pulsos por revolu¸c˜ao. Contando tanto o inicio quanto o final de bordas de ambos os canais de um codificador de quadratura, quadruplicaremos (x4) o numero de pulsos por revolu¸c˜ao. Como resultado, 2.000 pulsos por volta podem ser gerados a partir de uma quadratura de 500 CPR—count per revolution (ou 500 janelinhas).
PROCEDIMENTOS DE SEGURAN ¸CA
1. Monte o circuito indicado e certifique-se de que todos os elementos seguem exatamente o diagrama indicado no experimento.
2. Ap´os autoriza¸c˜ao do monitor ou professor, ligue a alimenta¸c˜ao.
3. Mudan¸cas no circuito devem ser feitas sempre com equipamento DESLI-GADO.
Experiˆ
encia 1 – Gera¸
c˜
ao de pulsos ´
opticos no Oscilosc´
opio
Monte no protoboard o circuito mostrado na Fig. 1. Use R = 3.3KΩ.• Porta 4 sensor no +5V do Arduino. • Porta 1 sensor no GND do Arduino.
• Portas 5,3,2 do sensor nos resistores (veja a imagem).
• Conecte o Oscilosc´opio da seguinte forma: A 1a. ponta de prova do Oscilosc´opio co-nectada no Ponto CH B. O Terra do Oscilosc´opio no GND.
• Conecte o Arduino no PC usando o cabo USB.
• Gire lentamente o Eixo do Motor. Aumente a velocidade de giro do motor. Verifique o Oscilosc´opio. Voce deve estar vendo um “trem de pulsos”. Obtenha uma foto usando o Smartphone.
• Ap´os concluir o item anterior, DESLIGUE o Oscilosc´opio. Mantenha o mesmo circuito para a pr´oxima experiencia.
Experiˆ
encia 2 – Usando o Arduino como Decodificador de
en-coder de quadratura
Siga atentamente os passos abaixo.
• Mantenha o circuito da experiencia anterior.. • Conecte o “Ponto CH B” na Porta 2 Arduino. • Conecte o “Ponto CH A” na Porta 3 Arduino.
• Suba o c´odigo a seguir no Arduino. Relembre de escolher a COM correta.
• Dentro do IDE Arduino, abra o “monitor serial”, escolha velocidade 9600, e Verifique se h´a informa¸c˜ao sendo mostrada.
• Verique o serial “monitor serial”.
• No teu experimento, pode-se afirmar que ´e necess´ario 1400 ou 2000 ou 4000 pulsos para encontrar na pr´atica uma volta completa do eixo? Quantos pulsos voce observou? • Obtenha foto usando o Smartphone.
/* *Quadrature Decoder */ #include "Arduino.h" #include <digitalWriteFast.h> // Quadrature encoders // Left encoder #define c_LeftEncoderInterruptA 0 #define c_LeftEncoderInterruptB 1 #define c_LeftEncoderPinA 2 #define c_LeftEncoderPinB 3 #define LeftEncoderIsReversed volatile bool _LeftEncoderASet; volatile bool _LeftEncoderBSet; volatile bool _LeftEncoderAPrev; volatile bool _LeftEncoderBPrev; volatile long _LeftEncoderTicks = 0; void setup()
{
Serial.begin(9600); // Quadrature encoders // Left encoder
pinMode(c_LeftEncoderPinA, INPUT); // sets pin A as input digitalWrite(c_LeftEncoderPinA, LOW); // turn on pullup resistors pinMode(c_LeftEncoderPinB, INPUT); // sets pin B as input digitalWrite(c_LeftEncoderPinB, LOW); // turn on pullup resistors
attachInterrupt(c_LeftEncoderInterruptA, HandleLeftMotorInterruptA, CHANGE); attachInterrupt(c_LeftEncoderInterruptB, HandleLeftMotorInterruptB, CHANGE); }
{
Serial.print("Encoder Ticks: "); Serial.print(_LeftEncoderTicks); Serial.print(" Revolutions: ");
Serial.print(_LeftEncoderTicks/4000.0);//4000 Counts Per Revolution Serial.print("\n");
}
// Interrupt service routines for the left motor’s quadrature encoder void HandleLeftMotorInterruptA(){ _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB); _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA); _LeftEncoderTicks+=ParseEncoder(); _LeftEncoderAPrev = _LeftEncoderASet; _LeftEncoderBPrev = _LeftEncoderBSet; }
// Interrupt service routines for the right motor’s quadrature encoder void HandleLeftMotorInterruptB(){ // Test transition; _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB); _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA); _LeftEncoderTicks+=ParseEncoder(); _LeftEncoderAPrev = _LeftEncoderASet; _LeftEncoderBPrev = _LeftEncoderBSet; } int ParseEncoder(){
if(_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && _LeftEncoderBSet) return 1; if(_LeftEncoderASet && !_LeftEncoderBSet) return -1; }else if(!_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && !_LeftEncoderBSet) return 1; if(_LeftEncoderASet && _LeftEncoderBSet) return -1; }else if(!_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && !_LeftEncoderBSet) return 1; if(!_LeftEncoderASet && _LeftEncoderBSet) return -1; }else if(_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && _LeftEncoderBSet) return 1; if(!_LeftEncoderASet && !_LeftEncoderBSet) return -1; }
}
Para executar o c´odigo abaixo em casa, voce precisa fazer o download dos arquivos do Link e instalar na tua vers˜ao IDE do Arduino em casa.
https://code.google.com/archive/p/digitalwritefast/
Relat´orio:
Fa¸ca o relat´orio apresentando o seu entendimento sobre o experimento, responda a per-guntas (se houver), e mostre imagens e/ou gr´aficos.