Buscar

prática7_andre_henrique_murillo

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

pratica7experiencia1.ino
#include <MsTimer2.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define encoder0PinA 20
#define encoder0PinB 21
#define keyUp 1
#define keyDown 2
#define keyRight 0
#define keyLeft 3
#define keySelect 4
#define analogPin A8
int encoder0Pulses = 0;
float pos_angular = 0;
float omega_RPM = 0;
float temp = 0;
int val = 0;
int keyValue = 0;
int step = 30;
int pwmPin = 44;
int valpwm = 0;
float input = 0;
float veloc = 0;
float Kp=10.0;
float Ki=1;
float Kd=5;
float u=0;
float uanterior=0;
float deltau=0;
float e=0;
float eanterior=0;
float eanterior2=0;
float s=0;
float santerior=0;
float omega_RPM_ref=0;
int pin1 = 44;
int pin2 = 45;
void setup() {
 lcd.begin(16, 2);
 pinMode(pin1, OUTPUT);
 pinMode(pin2, OUTPUT);
 pinMode(pwmPin, OUTPUT);
 pinMode(13, OUTPUT);
 MsTimer2::set(25, flash);
 MsTimer2::start();
 pinMode(encoder0PinA, INPUT);
 digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor
 pinMode(encoder0PinB, INPUT);
 digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor
 attachInterrupt(digitalPinToInterrupt(encoder0PinA), doEncoder_ExpandedA, CHANGE);
 attachInterrupt(digitalPinToInterrupt(encoder0PinB), doEncoder_ExpandedB, CHANGE);
 
 Serial.begin(9600);
 Serial.println("Serial Started!!!");
}
void displayMenu1() {
// Imprime o Menu 1 na tela do LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("[RPM]: ");
lcd.print(omega_RPM);
lcd.setCursor(0,1);
lcd.print("[PWM]: ");
lcd.print(input);
}
void loop() {
 keyPadRead();
 pwm();
 pos_angular = encoder0Pulses * 0.15;
 Serial.print (input);
 Serial.print (",");
 Serial.println(omega_RPM);
 displayMenu1();
 delay(250);
}
void motorInput(float input)
{
 if (input < 0)
 {
 input = max(input, -100);
 float v_map = map(input * -1, 0, 100, 0, 255);
 analogWrite(pin1, (int)v_map);
 analogWrite(pin2, 0);
 }
 else
 {
 input = min(input, 100);
 float v_map = map(input, 0, 100, 0, 255);
 analogWrite(pin2, (int)v_map);
 analogWrite(pin1, 0);
 }
}
void flash() {
 static bool output = false;
 digitalWrite(13, output); // Define o estado do LED no pino 13 de acordo com o valor da variavel "output".
 output = !output; // Inverte o valor da variavel "output" usando o operador "!".
 val = analogRead(analogPin);
 
 temp = 0.025*encoder0Pulses;
 omega_RPM = temp*40;
 eanterior=e;
 eanterior2=e;
 e=input-omega_RPM;
 s=santerior+e;
 uanterior=u;
 //u=Kp*e+Ki*s+Kd*(e-eanterior);
 u=e*(Kp+Ki+Kd)-eanterior*(Kp+2*Kd)+eanterior2*Kd;
 deltau=u-uanterior;
 motorInput(u);
 encoder0Pulses = 0;
}
void doEncoder_ExpandedA() {
 if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
 if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses - 1; // CCW
 
 }
 else {
 encoder0Pulses = encoder0Pulses + 1; // CW
 
 }
 }
 else { // found a high-to-low on channel A
 if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses + 1; // CW
 
 }
 else {
 encoder0Pulses = encoder0Pulses - 1; // CCW
 
 }
 }
}
void doEncoder_ExpandedB() {
 if (digitalRead(encoder0PinB) == HIGH) { // found a low-to-high on channel A
 if (digitalRead(encoder0PinA) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses + 1; // CCW
 
 }
 else {
 encoder0Pulses = encoder0Pulses - 1; // CW
 
 }
 }
 else { // found a high-to-low on channel A
 if (digitalRead(encoder0PinA) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses - 1; // CW
 
 }
 else {
 encoder0Pulses = encoder0Pulses + 1; // CCW
 
 }
 }
}
void keyPadRead()
{
 // Realiza a leitura do teclado do LCD Keypad Shield
 int analogKey = analogRead(0);
 if (analogKey < 80)
 {
 keyValue = 0;
 }
 else if (analogKey < 200)
 {
 keyValue = 1;
 valpwm = valpwm + step;
 input = input + step;
 }
 else if (analogKey < 400)
 {
 keyValue = 2;
 valpwm = valpwm - step;
 input = input - step;
 }
 else if (analogKey < 600)
 {
 keyValue = 3;
 }
 else if (analogKey < 800)
 {
 keyValue = 4;
 }
}
void pwm()
{
 valpwm = constrain(valpwm, 0, 255); // Limita o valor de valpwm entre 0 e 255
 analogWrite(pwmPin, valpwm);
 }
