#include <PID_v1.h> // Include the PID library
// Define pins
const int thermistorPin = A0; // Analog pin connected to the thermistor
const int heaterPin = 9; // PWM pin connected to the heater
const int dirPin1 = 2; // Direction pin for stepper motor 1
const int stepPin1 = 3; // Step pin for stepper motor 1
const int dirPin2 = 4; // Direction pin for stepper motor 2
const int stepPin2 = 5; // Step pin for stepper motor 2
const int dirPin3 = 6; // Direction pin for stepper motor 3
const int stepPin3 = 7; // Step pin for stepper motor 3
const int fanPin = 6; // PWM pin for the fan
const int stepsPerRevolution = 200; // Number of steps per revolution for the stepper motor (200 for a typical NEMA 17)
int stepDelay = 500; // Delay time between steps in microseconds
// Timing variables for stepper motors and temperature updates
unsigned long lastStepTime1 = 0; // Last step time for motor 1
unsigned long lastStepTime2 = 0; // Last step time for motor 2
unsigned long lastStepTime3 = 0; // Last step time for motor 3
unsigned long lastTemperatureUpdateTime = 0; // Last update time for temperature control
unsigned long lastPrintTime = 0; // Last time the status was printed to the serial monitor
bool stepState1 = LOW; // Step state for motor 1
bool stepState2 = LOW; // Step state for motor 2
bool stepState3 = LOW; // Step state for motor 3
// PID parameters
double Setpoint = 230.0; // Desired temperature in Celsius
double Input, Output; // Variables for PID input and output
double Kp = 1, Ki = 4, Kd = .8; // PID constants: Proportional, Integral, Derivative
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); // Initialize PID controller
// Thermistor variables
const double BETA = 3950; // Beta constant for the thermistor
const double ROOM_TEMP = 298.15; // Room temperature in Kelvin (25ºC)
const double NOMINAL_RESISTANCE = 100000; // Nominal resistance of the thermistor (100k ohms)
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud
pinMode(heaterPin, OUTPUT); // Set heater pin as output
pinMode(fanPin, OUTPUT); // Set fan pin as output
// Configure the PID controller
myPID.SetMode(AUTOMATIC); // Set PID to automatic mode
// Configure stepper motor pins
pinMode(stepPin1, OUTPUT); // Set step pin for motor 1 as output
pinMode(dirPin1, OUTPUT); // Set direction pin for motor 1 as output
pinMode(stepPin2, OUTPUT); // Set step pin for motor 2 as output
pinMode(dirPin2, OUTPUT); // Set direction pin for motor 2 as output
pinMode(stepPin3, OUTPUT); // Set step pin for motor 3 as output
pinMode(dirPin3, OUTPUT); // Set direction pin for motor 3 as output
// Initialize motor direction
digitalWrite(dirPin1, HIGH); // Set direction for motor 1
digitalWrite(dirPin2, HIGH); // Set direction for motor 2
digitalWrite(dirPin3, HIGH); // Set direction for motor 3
}
void loop() {
unsigned long currentTime = millis(); // Get the current time
// Execute tasks
controlMotor1(); // Control stepper motor 1
controlMotor2(); // Control stepper motor 2
controlMotor3(); // Control stepper motor 3
controlTemperature(); // Control temperature using PID
controlFan(); // Control fan speed
printStatus(); // Print status to serial monitor
}
void controlMotor1() {
unsigned long currentMicros = micros(); // Get the current time in microseconds
// Stepper motor control
if (currentMicros - lastStepTime1 >= stepDelay) { // Check if enough time has passed
lastStepTime1 = currentMicros; // Update last step time
// Toggle step pin state
stepState1 = !stepState1; // Alternate the state of the step pin
digitalWrite(stepPin1, stepState1); // Set the step pin
}
}
void controlMotor2() {
unsigned long currentMicros = micros(); // Get the current time in microseconds
// Stepper motor control
if (currentMicros - lastStepTime2 >= stepDelay) { // Check if enough time has passed
lastStepTime2 = currentMicros; // Update last step time
// Toggle step pin state
stepState2 = !stepState2; // Alternate the state of the step pin
digitalWrite(stepPin2, stepState2); // Set the step pin
}
}
void controlMotor3() {
unsigned long currentMicros = micros(); // Get the current time in microseconds
// Stepper motor control
if (currentMicros - lastStepTime3 >= stepDelay) { // Check if enough time has passed
lastStepTime3 = currentMicros; // Update last step time
// Toggle step pin state
stepState3 = !stepState3; // Alternate the state of the step pin
digitalWrite(stepPin3, stepState3); // Set the step pin
}
}
void controlTemperature() {
// Update temperature and PID control every 500 ms
if (millis() - lastTemperatureUpdateTime >= 500) { // Check if enough time has passed
lastTemperatureUpdateTime = millis(); // Update last temperature update time
// Read thermistor temperature
int analogValue = analogRead(thermistorPin); // Read analog value from thermistor pin
double resistance = (1023.0 / analogValue - 1) * NOMINAL_RESISTANCE; // Calculate thermistor resistance
double temperature = 1 / (log(resistance / NOMINAL_RESISTANCE) / BETA + 1 / ROOM_TEMP) - 273.15; // Calculate temperature in Celsius
Input = temperature; // Set PID input to the measured temperature
// Compute PID
myPID.Compute(); // Perform PID computation
// Control heater element
analogWrite(heaterPin, Output); // Set heater power based on PID output
}
}
void controlFan() {
// Control fan based on temperature
analogWrite(fanPin, 225); // Set fan speed (fixed value in this example)
}
void printStatus() {
// Print values to serial monitor every 500 ms to reduce impact on motor control
if (millis() - lastPrintTime >= 500) { // Check if enough time has passed
lastPrintTime = millis(); // Update last print time
Serial.print("Temperature: "); // Print temperature label
Serial.println(Input); // Print current temperature
// Serial.print("C, Output: ");
// Serial.println(Output);
}
}