Neste post será tratado sobre a medição de distância percorrida através da integração do encoder com o microcontrolador Arduino. Esse procedimento será utilizado no projeto do Robô de Inspeção Tubular, que está sendo desenvolvido pelas alunas Julia Machado e Tamyres Fonseca.
O encoder consiste em um sensor que, na parte construtiva, possui um disco de vidro ou plástico com setores alternados de opacidade e transparência. Além disso, possui um LED emissor de luz e fotorreceptores, posicionados da maneira como demonstra a Figura 1.
Seu funcionamento se dá de maneira digital: quando o fotorreceptor detecta a passagem de luz através de um dos setores de transparência do disco, a saída do sensor terá estado lógico igual a 1 e no momento de opacidade apresentará estado lógico igual a 0. Dessa forma, será contado um pulso a cada vez que o primeiro evento se repetir. Considerando essa maneira digital de contagem dos pulsos, sendo conhecido como encoder incremental, é necessário o auxílio de um sistema de contagem, cujo responsável é o Arduino, no qual implementa-se uma programação capaz de realizar o processo de contagem dos pulsos.
Esse tipo de sensor é de fácil obtenção e baixo custo. Um par deles pode ser encontrado dentro de mouses PS2 (com esfera), para indicar o posicionamento do cursor no eixo “X” e no eixo “Y”.
A pinagem do plug PS2 é de acordo com a Figura 2, porém é necessário identificar os fios através de um teste de continuidade, ligando uma das ponteiras do multímetro diretamente no lugar onde o fio é soldado na placa e a outra nos pinos do PS2. Esse processo é feito com o intuito de retirar o plug PS2 do cabo, tornando cada fio independente para a conexão direta com o Arduino.
Como mostra a Figura 3, o circuito para medição de distância percorrida utilizando o encoder é bem simples, basta conectar a placa do mouse ao Arduino. A Tabela 1 mostra a pinagem que foi utilizada tanto para a montagem quando para a programação nesse post. A Figura 4 ilustra a montagem que foi realizada para desenvolver os testes de medição de distância percorrida.
Na programação é importante salientar a utilização da biblioteca PS2, a qual foi acrescida de algumas modificações, como pode ser observado a seguir:
#define MDATA 5 #define MCLK 6 void gohi(int pin) { pinMode(pin, INPUT); digitalWrite(pin, HIGH); } void golo(int pin) { pinMode(pin, OUTPUT); digitalWrite(pin, LOW); } void mouse_write(char data) { char i; char parity = 1; gohi(MDATA); gohi(MCLK); delayMicroseconds(300); golo(MCLK); delayMicroseconds(300); golo(MDATA); delayMicroseconds(10); gohi(MCLK); while (digitalRead(MCLK) == HIGH) ; for (i=0; i < 8; i++) { if (data & 0x01) { gohi(MDATA); } else { golo(MDATA); } while (digitalRead(MCLK) == LOW) ; while (digitalRead(MCLK) == HIGH) ; parity = parity ^ (data & 0x01); data = data >> 1; } if (parity) { gohi(MDATA); } else { golo(MDATA); } while (digitalRead(MCLK) == LOW) ; while (digitalRead(MCLK) == HIGH) ; gohi(MDATA); delayMicroseconds(50); while (digitalRead(MCLK) == HIGH) ; while ((digitalRead(MCLK) == LOW) || (digitalRead(MDATA) == LOW)) ; golo(MCLK); } char mouse_read(void) { char data = 0x00; int i; char bit = 0x01; gohi(MCLK); gohi(MDATA); delayMicroseconds(50); while (digitalRead(MCLK) == HIGH) ; delayMicroseconds(5); while (digitalRead(MCLK) == LOW) ; for (i=0; i < 8; i++) { while (digitalRead(MCLK) == HIGH) ; if (digitalRead(MDATA) == HIGH) { data = data | bit; } while (digitalRead(MCLK) == LOW) ; bit = bit << 1; } while (digitalRead(MCLK) == HIGH) ; while (digitalRead(MCLK) == LOW) ; while (digitalRead(MCLK) == HIGH) ; while (digitalRead(MCLK) == LOW) ; golo(MCLK); return data; } void mouse_init() { gohi(MCLK); gohi(MDATA); mouse_write(0xff); mouse_read(); mouse_read(); mouse_read(); mouse_write(0xf0); mouse_read(); delayMicroseconds(100); } char mstat; char mx; char my; int acc_x=0, acc_y=0; int tempo=0; void setup() { Serial.begin(9600); mouse_init(); } void loop() { mouse_write(0xeb); mouse_read(); mstat = mouse_read(); mx = mouse_read(); my = mouse_read(); acc_x+=mx; acc_y+=my; tempo=millis()/1000; Serial.print(mstat, BIN); Serial.print("\ttempo(s)="); Serial.print(tempo, DEC); Serial.print("\tX="); Serial.print(mx, DEC); Serial.print("\tY="); Serial.print(my, DEC); Serial.print("\tAcc_X="); Serial.print(acc_x, DEC); Serial.print("\tAcc_Y="); Serial.print(acc_y, DEC); Serial.println(); delay(1000); }
Os resultados obtidos com a execução dessa montagem foram satisfatórios. Através da janela Serial Monitor do software de programação do Arduino, é possível monitorar a contagem dos pulsos realizada por cada um dos encoders conforme a movimentação deles: quando movimentados no sentido horário, a contagem é incrementada, e quando movimentados no sentido anti horário, decrementada. A distância percorrida é dada pelo acúmulo dessa contagem. Além disso, é possível saber a quantidade de pulsos momentânea de cada movimentação e o tempo (em segundos) no qual foi realizada.