pratica7experiencia2.ino
#include <MsTimer2.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define encoder0PinA 20
#define encoder0PinB 21
#define keyUp 1
#define keyDown 2
#define keyRight 0
#define keyLeft 3
#define keySelect 4
#define analogPin A8
int encoder0Pulses = 0;
float pos_angular = 0;
float omega_RPM = 0;
float temp = 0;
int val = 0;
int keyValue = 0;
int step = 30;
int pwmPin = 44;
int valpwm = 0;
float input = 0;
float veloc = 0;
float Kp=10.0;
float Ki=1;
float Kd=5;
float periodo=0;
float posicao=0;
float dposicao=0;
float u=0;
float uanterior=0;
float deltau=0;
float e=0;
float eanterior=0;
float eanterior2=0;
float s=0;
float santerior=0;
float omega_RPM_ref=0;
int pin1 = 44;
int pin2 = 45;
void setup() {
 lcd.begin(16, 2);
 pinMode(pin1, OUTPUT);
 pinMode(pin2, OUTPUT);
 pinMode(pwmPin, OUTPUT);
 pinMode(13, OUTPUT);
 MsTimer2::set(25, flash);
 MsTimer2::start();
 pinMode(encoder0PinA, INPUT);
 digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor
 pinMode(encoder0PinB, INPUT);
 digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor
 attachInterrupt(digitalPinToInterrupt(encoder0PinA), doEncoder_ExpandedA, CHANGE);
 attachInterrupt(digitalPinToInterrupt(encoder0PinB), doEncoder_ExpandedB, CHANGE);
 
 Serial.begin(9600);
 Serial.println("Serial Started!!!");
}
void displayMenu1() {
// Imprime o Menu 1 na tela do LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("[RPM]: ");
lcd.print(omega_RPM);
lcd.setCursor(0,1);
lcd.print("[PWM]: ");
lcd.print(input);
}
void loop() {
 keyPadRead();
 pwm();
 pos_angular = encoder0Pulses * 0.15;
 Serial.print (input);
 Serial.print (",");
 Serial.println(posicao);
 displayMenu1();
 delay(250);
}
void motorInput(float input)
{
 if (input < 0)
 {
 input = max(input, -100);
 float v_map = map(input * -1, 0, 100, 0, 255);
 analogWrite(pin1, (int)v_map);
 analogWrite(pin2, 0);
 }
 else
 {
 input = min(input, 100);
 float v_map = map(input, 0, 100, 0, 255);
 analogWrite(pin2, (int)v_map);
 analogWrite(pin1, 0);
 }
}
void flash() {
 static bool output = false;
 digitalWrite(13, output); // Define o estado do LED no pino 13 de acordo com o valor da variavel "output".
 output = !output; // Inverte o valor da variavel "output" usando o operador "!".
 val = analogRead(analogPin);
 
 temp = 0.025*encoder0Pulses;
 omega_RPM = temp*40;
 periodo = omega_RPM/2*3.1415;
 if (periodo > 2*3.1415) {
 periodo = periodo - 2*3.1415;
 }
 dposicao=omega_RPM/periodo;
 posicao=posicao+dposicao;
 eanterior=e;
 eanterior2=eanterior;
 e=input-omega_RPM;
 s=santerior+e;
 uanterior=u;
 u=Kp*e+Ki*s+Kd*(e-eanterior);
 //u=e*(Kp+Ki+Kd)-eanterior*(Kp+2*Kd)+eanterior2*Kd;
 deltau=u-uanterior;
 motorInput(u);
 encoder0Pulses = 0;
}
void doEncoder_ExpandedA() {
 if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
 if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses - 1; // CCW
 
 }
 else {
 encoder0Pulses = encoder0Pulses + 1; // CW
 
 }
 }
 else { // found a high-to-low on channel A
 if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses + 1; // CW
}
 else {
 encoder0Pulses = encoder0Pulses - 1; // CCW
 
 }
 }
}
void doEncoder_ExpandedB() {
 if (digitalRead(encoder0PinB) == HIGH) { // found a low-to-high on channel A
 if (digitalRead(encoder0PinA) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses + 1; // CCW
 
 }
 else {
 encoder0Pulses = encoder0Pulses - 1; // CW
 
 }
 }
 else { // found a high-to-low on channel A
 if (digitalRead(encoder0PinA) == LOW) { // check channel B to see which way
 // encoder is turning
 encoder0Pulses = encoder0Pulses - 1; // CW
 
 }
 else {
 encoder0Pulses = encoder0Pulses + 1; // CCW
 
 }
 }
}
void keyPadRead()
{
 // Realiza a leitura do teclado do LCD Keypad Shield
 int analogKey = analogRead(0);
 if (analogKey < 80)
 {
 keyValue = 0;
 }
 else if (analogKey < 200)
 {
 keyValue = 1;
 valpwm = valpwm + step;
 input = input + step;
 }
 else if (analogKey < 400)
 {
 keyValue = 2;
 valpwm = valpwm - step;
 input = input - step;
 }
 else if (analogKey < 600)
 {
 keyValue = 3;
 }
 else if (analogKey < 800)
 {
 keyValue = 4;
 }
}
void pwm()
{
 valpwm = constrain(valpwm, 0, 255); // Limita o valor de valpwm entre 0 e 255
 analogWrite(pwmPin, valpwm);
 }
Relat?rio.pdf
Laboratório de Controle e Servomecanismo
Prática 7: Controle PID.
ANDRÉ LUÍS CORELIANO (RA:745948)
HENRIQUE CRAVEIRO D’ANTONIO (RA:791375)
MURILLO JOSÉ SUDAHIA GODOY (RA:789974)
TURMA C
04/09/2023
1 Descrição do experimento
A prática 7 serviu para aprender sobre como o microcontrolador Arduino, junto
com os conhecimentos de controle proporcional, integral e derivativo (PID), pode ser
usado para controlar a velocidade e o sentido de rotação de um motor CC, através do uso
de uma ponte H e de um encoder, através de um botão e um display LCD. É importante
salientar que os códigos feitos durante a aula foram enviados junto a esse relatório por
meio de uma pasta .zip na plataforma ava.
2 Execução do experimento
2.1 Experiência 1
Utilizando o código enviado junto a esse relatório, o serial plotter forneceu a se-
guinte imagem:
2.2 Experiência 2
Não foi possı́vel obter a imagem do serial plotter para esse experimento porém o
código utilizado foi enviado junto a esse relatório.
2.2 Pós-Laboratório
Com códigos implementados que alteram a velocidade e o sentido de rotação de um
motor CC, com a velocidade do motor sendo visualizada no display LCD não há dificul-
dade em medir a posição e a velocidade angular do motor a partir deles. Na experiência
1
1 controlou-se a velocidade do motor e na experiência 2 controlou-se a posição do motor,
ambas através da lei de controle PID discretizada.
3 Avaliação dos resultados do experimento
A prática ocorreu de maneira satisfatória, visto que os códigos feitos pelo grupo
foram executados da maneira esperada.
4 Análise crı́tica e discussão
A dificuldade encontrada durante a execução dessa prática foi a falta de experiência
do grupo em programar com o arduino e também a inexperiência do grupo com as técnicas
de controle PID. Apesar disso a prática ocorreu de maneira satisfatória, de modo que
todos os códigos exigidos foram executados de maneira coerente. Além disso foi possı́vel
aplicar de maneira prática, conceitos estudados na parte teórica da disciplina, controlando
a velocidade e a posição do motor CC através da lei de controle PID discretizada. Essa
técnica é utilizada para melhorar e refinar o controle de sistemas dinâmicos utilizando
ajustes empı́ricos.
5 Outras informações
Nessa prática foi solicitado um pré-laboratório. As respostas do pré-laboratório são:
1) A equação (2) fornece:
uk = Kpek +KiSk +Kd(ek − ek−1)
A equação (4) fornece:
∆uk = ek(Kp +Ki +Kd)− ek−1(Kp +2Kd)+ ek−2Kd
As definições de Kp, Ki e Kd são:
Sk=Sk−1 + ek
Kp = Kc
Ki =
Kc
∆Ti
2
Kd =
Kc∆Td
∆T
Substituindo esses valores na equação 2:
uk = Kcek+
Kc
∆Ti
(Sk−1 + ek)+
Kc∆Td
∆T
(ek − ek−1)
Simplificando a expressão:
uk=(Kc +
Kc
∆Ti
+
Kc∆Td
∆T
)ek +(
Kc
∆Ti
)Sk−1 − (
Kc∆Td
∆T
)ek−1
Escrevendo essa equação utilizando ∆uk:
∆uk=uk −uk−1=(Kc +
Kc
∆Ti
+
Kc∆Td
∆T
)ek +(
Kc
∆Ti
)Sk−1 − (
Kc∆Td
∆T
)ek−1 −uk−1
Reescrevendo em termos de ek e ek−1:
∆uk=ek(Kc +
Kc
∆Ti
+
Kc∆Td
∆T
)− ek−1(
Kc∆Td
∆T
)+(
Kc
∆Ti
)Sk−1 −uk−1
Rearranjando os termos:
∆uk=ek(
Kc(∆Ti +∆T +∆Td)
∆Ti
)− ek−1(
Kc∆Td
∆T
)+(
Kc
∆Ti
)Sk−1 −uk−1
Comparando essa equação com a equação (4) da prática nota-se que:
O primeiro termo: ek(
Kc(∆Ti +∆T +∆Td)
∆Ti
) é o termo correspondente a: ek na
equação (4).
O segundo termo: −ek−1(
Kc∆Td
∆T
) é o termo correspondente a: −ek−1(Kp+2Kd) na
equação (4).
O terceiro termo: (
Kc
∆Ti
)Sk−1 é o termo correspondente a: ek−2Kd na equação (4).
Portanto, a equação simplificada é de fato a equação (4).
6 Referências
Nessa prática não foram utilizadas referências bibliográficas.
3

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Continue navegando