Introduction
This week’s assignment focuses on integrating an output device into our board. For my final project, a controller for a pellet extruder, I chose to operate the Massive Dimension pellet extruder motor using the board.
Objectives
To control the motor effectively, I referenced the Teknik Motor Clearpath user manual, which explains the motor can operate as a stepper motor, suppling enable, step and direction inputs.
- Enable: This signal can be 0 or 1. To activate the motor, it must be set to 1.
- Direction: This signal can also be 0 or 1, where 0 rotates the motor clockwise and 1 rotates it counterclockwise.
- Step: This output toggles on and off. Each toggle represents one step, and the motor is configured to require 800 steps to complete a full rotation.
The goal is to achieve precise control over the motor’s RPM.
- Custom Board from previous week
- Massive Dimension Pellet Extruder MDPH2: MDPH2 Pellet Head Extruder System
Process
I tried generating steps through a loop, manually toggling the step output.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
// extrudercontrol.ino
//
//
// Luis Pacheco 3/27/24
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose, but must
// acknowledge this project. Copyright is retained and
// must be preserved. The work is provided as is; no
// warranty is provided, and users accept all liability.
//
#include <Arduino.h>
// Motor variables
int OutStep = 25;
int OutDir = 26;
int OutEnable = 27;
bool MotorEnable = false;
float MotorRev = 800;
float MotorSpeed = 0; // revolutions per minute
unsigned long LastRunTime = 0;
unsigned long currentMotorTime = 0;
unsigned long previousMotorTime = 0;
long motorInterval = 0.1;
// Rotary encoder variables
#define SPIN_A 2
#define SPIN_B 4
#define SPIN_BUTTON 15
volatile bool sturnedCW = false;
volatile bool sturnedCCW = false;
static int svalue = 0;
int DEBONCE_TO = 150;
unsigned long sdebounceTime = 0;
bool slastWasCW = false;
bool slastWasCCW = false;
void setup() {
Serial.begin(115200);
// MOTOR setup
pinMode(OutDir, OUTPUT);
pinMode(OutStep, OUTPUT);
pinMode(OutEnable, OUTPUT);
digitalWrite(OutEnable, HIGH); // activate extruder motor
digitalWrite(OutDir, HIGH); // Set direction
Serial.println("Motor setup OK");
currentMotorTime = millis();
previousMotorTime = millis();
// Motor Encoder setup
pinMode(SPIN_A, INPUT_PULLUP);
pinMode(SPIN_B, INPUT_PULLUP);
pinMode(SPIN_BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SPIN_B), scheckEncoder, CHANGE);
Serial.println("Reading from encoder: MOTOR ");
}
void loop() {
// motor control logic here
if (MotorEnable && MotorSpeed != 0) {
currentMotorTime = millis();
float StepPerMillis = MotorRev * MotorSpeed / 30000000;
float MillisPerStep = 1 / StepPerMillis;
digitalWrite(OutStep, HIGH);
delayMicroseconds(MillisPerStep);
digitalWrite(OutStep, LOW);
delayMicroseconds(MillisPerStep);
}
// Rotary encoder logic for motor speed control
if (sturnedCW) {
svalue++;
MotorSpeed = svalue * 25; // Example: Adjusting speed with each CW turn
sturnedCW = false;
slastWasCW = true;
sdebounceTime = millis();
}
if (sturnedCCW) {
if (MotorSpeed > 0) {
svalue--;
MotorSpeed = svalue * 25; // Example: Decreasing speed with each CCW turn
}
sturnedCCW = false;
slastWasCCW = true;
sdebounceTime = millis();
}
// Reset motor speed to zero if encoder button is pressed
int sbtnState = digitalRead(SPIN_BUTTON);
if (sbtnState == LOW && millis() - sdebounceTime > DEBONCE_TO) {
MotorSpeed = 0;
sdebounceTime = millis();
}
}
void scheckEncoder() {
if ((!sturnedCW) && (!sturnedCCW)) {
int spinA = digitalRead(SPIN_A);
delayMicroseconds(1500); // Debounce delay
int spinB = digitalRead(SPIN_B);
if (spinA == spinB) {
sturnedCW = !slastWasCCW;
sturnedCCW = slastWasCCW;
} else {
sturnedCW = slastWasCW;
sturnedCCW = !slastWasCW;
}
}
}
|
This method, however, led to several issues:
- Introducing delays in the loop affected step timing and, consequently, RPM accuracy.
- As code complexity increases and depending on the microprocessor’s speed, loop execution may slow down, further impacting RPM precision. This method of manual step generation is known as “Bit Banging.”
After exploring PWM (Pulse Width Modulation) and encountering limitations related to its fixed frequency, I discovered the ESP32 allows for PWM frequency adjustment. This capability enables consistent RPM control, regardless of main loop execution time or added delays, as the frequency can be dynamically altered. Ill imlement this on the final project.
Conclusion
Utilizing the ESP32’s hardware features for step control, as opposed to bit banging, significantly can improve the project. It allows for the addition of various inputs, outputs, networking features, etc., without compromising the precision or consistency of the extruder’s RPM.