-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExtruder_PID_Control.ino
149 lines (100 loc) · 3.45 KB
/
Extruder_PID_Control.ino
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <PID_v1.h>
const unsigned int secondsInAMinute = 60;
const unsigned int microSecondsInASecond = 1000000;
const unsigned long serialUpdateInterval=250;
unsigned long serialUpdatePreviousTime = 0;
//*******Spooler variables*******//
unsigned int spooler_pin_irq = 0; //IRQ that matches to pin 2
const unsigned int spoolerPulsesPerRev = 10;
const unsigned long spoolerUpdateInterval=2500; // time in microseconds
unsigned long spoolerPulseCounts = 0;
double spoolerRPM = 0.00;
unsigned long spoolerStartTime = 0;
double spoolerSetpoint, SpoolerInput, SpoolerOutput;
double Spooler_consKp=1, Spooler_consKi=0.05, Spooler_consKd=0.25;
PID spoolerPID(&SpoolerInput, &SpoolerOutput, &spoolerSetpoint, Spooler_consKp, Spooler_consKi, Spooler_consKd, DIRECT);
//*****************************//
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
Serial.setTimeout(50);
//initialize the variables we're linked to
SpoolerInput = spoolerRPM;
spoolerSetpoint = 0;
//turn the PID on
spoolerPID.SetMode(AUTOMATIC);
//setup ISR for spooler interrupt
attachInterrupt(spooler_pin_irq, ISR_SpoolerPulseCounter, RISING);
}
void ISR_SpoolerPulseCounter() {
spoolerPulseCounts++;
}
void loop() {
ReadSerialData();
CalculateSpoolerRPMS();
PrintSerialData();
}
void ReadSerialData(){
String a = "";
String Device, Value;
while(Serial.available()) {
a= Serial.readString();// read the incoming data as string
if (a.length() >= 3){
int splitPosition = a.indexOf(";");
Device = a.substring(0, splitPosition);
Value = a.substring(splitPosition + 1);
}
}
if (isNumeric(Value)){
if (Device.length() >= 1 && Value.length() >= 1){
if (Device == "EXTRUDER_RPM"){
}
if(Device == "SPOOLER_RPM"){
spoolerSetpoint = Value.toFloat();
}
}
}
}
void PrintSerialData(){
if (millis() - serialUpdatePreviousTime >= serialUpdateInterval) {
serialUpdatePreviousTime = millis();
Serial.println(PrintSpoolerRPM());
Serial.println(PrintSpoolerSetpoint());
}
}
String PrintSpoolerRPM(){
return "SpoolerRPM = " + (String)spoolerRPM;
}
String PrintSpoolerSetpoint(){
return "SpoolerSetpoint = " + (String)spoolerSetpoint;
}
void CalculateSpoolerRPMS(){
if (spoolerStartTime == 0) { //kick start the timing routine
spoolerStartTime=micros();
}
if (micros() - spoolerStartTime > spoolerUpdateInterval && spoolerPulseCounts > 5) { //PulseCounts > 5 filters out false counts
//RPM= 6*1000000/(micros() - startTime)*PulseCounts; //RPM = ((secondsInAMinute / pulsesPerRev) * microSecondsInASecond)/(currentMicroSeconds - startTime) * numberOfPulses
spoolerRPM = ((secondsInAMinute / spoolerPulsesPerRev) * microSecondsInASecond) / (micros() - spoolerStartTime) * spoolerPulseCounts;
spoolerPulseCounts = 0; //reset IRQ counts
spoolerStartTime=0;
//Serial.print(F("RPM = "));
//Serial.print(spoolerRPM);
SpoolerInput = spoolerRPM;
spoolerPID.Compute();
//Serial.print(" PID Output Value= " + (String)SpoolerOutput);
}
}
bool isNumeric(String value){
int decimalExists;
if (value.length() == 0){return false;}
for (unsigned int i = 0; i < value.length(); i++){
if (value.charAt(i) == '.'){
decimalExists++;
}
if (!isDigit(value.charAt(i)) && value.charAt(i) != '.') {
return false;
}
if (decimalExists > 1){return false;}
}
return true;
}