Problemas para medir o rpm de um motor com encoder.

Oi, pessoal, tudo bem?

Faz um bom tempo que eu estou tentando contar pulsos com um encoder aqui em casa por meio de um motor 12V e um arduino UNO... O Encoder contabiliza e mostra perfeitamente no monitor serial quando o motor é girado manualmente de forma devagar, porém, há um problema: Ocorre quando o motor está girando, pois o mesmo possui 64 furos, mas o Encoder leva cerca de 7 SEGUNDOS para detectar  64 furos,  totalizando assim, uma volta... Obviamente o motor já deveria ter dados muito mais voltas neste tempo, mas o encoder aparentemente não é capaz de informar isso de forma rápida e instantânea para o arduino.
Com isso, vem a dúvida, onde está o problema?


* Na programação?;

*No Encoder?;

*No arduino?;

*Na rotação do motor (já alterei muitas vezes com um transistor e as variações são mínimas);

*No circuito ligado ao ENCODER?

Eu já experimentei muitas coisas diferentes, testei vários valores de resistores para o Led Infravermelho (entre 180R e 220R, pois a partir de 330R ele não detecta mais);

Testei diversos valores de resistor para o coletor do fototransistor;

Alterei a velocidade do motor diversas vezes, mas o encoder continua com dificuldade para ler em tempo real.

Em anexo eu estou deixando o circuito e a programação do encoder. Obs.: Eu também utilizei um potenciômetro de 10K para regular o sinal PWM na base do transistor BC548, no caso, o A0 é referente a entrada analógica do arduino, o port 3 é o sinal PWM direcionado a base do transistor. Também utilizei um resistor e um Led ligados em série no port 13 para representar o estado do encoder (se ele está detectando um furo ou não)

Programação:



const int encoderIn = 8;                // Entrada para o arduino interpretar quando um furo for detectado
const int statusLED = 13;            // Saída para o LED de teste
int motorDC = 3;                         // Saída PWM no port 3 para o controle do motor DC 12V 
unsigned int analogPin = A0;       // Declara o analogPin como variável do tipo int com valores positivos

float valpotenciometro = 0;           //Variável para armazenar o valor lido do potenciometro
int detectState=0;                       //Variável para ler o Status do Encoder
int ContFuros=0;                        //Variável para contar o número de Furos detectados pelo Encoder
int NumeroVoltas=0;                   //Variável para informar quantas voltas foram dadas
float PosicaoGraus=0;                //Variável para informar a posição em graus do motor 


void setup()
{
     Serial.begin(9600);
     pinMode(analogPin, INPUT); //Definindo o sinal enviado pelo potenciômetro (pino A0) como entrada
     pinMode(motorDC, OUTPUT); //Definindo o sinal PWM (pino 3) como saída
     pinMode(encoderIn, INPUT); //Definindo o sinal do encoder (pino 8) como entrada
     pinMode(statusLED, OUTPUT); //Definindo o LED de status do encoder (pino 13) como saída
}
void loop()
{
     valpotenciometro = analogRead(analogPin); //relacionando o valor do potenciômetro com do PWM
     int pwm = map(valpotenciometro, 0, 1023, 0, 255);
     analogWrite(motorDC, pwm);
     Serial.println(pwm);

     detectState=digitalRead(encoderIn);
     if (detectState == HIGH) //Se o encoder detectar o furo, o mesmo irá...
     {
          digitalWrite(statusLED, HIGH); //Led de status acende
          ContFuros=ContFuros + 1; //O número de Furos contados será acrescentado em uma unidade
         PosicaoGraus=PosicaoGraus + 5.538; //A nova posição do disco será acrescida de 5.538 graus
         while(digitalRead(encoderIn)==1);
         {
               if(PosicaoGraus>=360)
               {
                     PosicaoGraus = 0;
               }
      }
}
      else
      {
               digitalWrite(statusLED, LOW); //Deixa o Led de status em nível baixo.
      }
Serial.print("\tNúmero de voltas:");
Serial.print(NumeroVoltas); //Mostra o número de voltas que infelizmente cresce a cada 7 segundos
Serial.print("\tpulsos: ");
Serial.print(ContFuros); //Mostra o número de furos contados que estranhamente demoram para ser contabilizados.
Serial.print("\tPosição em graus: ");
Serial.println(PosicaoGraus); //"Posição em graus do motor"


if(ContFuros>64)                               //Se a quantidade de furos for maior do que 64......
{
NumeroVoltas = NumeroVoltas +1;        
ContFuros = 0;                                 //Então o motor deu uma volta completa    
}


}

Exibições: 2695

Anexos

Responder esta

Respostas a este tópico

Fique sabendo que a contagem de tempo com os timers do Arduino tem uma taxa de erro significativa. 

Desenvolvi uma técnica de medição que reduz esse erro e dá mais precisão.

Assim que eu tiver tempo divulgarei o meu projeto. Aguardem. 

 

Boa tarde, José.

Interessante, no meu caso, um fator importantíssimo é o de detectar todas vezes que ocorre alguma borda de descida ou subida para a detecção dos furos, no caso, o Elcids Chagas utilizou diversas técnicas para evitar que o processamento dos dados “atrapalhem” a contabilização dos Pulsos, além da interrupção, que é algo primordial na hora de fazer um código para o encoder. Eu não sabia da existência de interrupções no arduino rsrsrs, ainda bem que houve a menção disso lá em cima, tenho certeza de que será muito útil para projetos futuros.

Estou curioso para ver tal técnica!

Abraços

              Lucas

Boa tarde, José.

Eu cheguei a pesquisar e vi o módulo, achei interessante pelo fato de tudo já estar integrado no próprio módulo. No caso, o disco possui 64 furos e não sei dizer ao certo as informações sobre o RPM do motor, apenas sei que ele é de 12V e consome cerca de 50mA sem trabalhar com carga, mas o meu problema já foi solucionado rsrs, só restaram algumas dúvidas com relação ao penúltimo comentário, mas muito obrigado pela dica!

Abraços,

              Lucas

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço