collapse

* Links de Robótica

* Posts Recentes

Palavras Cruzadas por brunus
[Hoje às 01:13]


[Projecto] Bomba Airsoft por jm_araujo
[23 de Setembro de 2017, 16:54]


Apresentação por Tech_JA
[23 de Setembro de 2017, 09:19]


Medir Agua que está no Poço por filjoa
[21 de Setembro de 2017, 20:58]


URGENTE - display de 7 segmentos com backpack por helderjsd
[20 de Setembro de 2017, 12:30]


Preços e fabricantes de pcb por Sérgio_Sena
[19 de Setembro de 2017, 10:20]


Isaac Asimov - I, Robot por senso
[18 de Setembro de 2017, 03:41]


ic SL440 da Plessey? por senso
[16 de Setembro de 2017, 13:11]


Compra Colectiva RS-Amidata por brunus
[15 de Setembro de 2017, 22:31]


Ideias para construir um quadrúpede simples por zordlyon
[15 de Setembro de 2017, 10:18]

Autor Tópico: Encoders simples e interrupts  (Lida 692 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.088
    • 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 »