-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExtruder.h
310 lines (295 loc) · 9.62 KB
/
Extruder.h
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#ifndef EXTRUDER_H_INCLUDED
#define EXTRUDER_H_INCLUDED
#define CELSIUS_EXTRA_BITS 3
//#ifdef TEMP_PID
//extern uint8_t current_extruder_out;
//#endif
// Updates the temperature of all extruders and heated bed if it's time.
// Toggels the heater power if necessary.
extern bool reportTempsensorError(); ///< Report defect sensors
extern uint8_t manageMonitor;
#define TEMPERATURE_CONTROLLER_FLAG_ALARM 1
/** TemperatureController manages one heater-temperature sensore loop. You can have up to
4 loops allowing pid/bang bang for up to 3 extruder and the heated bed.
*/
class TemperatureController
{
public:
uint8_t pwmIndex; ///< pwm index for output control. 0-2 = Extruder, 3 = Fan, 4 = Heated Bed
uint8_t sensorType; ///< Type of temperature sensor.
uint8_t sensorPin; ///< Pin to read extruder temperature.
int16_t currentTemperature; ///< Currenttemperature value read from sensor.
int16_t targetTemperature; ///< Target temperature value in units of sensor.
float currentTemperatureC; ///< Current temperature in degC.
float targetTemperatureC; ///< Target temperature in degC.
uint32_t lastTemperatureUpdate; ///< Time in millis of the last temperature update.
int8_t heatManager; ///< How is temperature controled. 0 = on/off, 1 = PID-Control, 3 = deat time control
#ifdef TEMP_PID
float tempIState; ///< Temp. var. for PID computation.
uint8_t pidDriveMax; ///< Used for windup in PID calculation.
uint8_t pidDriveMin; ///< Used for windup in PID calculation.
float pidPGain; ///< Pgain (proportional gain) for PID temperature control [0,01 Units].
float pidIGain; ///< Igain (integral) for PID temperature control [0,01 Units].
float pidDGain; ///< Dgain (damping) for PID temperature control [0,01 Units].
uint8_t pidMax; ///< Maximum PWM value, the heater should be set.
float tempIStateLimitMax;
float tempIStateLimitMin;
uint8_t tempPointer;
float tempArray[4];
#endif
uint8_t flags;
void setTargetTemperature(float target);
void updateCurrentTemperature();
void updateTempControlVars();
inline bool isAlarm() {return flags & TEMPERATURE_CONTROLLER_FLAG_ALARM;}
inline void setAlarm(bool on) {if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_ALARM; else flags &= ~TEMPERATURE_CONTROLLER_FLAG_ALARM;}
#ifdef TEMP_PID
void autotunePID(float temp,uint8_t controllerId,bool storeResult);
#endif
};
class Extruder;
extern Extruder extruder[];
/** \brief Data to drive one extruder.
This structure contains all definitions for an extruder and all
current state variables, like current temperature, feeder position etc.
*/
class Extruder // Size: 12*1 Byte+12*4 Byte+4*2Byte = 68 Byte
{
public:
static Extruder *current;
#if FEATURE_DITTO_PRINTING
static uint8_t dittoMode;
#endif
uint8_t id;
int32_t xOffset;
int32_t yOffset;
float stepsPerMM; ///< Steps per mm.
uint8_t enablePin; ///< Pin to enable extruder stepper motor.
// uint8_t directionPin; ///< Pin number to assign the direction.
// uint8_t stepPin; ///< Pin number for a step.
uint8_t enableOn;
// uint8_t invertDir; ///< 1 if the direction of the extruder should be inverted.
float maxFeedrate; ///< Maximum feedrate in mm/s.
float maxAcceleration; ///< Maximum acceleration in mm/s^2.
float maxStartFeedrate; ///< Maximum start feedrate in mm/s.
int32_t extrudePosition; ///< Current extruder position in steps.
int16_t watchPeriod; ///< Time in seconds, a M109 command will wait to stabalize temperature
int16_t waitRetractTemperature; ///< Temperature to retract the filament when waiting for heatup
int16_t waitRetractUnits; ///< Units to retract the filament when waiting for heatup
#ifdef USE_ADVANCE
#ifdef ENABLE_QUADRATIC_ADVANCE
float advanceK; ///< Koefficient for advance algorithm. 0 = off
#endif
float advanceL;
int16_t advanceBacklash;
#endif
TemperatureController tempControl;
const char * PROGMEM selectCommands;
const char * PROGMEM deselectCommands;
uint8_t coolerSpeed; ///< Speed to use when enabled
uint8_t coolerPWM; ///< current PWM setting
/** \brief Sends the high-signal to the stepper for next extruder step.
Call this function only, if interrupts are disabled.
*/
static inline void step()
{
#if NUM_EXTRUDER==1
WRITE(EXT0_STEP_PIN,HIGH);
#else
switch(Extruder::current->id)
{
case 0:
#if NUM_EXTRUDER>0
WRITE(EXT0_STEP_PIN,HIGH);
#if FEATURE_DITTO_PRINTING
if(Extruder::dittoMode) {
WRITE(EXT1_STEP_PIN,HIGH);
}
#endif
#endif
break;
#if defined(EXT1_STEP_PIN) && NUM_EXTRUDER>1
case 1:
WRITE(EXT1_STEP_PIN,HIGH);
break;
#endif
#if defined(EXT2_STEP_PIN) && NUM_EXTRUDER>2
case 2:
WRITE(EXT2_STEP_PIN,HIGH);
break;
#endif
#if defined(EXT3_STEP_PIN) && NUM_EXTRUDER>3
case 3:
WRITE(EXT3_STEP_PIN,HIGH);
break;
#endif
#if defined(EXT4_STEP_PIN) && NUM_EXTRUDER>4
case 4:
WRITE(EXT4_STEP_PIN,HIGH);
break;
#endif
#if defined(EXT5_STEP_PIN) && NUM_EXTRUDER>5
case 5:
WRITE(EXT5_STEP_PIN,HIGH);
break;
#endif
}
#endif
}
/** \brief Sets stepper signal to low for current extruder.
Call this function only, if interrupts are disabled.
*/
static inline void unstep()
{
#if NUM_EXTRUDER==1
WRITE(EXT0_STEP_PIN,LOW);
#else
switch(Extruder::current->id)
{
case 0:
#if NUM_EXTRUDER>0
WRITE(EXT0_STEP_PIN,LOW);
#if FEATURE_DITTO_PRINTING
if(Extruder::dittoMode) {
WRITE(EXT1_STEP_PIN,LOW);
}
#endif
#endif
break;
#if defined(EXT1_STEP_PIN) && NUM_EXTRUDER>1
case 1:
WRITE(EXT1_STEP_PIN,LOW);
break;
#endif
#if defined(EXT2_STEP_PIN) && NUM_EXTRUDER>2
case 2:
WRITE(EXT2_STEP_PIN,LOW);
break;
#endif
#if defined(EXT3_STEP_PIN) && NUM_EXTRUDER>3
case 3:
WRITE(EXT3_STEP_PIN,LOW);
break;
#endif
#if defined(EXT4_STEP_PIN) && NUM_EXTRUDER>4
case 4:
WRITE(EXT4_STEP_PIN,LOW);
break;
#endif
#if defined(EXT5_STEP_PIN) && NUM_EXTRUDER>5
case 5:
WRITE(EXT5_STEP_PIN,LOW);
break;
#endif
}
#endif
}
/** \brief Activates the extruder stepper and sets the direction. */
static inline void setDirection(uint8_t dir)
{
#if NUM_EXTRUDER==1
if(dir)
WRITE(EXT0_DIR_PIN,!EXT0_INVERSE);
else
WRITE(EXT0_DIR_PIN,EXT0_INVERSE);
#else
switch(Extruder::current->id)
{
#if NUM_EXTRUDER>0
case 0:
if(dir)
WRITE(EXT0_DIR_PIN,!EXT0_INVERSE);
else
WRITE(EXT0_DIR_PIN,EXT0_INVERSE);
#if FEATURE_DITTO_PRINTING
if(Extruder::dittoMode) {
if(dir)
WRITE(EXT1_DIR_PIN,!EXT1_INVERSE);
else
WRITE(EXT1_DIR_PIN,EXT1_INVERSE);
}
#endif
break;
#endif
#if defined(EXT1_DIR_PIN) && NUM_EXTRUDER>1
case 1:
if(dir)
WRITE(EXT1_DIR_PIN,!EXT1_INVERSE);
else
WRITE(EXT1_DIR_PIN,EXT1_INVERSE);
break;
#endif
#if defined(EXT2_DIR_PIN) && NUM_EXTRUDER>2
case 2:
if(dir)
WRITE(EXT2_DIR_PIN,!EXT2_INVERSE);
else
WRITE(EXT2_DIR_PIN,EXT2_INVERSE);
break;
#endif
#if defined(EXT3_DIR_PIN) && NUM_EXTRUDER>3
case 3:
if(dir)
WRITE(EXT3_DIR_PIN,!EXT3_INVERSE);
else
WRITE(EXT3_DIR_PIN,EXT3_INVERSE);
break;
#endif
#if defined(EXT4_DIR_PIN) && NUM_EXTRUDER>4
case 4:
if(dir)
WRITE(EXT4_DIR_PIN,!EXT4_INVERSE);
else
WRITE(EXT4_DIR_PIN,EXT4_INVERSE);
break;
#endif
#if defined(EXT5_DIR_PIN) && NUM_EXTRUDER>5
case 5:
if(dir)
WRITE(EXT5_DIR_PIN,!EXT5_INVERSE);
else
WRITE(EXT5_DIR_PIN,EXT5_INVERSE);
break;
#endif
}
#endif
}
static inline void enable()
{
#if NUM_EXTRUDER==1
#if EXT0_ENABLE_PIN>-1
WRITE(EXT0_ENABLE_PIN,EXT0_ENABLE_ON );
#endif
#else
if(Extruder::current->enablePin > -1)
digitalWrite(Extruder::current->enablePin,Extruder::current->enableOn);
#if FEATURE_DITTO_PRINTING
if(Extruder::dittoMode) {
if(extruder[1].enablePin > -1)
digitalWrite(extruder[1].enablePin,extruder[1].enableOn);
}
#endif
#endif
}
static void manageTemperatures();
static void disableCurrentExtruderMotor();
static void selectExtruderById(uint8_t extruderId);
static void disableAllHeater();
static void initExtruder();
static void initHeatedBed();
static void setHeatedBedTemperature(float temp_celsius,bool beep = false);
static float getHeatedBedTemperature();
static void setTemperatureForExtruder(float temp_celsius,uint8_t extr,bool beep = false);
};
#if HAVE_HEATED_BED
#define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER+1
extern TemperatureController heatedBedController;
#else
#define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER
#endif
#define TEMP_INT_TO_FLOAT(temp) ((float)(temp)/(float)(1<<CELSIUS_EXTRA_BITS))
#define TEMP_FLOAT_TO_INT(temp) ((int)((temp)*(1<<CELSIUS_EXTRA_BITS)))
//extern Extruder *Extruder::current;
extern TemperatureController *tempController[NUM_TEMPERATURE_LOOPS];
extern uint8_t autotuneIndex;
#endif // EXTRUDER_H_INCLUDED