collapse

* Links de Robótica

* Posts Recentes

RN42 e TP-Link MR3020 por doiga
[Ontem às 19:22]


Ajuda Projecto IR / RF por senso
[Ontem às 13:15]


Recomendação de um opamp para um DAC r2r por Njay
[Ontem às 12:33]


Ideias para construir um quadrúpede simples por dropes
[21 de Novembro de 2017, 22:43]


Ajuda com TRIAC por senso
[17 de Novembro de 2017, 18:00]


TV LG White Screen por almamater
[15 de Novembro de 2017, 08:37]


Pergunta sobre prototipagem ( Pesquisa ) por luisjustin
[14 de Novembro de 2017, 23:22]


Medir Agua que está no Poço por Njay
[14 de Novembro de 2017, 13:28]


Amplificador audio por beirao
[12 de Novembro de 2017, 23:43]


Power_OK Enermax por edeweld
[12 de Novembro de 2017, 17:15]

Autor Tópico: Encoders simples e interrupts  (Lida 724 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline daniboy

  • Mini Robot
  • *
  • Mensagens: 1
Encoders simples e interrupts
« em: 16 de Fevereiro de 2013, 16:34 »
Boa tarde a todos,

sou um novato quanto a posts.
Estou a desenvolver um pequeno robot diferencial com 2 rodas acopladas a 2 motores DC.

Estou neste momento com problemas nas rotinas relativas aos encoders.
A ideia dos encoders era saber com precisão quanto as rodas rodaram, e de uma forma aproximada, tendo em conta o solo e os deslizamentos, poderia saber as deslocação do veiculo.

Não estou a usar encoders de quadratura, pois através do código sei se me encontro a andar em frente ou para trás, e por isso apenas uso um fio para detectar o estado do encoder (1 ou 0).
no meu caso pretendo contar as transições de 1 para 0.
A ideia passa por ligar o encoder aos interrupts e a cada transição, é gerada uma interrupção e executadas determinadas funções (incremento dos pulsos, calculo de distancias, etc).

a realidade é que ao usar os interrupts, estou a ter algumas dificuldades, porque basta o feixe ser interrompido, e o arduino fica a incrementar a variavel de pulsos.
este foi o codigo que estou a utilizar.

// CODE //

  int MotorA1 = 9;
  int MotorB1 = 10;
// variable to be updated by the interrupt
const int encoderPinA = 2;
int Pos, oldPos;
volatile int encoderPos = 0;
/* volatile variables are forced to reside in RAM,  not in registers */


void setup() {
 
  pinMode(encoderPinA, INPUT);
  digitalWrite(encoderPinA, HIGH);
  pinMode(MotorA1, OUTPUT);
  pinMode(MotorB1, OUTPUT);
  //enable interrupt 0 which uses pin 2
  //jump to the incrementa function on falling edge
  Serial.begin(9600);
 
  attachInterrupt(0, incrementa, RISING);
}


void loop() {
      analogWrite(MotorA1, 0);
      analogWrite(MotorB1, 110);

      uint8_t oldSREG = SREG;
     
      cli();
      Pos = encoderPos;
      SREG=oldSREG;
      if(Pos != oldPos){
        Serial.print("Numero de pulsos lidos: ");
        Serial.println(Pos);
        float pulsos;
        pulsos = Pos;
        float distancia;
        // 1cm equivale a 40 pulsos
        distancia = pulsos/40;
        Serial.print("Distancia percorrida: ");       
        Serial.println(distancia);
        Serial.print(" cm");
        oldPos = Pos;
      }

}   

// Interrupt service routine for interrupt 0

void incrementa() {
    digitalRead(EncoderPinA);
    encoderPos++;

}


Será que alguem tem alguma experiencia com este tipo de situação???

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.141
    • Tróniquices
Re: Encoders simples e interrupts
« Responder #1 em: 16 de Fevereiro de 2013, 16:48 »
O teu problema é provavelmente que nas transições estás a ter várias interrupções, e/ou a posição do encoder fica no limite da transição e "micro vibrações" ficam a movê-lo "micro passos" fazendo com que cause transições na linha.

O que deves começar por fazer é, quando detectas uma transição, ignorar transições durante algum tempo e só depois voltar a olhar para elas. Quanto tempo? Isso depende do teu encoder e da velocidade máxima que tencionas atingir. Tem que ser um tempo um pouco menor do que o tempo minimo (a velocidade máxima) que é suposto veres impulsos. Se ele der digamos 100 por volta e o teu veiculo atingir uma velocidade máxima equivalente a 5 voltas por segundo, o intervalo minimo entre impulsos será, ora 100 x 5 = 500 impulsos por segundo que corresponde a 1s/500 = 2 milisegundos, portanto digamos aí 1.5 - 1.75ms, é uma questão de experimentar valores perto do minimo de 2ms.

Se tivesses um osciloscópio podias confirmar isto, pois verias que nas transições as coisas não são tão simples como parecem ;)

p.s. O teu attach diz "RAISING" portanto é de 0 para 1, mas na verdade neste caso é indiferente ser 0->1 ou 1->0
« Última modificação: 16 de Fevereiro de 2013, 16:55 por Njay »