// #include <SPI.h>
#include <RotaryEncoder.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
int pwm = 5;
int clk = 8; // Pin 1 from rotary encoder
int data = 9; // Pin 2 from rotary encoder
int botao_sw = 11;
const int dir_pino = 12;
// const int reset_pino = 10;
const int step_pino = 13;
// const int ENPin = 7;
int velocidade_max = 1000;
int velocidade_min = 0;
float temp_definida = 175; // Default temperature setpoint. Leave it 0 and control it with rotary encoder
float temperatura_lida = 0.0;
float erro_PID = 0;
float erro_anterior = 0;
float tempo_decorrido, Tempo, tempo_anterior;
float valor_PID = 0;
int botao_apertado = 0;
int menu_ativado = 0;
float ultima_temp_definida = 0;
int disp = 1;
int estado_clk;
int ultimo_estado;
bool estado_dt;
int kp = 40;
int ki = 20;
int kd = 30;
int PID_p = 0;
int PID_i = 0;
int PID_d = 0;
float ultimo_kp = 0;
float ultimo_ki = 0;
float ultimo_kd = 0;
int valor_PIDs_fixos = 0; // Duvida
unsigned long delay_LCD_desejado = 1000; // Replace 500 with the desired delay time in milliseconds
unsigned long tempo_ant_menu = 0;
// unsigned long tempo_atual = 0;
// unsigned long tempo1_anterior_encoder = 0;
float vel_motor = 40;
int velocidade_rotacao = 0;
// Define a stepper and the pins it will use
AccelStepper stepper1(1, step_pino, dir_pino); // (Type of driver: with 2 pins, STEP, DIR)
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
/// pinMode(PWM_pin,OUTPUT);
// pinMode(ENPin, OUTPUT);
// digitalWrite(ENPin, HIGH); // Stepper driver is disbled
stepper1.setMaxSpeed(velocidade_max);
TCCR2B = TCCR2B & B11111000 | 0x03; // pin 3 and 11 PWM frequency of 928.5 Hz
Tempo = millis();
ultimo_estado = (PINB & B00000001); // Detect first state of the encoder
PCICR |= (1 << PCIE0); // enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); // Set pin D8 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT1); // Set pin D9 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT3); // Set pin D11 trigger an interrupt on state change.
pinMode(botao_sw, INPUT_PULLUP);
pinMode(data, INPUT);
pinMode(clk, INPUT);
pinMode(pwm, OUTPUT);
digitalWrite(pwm, HIGH);
pinMode(dir_pino, OUTPUT);
// pinMode(reset_pino, OUTPUT);
pinMode(step_pino, OUTPUT);
Serial.begin(9600);
lcd.init();
lcd.backlight();
}
void loop()
{
// digitalWrite(reset_pino, HIGH);
temperatura_lida = medirTemperatura(analogRead(0));
erro_PID = temp_definida - temperatura_lida + 3;
PID_p = 0.01 * kp * erro_PID;
PID_i = 0.01 * PID_i + (ki * erro_PID);
tempo_anterior = Tempo;
Tempo = millis();
tempo_decorrido = (Tempo - tempo_anterior) / 1000;
PID_d = 0.01 * kd * ((erro_PID - erro_anterior) / tempo_decorrido);
valor_PID = PID_p + PID_i + PID_d;
if (valor_PID < 0)
{
valor_PID = 0;
}
else
{
if (valor_PID > 255)
{
valor_PID = 255;
}
}
analogWrite(pwm, 255 - valor_PID);
erro_anterior = erro_PID;
if (vel_motor > 20 || vel_motor < -20)
{
if (vel_motor > 0)
{
digitalWrite(dir_pino, LOW);
velocidade_rotacao = map(vel_motor*-1, 0, 100, velocidade_min, velocidade_max);
stepper1.setSpeed(velocidade_rotacao);
stepper1.runSpeed();
}
else
{
digitalWrite(dir_pino, LOW);
velocidade_rotacao = map(vel_motor*-1, 0, 100, velocidade_min, velocidade_max);
stepper1.setSpeed(velocidade_rotacao);
stepper1.runSpeed();
}
}
if (menu_ativado == 0)
{
unsigned long currentTime = millis();
if (currentTime - tempo_ant_menu >= delay_LCD_desejado)
{
lcd.clear();
lcd.setCursor(9, 0);
lcd.print("D:");
lcd.setCursor(11, 0);
lcd.print(temp_definida, 1);
lcd.setCursor(0, 0);
lcd.print("A:");
lcd.setCursor(2, 0);
lcd.print(temperatura_lida, 1);
lcd.setCursor(0, 1);
lcd.print("M:");
lcd.setCursor(2, 1);
lcd.print(vel_motor, 1);
lcd.setCursor(8, 1);
lcd.print("Z:");
lcd.setCursor(10, 1);
lcd.print(valor_PID, 1);
tempo_ant_menu = currentTime;
Serial.println("p ->");
Serial.println(PID_p);
Serial.println("i ->");
Serial.println(PID_i);
Serial.println("d ->");
Serial.println(PID_d);
Serial.println("\n");
}
}
else
{
if (menu_ativado == 1)
{
if (temp_definida != ultima_temp_definida || disp)
{
disp = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set temperature");
lcd.setCursor(0, 1);
lcd.print(temp_definida);
}
ultima_temp_definida = temp_definida;
}
else
{
if (menu_ativado == 2)
{
if (kp != ultimo_kp || disp)
{
disp = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set P value ");
lcd.setCursor(0, 1);
lcd.print(kp);
}
ultimo_kp = kp;
}
else
{
if (menu_ativado == 3)
{
if (ki != ultimo_ki || disp)
{
disp = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set I value ");
lcd.setCursor(0, 1);
lcd.print(ki);
}
ultimo_ki = ki;
}
else
{
if (menu_ativado == 4)
{
if (kd != ultimo_kd || disp)
{
disp = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set D value ");
lcd.setCursor(0, 1);
lcd.print(kd);
}
ultimo_kd = kd;
}
else
{
if (menu_ativado == 5)
{
if (((temperatura_lida > temp_definida) && (temperatura_lida - temp_definida > 10)) || ((temperatura_lida < temp_definida) && (temperatura_lida - temp_definida < -10)))
{
menu_ativado = 0;
Serial.print(temperatura_lida);
Serial.print("\n");
}
else
{
if (disp)
{
disp = 0;
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Executando");
}
}
}
}
}
}
}
}
}
float medirTemperatura(float x)
{
float y = 0;
y = ((1.697 * pow(10, -9) * pow(x, 4)) - (2.764 * pow(10, -6) * pow(x, 3)) + (0.001467 * pow(x, 2)) - (0.1055 * x) + 29.68);
if (x > 926)
{
y = y + x * 0.01 - 30 / (x * 0.01);
}
else
{
if (x > 840)
{
y = y - x * 0.005;
}
}
return y;
}
ISR(PCINT0_vect)
{
if (menu_ativado == 0)
{
estado_clk = (PINB & B00000001);
estado_dt = (PINB & B00000010);
if (estado_clk != ultimo_estado)
{
if (estado_dt != estado_clk)
{
if (vel_motor < 100)
{
vel_motor = vel_motor + 0.5;
}
}
else
{
if (vel_motor > -100)
{
vel_motor = vel_motor - 0.5;
}
}
}
ultimo_estado = estado_clk;
}
else
{
if (menu_ativado == 1)
{
estado_clk = (PINB & B00000001);
estado_dt = (PINB & B00000010);
if (estado_clk != ultimo_estado)
{
if (estado_dt != estado_clk)
{
temp_definida = temp_definida + 0.5;
}
else
{
temp_definida = temp_definida - 0.5;
}
}
ultimo_estado = estado_clk;
}
else
{
if (menu_ativado == 2)
{
estado_clk = (PINB & B00000001);
estado_dt = (PINB & B00000010);
if (estado_clk != ultimo_estado)
{
if (estado_dt != estado_clk)
{
kp = kp + 1;
}
else
{
kp = kp - 1;
}
}
ultimo_estado = estado_clk;
}
else
{
if (menu_ativado == 3)
{
estado_clk = (PINB & B00000001);
estado_dt = (PINB & B00000010);
if (estado_clk != ultimo_estado)
{
if (estado_dt != estado_clk)
{
ki = ki + 1;
}
else
{
ki = ki - 1;
}
}
ultimo_estado = estado_clk;
}
else
{
if (menu_ativado == 4)
{
estado_clk = (PINB & B00000001);
estado_dt = (PINB & B00000010);
if (estado_clk != ultimo_estado)
{
if (estado_dt != estado_clk)
{
kd = kd + 1;
}
else
{
kd = kd - 1;
}
}
ultimo_estado = estado_clk;
}
}
}
}
}
if (PINB & B00001000)
{
botao_apertado = 1;
}
else if (botao_apertado == 1)
{
if (menu_ativado == 4)
{
disp = 1;
menu_ativado = 0;
valor_PIDs_fixos = 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 3)
{
disp = 1;
menu_ativado = menu_ativado + 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 2)
{
disp = 1;
menu_ativado = menu_ativado + 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 1 && valor_PIDs_fixos != 1)
{
disp = 1;
menu_ativado = menu_ativado + 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 1 && valor_PIDs_fixos == 1)
{
disp = 1;
menu_ativado = 5;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 0 && valor_PIDs_fixos != 1)
{
disp = 1;
menu_ativado = menu_ativado + 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 0 && valor_PIDs_fixos == 1)
{
disp = 1;
menu_ativado = menu_ativado + 1;
botao_apertado = 0;
delay(500);
}
else
{
if (menu_ativado == 5)
{
disp = 1;
menu_ativado = 2;
botao_apertado = 0;
delay(500);
}
}
}
}
}
}
}
}
}
}ERC Warnings
S8050:OUT: Multi-driven net on pin