collapse

* Posts Recentes

Emulador NES em ESP32 por dropes
[Hoje às 15:31]


Arame de Estendal por almamater
[Ontem às 16:16]


O que é isto ? por SerraCabo
[12 de Abril de 2024, 14:20]


Amplificador - Rockboard HA 1 In-Ear por almamater
[11 de Abril de 2024, 20:46]


Meu novo robô por josecarlos
[29 de Março de 2024, 18:30]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]

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