ola pessoal, estou com o problema no meu projeto devido a programação que to utilizando, estou tentando fazer o controle da rotação com PID, e fazer a medição de torque, porem quando introduzo a programção na torque junto com a de rotação, começa a dar erro na leitura de rotação. se alguém poder me ajudar a solucionar esse problema.
Tags:
Ola
ajuda se mostrar o código e qual erro está acontecendo.
//--------------------------------------TORQUE------------------------------------------------*/
//#include "HX711.h"
//HX711 scale(A1, A2);
/* -------------------------- Variáveis globais ----------------------------------------------*/
volatile byte contagem_rpm = 0; // Precisa ser volátil porque incrementa em interrupção
unsigned long ultima_leitura_rpm = 0; // Armazena tempo anterior
int pinRele12 = 12; // Pino de Rele
int pinRele4 = 4; // Pino de Rele
int pinPWM = 9; // Pino de PWM
// Parâmetros do controlador PID
double KP = 0.30; //
double KI = 0.05; // refinamento (proporcional à amplitude e duração do desvio)
double KD = 0.05; // diminui o tempo de resposta (proporcional à velocidade de variação do desvio)
double N = 100.; // Filtro derivativo (deve ser valor grande)
double Ts = 0.01; // Período de amostragem (segundos)
unsigned long TsMicros = Ts*1000000; // Período de amostragem em microssegundos
double coef[5]; // Coeficientes da equação de diferenças do PID
// Limitadores da ação de controle
double ControleMin = -200.00;
double ControleMax = 200.00;
// Melhores valores encontrados até então: KP=0.1 , KI=0.05, KD=0.02 para limitador (-200 a 200)
/*---------------------------------------------------------------------------------------------*/
void setup () {
Serial.begin(9600);
pinMode(pinRele12, OUTPUT);
pinMode(pinRele4, OUTPUT);
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2),Frpm, RISING);
converteGanhos(coef,KP,KI,KD,N,Ts); // Destacar chamada de função com argumento array
/*-------------------------------------------------------------------------------------------*/
}
/*-------------------------Rotina principal -------------------------------------------------*/
void loop ()
{
int setPoint; // setPoint
double torque; // Leitura torque
double rpm; // Leitura rpm
double e0=0; // Erro atual
double e1=0; // Erro k-1
double e2=0; // Erro k-2
double u0=0; // Controle atual
double u1=0; // Controle k-1
double u2=0; // Controle k-2
int pwm; // PWM
unsigned long int ti; // Tempo inicial das operações (para controle do período de amostragem)
long int dt;
ti = micros(); // Marca o tempo inicial das operações do controlador
digitalWrite(5,LOW);
if ( Serial.available() ) { // Verifica se a porta serial tem dados
setPoint = Serial.parseInt(); // Se tiver, repassa para o setpoint
ajustaReles(setPoint); // Ajusta os relés de acordo com o setpoint
}
torque = leitura_torque(); // Faz leitura de torque
rpm = leitura_rpm(); // Faz leitura de rotação
e0 = setPoint-rpm; // Calcula erro de velocidade
u0 = -(coef[0]*u1+coef[1]*u2+coef[3]*e0+coef[4]*e1+coef[5]*e2); // Calcula ação PID com equação de diferenças. Inverte o sinal para fazer ação de frenagem
u0 = limitador(u0); // Limita o sinal de controle
pwm = map(u0, ControleMin, ControleMax, 0, 255); // Mapeia para o PWM
analogWrite(pinPWM, pwm); // Envia o sinal de controle por PWM
//envia_dado(setPoint,rpm,controle); // Transmite os dados para o computador
u2 = u1; // Atrasa o sinal de controle
u1 = u0; // Atrasa o sinal de controle
e2 = e1; // Atrasa o sinal de erro
e1 = e0; // Atrasa o sinal de erro
Serial.println(rpm);
dt = micros() - ti; // Calcula quanto tempo passou em relação ao início do controle
delayMicroseconds(TsMicros-dt); // Atrasa o restante do tempo para garantir o delay da amostragem (atenção para não dar negativo)
}
/*-------------------------------------------------------------------------------------------*/
/*---------------------------- Funções auxiliares -------------------------------------------*/
// ------------------------------- Função para leitura de torque ---------------------------------
double leitura_torque() {
//scale.read_average(20);
//scale.set_scale(30300.f);
//scale.tare();
return 0.;
}
// ----------- Faz leitura de rotação ----------------------------------------------------
double leitura_rpm(){
double rpm;
rpm = 15000000. * contagem_rpm/(micros() - ultima_leitura_rpm) ;
ultima_leitura_rpm = micros();
contagem_rpm = 0;
return rpm;
/* 1 volta = 4 contagens (pulsos)
num_voltas = contagem_rpm/4;
num_ciclos_por_seg = num_voltas/delta_tempo;
rpm = 60*num_ciclos_por_seg = 60 * (contagem_rpm/4) / (delta_tempo_micros/1000000)
rpm = 15000000 * contagem_rpm/delta_tempo_micros */
}
// ----------- Ajusta os reles da placa de acordo com o set-point ----------------------
void ajustaReles(int setPoint){
if (setPoint < 500) { // calibrar este valor para baixas rotações
digitalWrite(pinRele12, HIGH);
digitalWrite(pinRele4, HIGH);
}
if (setPoint > 500) {
digitalWrite(pinRele12, LOW);
digitalWrite(pinRele4, LOW);
}
}
// ----------- Converte ganhos PID em coeficientes de equação de diferenças -----------------------
void converteGanhos(double coefs[], double Kp, double Ki, double Kd,double N, double Ts){
// Expressões baseadas em discretização de Euler simples
double a0= (1+N*Ts);
double a1 = -(2 + N*Ts);
double a2 = 1;
double b0 = Kp*(1+N*Ts) + Ki*Ts*(1+N*Ts) + Kd*N;
double b1 = -(Kp*(2+N*Ts) + Ki*Ts + 2*Kd*N);
double b2 = Kp + Kd*N;
coefs[0] = -a1/a0;
coefs[1] = -a2/a0;
coefs[2] = b0/a0;
coefs[3] = b1/a0;
coefs[4] = b2/a0;
// Atentar para uso de argumento array.
}
// ----------- Limitador do sinal de controle ----------------------------------------------
double limitador(double u){
double controle;
controle = (u >= ControleMax ? ControleMax : u);// Limitador p/ máximo
controle = (u <= ControleMin ? ControleMin : u);// Limitador p/ mínimo return controle; } /*----------------------------------FUNÇÃO DE INERRUPÇÃO-------------------------------------*/ void Frpm () { // Incrementa contador do enconder sempre que perceber borda de subida contagem_rpm++; digitalWrite(5,HIGH); } estou ultilizando esse codigo, nao sei qual e o motivo mais a leitura de rotação fica oscilando entre 0 e um valor arbitrario.
Já resolveu seu problema?
Não identifiquei nenhum problema no código em si. Uma coisa não deveria interferir na outra. O problema deve estar nas ligações.
Boa tarde EV,
Recomendações:
1. Leia http://labdegaragem.com/forum/topics/sugest-o-de-como-postar
2. Remova seu sketch da área de texto do seu tópico;
3. Comente as linhas do seu sketch. Fica difícil descobrir o que vc quer fazer com cada linha.
4. Clique em : " Deseja carregar arquivos? " e depois em " Escolher arquivo" e anexe o arquivo
com o seu sketch.
RV
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por