Pessoal boa tarde!

Fiz o seguinte código em C para o controle de um servo com 8051.

Funciona da seguinte maneira, tenho um sensor indutivo que detecta a presença de metais, enquanto ele não detecta meu motor permanece em 0º, detectando presença de metais ele vai pra 180º e depois de um tempo volta para a posição inicial.

Acontece o seguinte problema quando simulo no Proteus, ele começa em 0º com o acionamento do sensor vai pra 180º, mas ele volta muito rápido para a posição inicial, se alguem puder dar uma ajuda sobre a mudança de tempo ou até uma mudança estrutural fico muito feliz.

/* Programa para esteira seletora de materiais
versão 3.0 */

#include <at89x52.h> //biblioteca do at89s52
#include <delay.h> //biblioteca delay

//tempo servomotor 0º 1ms
//tempo servomotor 180º 2 ms
//inicio do timer para estouro do flag 65535-0500= 65035
//inicio do timer para estouro do flag 65535-2000= 63535
// colocar no registrador TL0 0xFE TH 0x0B
//colocar no registrador TL0 0xF8 TH 0x2F

int cont=0; //variável cont
#define motor P2_2 //saida motor P2_2
#define ligado P2_0 //saida led P2_0
#define sensor P3_2 //saida para sensor indutivo P3_2

void External_Interrupt () interrupt 0 { //rotina de interrupção P3_2

Timer_1 (); //chamando rotina de timer 1, para rotacionar motor para 180º
delay_ms(1000); // atraso de 1s
sensor=1; //nivel logico alto do sensor indutivo
}

void Timer_0 () interrupt 1 { //timer 0, motor 0º

TR0=0; //pausa timer para recarregar (Timer Stop)
TH0=0xFE; //recarrego Timer com o valor
TL0=0x0B; // 65035
TR0=1; //acionamento do timer para contagem

if (cont<1) { cont++; //condição para contagem de tempo, gerando pulsos
motor=1; } //motor nível lógico alto
else {
cont=0; //zero variavel cont
motor=0; } //motor nível lógico baixo

}


void Timer_1 () interrupt 3 { //timer 1, motor 180º
TR1=0; //pausa timer para recarregar (Timer Stop)
TH1=0xF8; //recarrego Timer com o valor
TL0=0x2F; // 63535
TR1=1; //acionamento do timer para contagem

if (cont<100){ cont++; // condição para contagem de tempo, gerando pulsos
motor=1; } //motor nível lógico alto

else {
cont=0; //zero variavel cont
delay_ms(200); //atraso de 200ms
motor=0; //motor nível lógico baixo
delay_ms(2000); // atraso de 2s para termino rotina
}
}

void main () { //rotina principal
EA=1; //habilitando interrupt enable
EX0=1; //habilitando interrupção externa
ET0=1; // habilitando timer0
ET1=1; //habilitando timer1
TMOD=1; //habilitando timers modo 16 bits
TR0=1; // habilitando timer0 modo contagem tempo
TR1=1; // habilitando timer1 modo contagem tempo

while (1) { //loop infinito

ligado=1; //circuito funcionando, habilito P2_0

if (sensor==1) {delay_ms(500);
Timer_0 (); } // condição para voltar ao Timer0

}
} //termino de programa

Exibições: 1158

Responder esta

Respostas a este tópico

Vc poderia fazer um amortecimento matemático.

Pode ser:

- linear:

 Vc precisa de 2 varáveis:

 - Posicao e PosicaoDesejada 

 Aih num loop vc faria

 Se Posicao for menor que posicao desejada incrementa posicao

 Se Posicao for maior que posicao desejada decrementa posica.

 - "Logaritmico" (eh um log falso):

 Idem qto a 2 vairiáveis, só que essas precisam ter pontos decimais. 

 Posicao = (Posicao*0.9) + (PosicaoDesejada*0.1).

 Aih quando estiver bem longe ele corre e quando chega perto vai desacelerando.

O 0.9 e o 0.1 podem ser ajustados para melhor resultados, desde que sempre somem 1.0

Para não ter que recorrer a um float ou coisa assim tb vc pode em vez de trabalhar de 0 a 255 ou 0 a 100 trabalhar com 

0 a 25500 ou 0 a 10000 e coeficientes 90 e 10. Aih na hora de jogar a vairiavel na função vc faz uma divisão.

No seu programa essa Posicao entraria na função delay(), que é uma forma meio primitiva de programar, mas se está te atendendo é o mais importante.

Só pra deixar um pouco mais claro cara tem como só me dar um exemplo, só pra poder enxergar melhor, foi voce que me ajudou da outra vez. 
Sobre a programação ela ta compilando é a questão do tempo pra voltar a posição inicial eu preciso de um atraso e com o delay mesmo eu colocando 2s ele volta em questão de milisegundos, se puder só exemplificar já vou conseguir compreender totalmente.

Já pesquei um pouco do que você disse é algo pra visualizar melhor e muito obrigado

Se entendi é pq hora vc dá um comando para 180 e hora dá pra 0. Ele vai de um ponto a outro o mais rápido que pode.

Vc teria que mandar 180, depois 179, depois 178..... até 0. Ou pelo menos 180, 170, 160 ou coisa assim.

Essa minha sugestão faz essa interpolação.

Esse é o conceito. Vc consegue fazer o codigo ?

Cara obrigado me ajudou muito, desculpe não agradecer antes tava sem tempo rs

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço