Baixe o app para aproveitar ainda mais
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
Compartilhar