Olá, estou precisando de uma ajuda, preciso medir o tempo de duração que um motor recebe alimentação, esse motor recebe alimentação por um período de tempo x para realizar um movimento de amplitude y.

  Eu sei que se a carga aplicada nesse motor variar e o tempo x for constante a amplitude do movimento também vai variar, porém o cliente quer aferir esse tempo.

  Para uma partida suave do motor foi feito uma rampa de aceleração linear por PWM e no final da rampa o motor recebe alimentação plena pelo tempo programado.

  Para medir esse tempo eu pensei em um acoplador óptico com o LED ligado em paralelo ao motor, assim quando esse recebesse alimentação o acoplador iria gerar uma interrupção no ARDUINO que daria início a uma contagem de tempo, depois eu monitoro o pino até que pare a alimentação do motor e meço o tempo decorrido.

  Para evitar que o PWM gere muitas interrupções eu a desabilito assim que vem o primeiro pulso, aí gero um atraso de 2 segundos que sei que é um intervalo maior que o tempo da rampa e menor que o tempo todo de alimentação do motor, após esse intervalo eu passo a monitorar o pino até que a alimentação do motor seja desligada.

  No geral funciona, mas o circuito faz duas medições para cada vez que o motor é alimentado, após várias análises eu percebi que se eu tirar a rampa de aceleração a medição ocorre apenas uma vez e se eu deixar a rampa ocorre duas vezes, é como se os pulsos do PWM fossem mais rápido do que o tempo que o programa leva para desabilitar a interrupção, aí ela acontece duas vezes.

Para testar eu estou usando dois ARDUINOS MEGA, um para medir o tempo e o outro para simular o controlador do motor, vou colocar o código dos dois para ver se alguém pode me ajudar.

Código que simula o controlador do motor:

#define    outPin     13                       //Pino que simula o motor
#define onTime 10000 //Tempo que o motor fica ligado
#define offTime 5000 //Tempo de motor desligado
void setup() { //Configurações diversas
pinMode(outPin, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.println("Arduino COM3 iniciado");
}

void loop() { //Loop
for (int x = 0; x /font> 255; x ++){ // Simula a rampa PWM
delay(2); //de partida do motor
analogWrite(outPin, x);
} //
digitalWrite(outPin, HIGH); //Garante nivel alto
delay(onTime); //Simula tempo de motor ligado
digitalWrite(outPin, LOW); //Simula motor desligado
delay(offTime); //Simula tempo de motor desligado
}
Código para medir o tempo do motor ligado:

#define       intPin     21                           //Entrada de interrupcao
volatile unsigned long contaIni = 0x00; //Contagem de tempo decorrido
volatile unsigned long contaEnd = 0x00; //Contagem de tempo decorrido
volatile unsigned int contaEve = 0x00; //Contagem de eventos
volatile bool intTrue = 0x00; //Flag para saber de hove interr

void
isrInt(){ //ISR da interrupcao
detachInterrupt(digitalPinToInterrupt(intPin)); //Desabilita interr
contaIni = millis(); //Salva tempo inicial
intTrue = 1; //Flag para indicar interrupcao
}
void setup() {
pinMode(13, OUTPUT);
Serial.begin(115200);
//Habilita interrpcao externa na borda de subida
attachInterrupt(digitalPinToInterrupt(intPin), isrInt, RISING); //
}
void loop() {
if (intTrue == 1){ //Se houve interrupcao
intTrue = 0x00; //Zera flag de interrupcao
delay(1500); //Aguarda tempo de PWM
while(digitalRead(intPin) == 1); //Aguarda desligar motor
contaEnd = millis(); //Salva tempo final
Serial.print ("Evento - "); //Saída serial
Serial.print (contaEve); //apenas para controle
Serial.print (" - Tempo = "); //Saída serial
Serial.println(contaEnd - contaIni); //Tempo decorrido
contaEve ++; //Incrementa evento
//Habilita interrupcao
attachInterrupt(digitalPinToInterrupt(intPin), isrInt, RISING);
}
}

Exibições: 337

Anexos

Responder esta

Respostas a este tópico

Olá, Renato.

   Em primeiro lugar, sugiro uma olhada no tópico Como postar, por minerin RV <-- LINK.

   Não sei se entendi bem, mas por que você está desabilitando a interrupção?

   Não é mais fácil simplesmente iniciar a contagem do tempo na primeira interrupção e ignorar as demais?

   A primeira interrupção seta um flag. Nas próximas, se este flag estiver setado, a interrupção nada faz.

   Como saber qual é a primeira interrupção? R: Aquela na qual o flag está resetado.

   Não esqueça de declarar este flag como volátil.

   Sempre que o sinal cair e ficar baixo por um tempo maior do que o maior tempo baixo do PWM, resete o flag, pois isto significa que o motor parou.

   Espero ter ajudado.

D.T. Ribeiro.

Bom dia,

conforme recomendaçao já feita pelo amigo DTR, remova o código da área de texto do seu tópico.

Sobre sua dificuldade:

Eu não usaria interrupt, pela complexidade que este uso tem, pois até durante o delay que vc usou ele pode ocorrer. 

Sugiro que no for que voce usa para ligar o motor voce , voce ligue um flag dizendo motorLigado = true,

e quando colocar o pino outPin em low, desligue o flag.

RV mineirin

Olá, não estava habituado a fazer isso, mas acho que ficou melhor a visualização. Obrigado pela dica.

Não tenho como fazer esse flag no for, pois esse for está rodando em outro ARDUINO, eu criei esse código para fazer simulações no laboratório, na prática eu só tenho acesso à alimentação do motor, ou seja, eu só posso monitorar se tem ou não alimentação no motor e medir o tempo que ele recebe essa alimentação.

De qualquer forma obrigado pelo retorno.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço