//LCD config
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Thermistor needed libraries
#include <thermistor.h>
thermistor therm1(A0, 0);
//I/O
int PWM_pin = 5; //Pin for PWM signal to the MOSFET driver (the BJT npn with pullup)
int speed_pot = A1;
int temp_pot = A2;
int LED = 13;
//Variables
float set_temperature = 200; //Default temperature setpoint. Leave it 0 and control it with rotary encoder
float temperature_read = 0.0;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
float PID_value = 0;
float rotating_speed = 0;
#include <AccelStepper.h>
AccelStepper stepper1(1, 3, 4); //(Type of driver: with 2 pins, STEP, DIR)
//PID constants
int kp = 90;
int ki = 30;
int kd = 80;
int PID_p = 0;
int PID_i = 0;
int PID_d = 0;
int max_PWM = 255;
int max_speed = 500;
void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
pinMode(PWM_pin, OUTPUT);
TCCR0B = TCCR0B & B11111000 | B00000010; // D6 adn D6 PWM frequency of 7812.50 Hz
Time = millis();
TCCR1A = 0; //Reset entire TCCR1A register
TCCR1B = 0; //Reset entire TCCR1B register
TCCR1A |= B00000010; // /8
TCNT1 = 0; //Reset Timer 1 value to 0
lcd.init();
lcd.backlight();
}
void loop() {
// Reading the real value of temperature
temperature_read = therm1.analog2temp(); // read temperature
set_temperature = map(analogRead(temp_pot), 0, 1023, 0, 300); // Adjust the range as needed
// Calculating the error between the setpoint and the real value
PID_error = set_temperature - temperature_read + 6;
// Calculate the P value
PID_p = 0.01 * kp * PID_error;
// Calculate the I value in a range on +-6
PID_i = 0.01 * PID_i + (ki * PID_error);
// For derivative we need real time to calculate speed change rate
timePrev = Time; // the previous time is stored before the actual time read
Time = millis(); // actual time read
elapsedTime = (Time - timePrev) / 1000;
// Now we can calculate the D value
PID_d = 0.01 * kd * ((PID_error - previous_error) / elapsedTime);
// Final total PID value is the sum of P + I + D
PID_value = PID_p + PID_i + PID_d;
// We define PWM range between 0 and 255
if (PID_value < 0) {
PID_value = 0;
}
if (PID_value > max_PWM) {
PID_value = max_PWM;
}
// Now we can write the PWM signal to the mosfet on digital pin D5
analogWrite(PWM_pin, PID_value);
previous_error = PID_error;
// Running the stepper motor at the calculated speed
digitalWrite(LED, HIGH);
// Calculating rotating speed based on potentiometer value
int potValue = analogRead(speed_pot);
Serial.print("Potentiometer Value: ");
Serial.println(potValue);
int rotating_speed = map(potValue, 0, 1024, 0, 4000);
Serial.print("Rotating Speed: ");
Serial.println(rotating_speed);
stepper1.setMaxSpeed(rotating_speed);
stepper1.moveTo(10000); // Set a long distance to move to
stepper1.run(); // This will run the motor continuously at the set speed
delay(250); //Refresh rate + delay of LCD print
// Displaying temperature and speed on LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T: ");
lcd.print(temperature_read, 1);
lcd.print(" S: ");
lcd.print(rotating_speed);
lcd.setCursor(0, 1);
lcd.print("PID: ");
lcd.print(PID_value);
}