Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MarlinKimbra
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
MarlinKimbra
Commits
a8e1e08b
Commit
a8e1e08b
authored
Jun 09, 2015
by
MagoKimbra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update
parent
433d7898
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
185 additions
and
175 deletions
+185
-175
Configuration.h
MarlinKimbra/Configuration.h
+5
-6
Marlin_main.cpp
MarlinKimbra/Marlin_main.cpp
+22
-18
temperature.cpp
MarlinKimbra/temperature.cpp
+151
-147
temperature.h
MarlinKimbra/temperature.h
+7
-4
No files found.
MarlinKimbra/Configuration.h
View file @
a8e1e08b
...
@@ -215,10 +215,13 @@
...
@@ -215,10 +215,13 @@
//============================= PID Settings ================================
//============================= PID Settings ================================
//===========================================================================
//===========================================================================
// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning
// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define K1 0.95 // Smoothing factor within the PID
#define MAX_OVERSHOOT_PID_AUTOTUNE 20 // Max valor for overshoot autotune
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
#ifdef PIDTEMP
#ifdef PIDTEMP
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
...
@@ -227,16 +230,12 @@
...
@@ -227,16 +230,12 @@
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_FUNCTIONAL_RANGE 10 // degC
#define PID_FUNCTIONAL_RANGE 10 // degC
#define PID_INTEGRAL_DRIVE_MAX PID_MAX // Limit for the integral term
#define PID_INTEGRAL_DRIVE_MAX PID_MAX // Limit for the integral term
#define K1 0.95 // Smoothing factor within the PID
#define MAX_OVERSHOOT_PID_AUTOTUNE 20 // Max valor for overshoot autotune
// HotEnd{HE0,HE1,HE2,HE3}
// HotEnd{HE0,HE1,HE2,HE3}
#define DEFAULT_Kp {40, 40, 40, 40} // Kp for E0, E1, E2, E3
#define DEFAULT_Kp {40, 40, 40, 40} // Kp for E0, E1, E2, E3
#define DEFAULT_Ki {07, 07, 07, 07} // Ki for E0, E1, E2, E3
#define DEFAULT_Ki {07, 07, 07, 07} // Ki for E0, E1, E2, E3
#define DEFAULT_Kd {60, 60, 60, 60} // Kd for E0, E1, E2, E3
#define DEFAULT_Kd {60, 60, 60, 60} // Kd for E0, E1, E2, E3
#endif // PIDTEMP
#endif // PIDTEMP
//===========================================================================
//===========================================================================
//===========================================================================
//============================= PID > Bed Temperature Control ===============
//============================= PID > Bed Temperature Control ===============
...
...
MarlinKimbra/Marlin_main.cpp
View file @
a8e1e08b
...
@@ -3204,10 +3204,10 @@ inline void gcode_G28() {
...
@@ -3204,10 +3204,10 @@ inline void gcode_G28() {
#ifdef ENABLE_AUTO_BED_LEVELING
#ifdef ENABLE_AUTO_BED_LEVELING
void
out_of_range_error
(
const
char
*
edge
)
{
void
out_of_range_error
(
const
char
*
p_
edge
)
{
char
msg
[
40
]
;
ECHO_M
(
"?Probe "
)
;
sprintf_P
(
msg
,
PSTR
(
"?Probe %s position out of range.
\n
"
),
edge
);
PS_PGM
(
p_
edge
);
ECHO_
V
(
msg
);
ECHO_
EM
(
" position out of range."
);
}
}
/**
/**
...
@@ -5123,18 +5123,20 @@ inline void gcode_M226() {
...
@@ -5123,18 +5123,20 @@ inline void gcode_M226() {
#endif // PREVENT_DANGEROUS_EXTRUDE
#endif // PREVENT_DANGEROUS_EXTRUDE
/**
#if defined(PIDTEMP) || defined(PIDTEMPBED)
* M303: PID relay autotune
/**
* S<temperature> sets the target temperature. (default target temperature = 150C)
* M303: PID relay autotune
* E<extruder> (-1 for the bed)
* S<temperature> sets the target temperature. (default target temperature = 150C)
* C<cycles>
* E<extruder> (-1 for the bed)
*/
* C<cycles>
inline
void
gcode_M303
()
{
*/
int
e
=
code_seen
(
'E'
)
?
code_value_short
()
:
0
;
inline
void
gcode_M303
()
{
int
c
=
code_seen
(
'C'
)
?
code_value_short
()
:
5
;
int
e
=
code_seen
(
'E'
)
?
code_value_short
()
:
0
;
float
temp
=
code_seen
(
'S'
)
?
code_value
()
:
(
e
<
0
?
70.0
:
150.0
);
int
c
=
code_seen
(
'C'
)
?
code_value_short
()
:
5
;
PID_autotune
(
temp
,
e
,
c
);
float
temp
=
code_seen
(
'S'
)
?
code_value
()
:
(
e
<
0
?
70.0
:
150.0
);
}
PID_autotune
(
temp
,
e
,
c
);
}
#endif
#ifdef PIDTEMPBED
#ifdef PIDTEMPBED
// M304: Set bed PID parameters P I and D
// M304: Set bed PID parameters P I and D
...
@@ -6425,8 +6427,10 @@ void process_next_command() {
...
@@ -6425,8 +6427,10 @@ void process_next_command() {
gcode_M302
();
break
;
gcode_M302
();
break
;
#endif // PREVENT_DANGEROUS_EXTRUDE
#endif // PREVENT_DANGEROUS_EXTRUDE
case
303
:
// M303 PID autotune
#if defined(PIDTEMP) || defined(PIDTEMPBED)
gcode_M303
();
break
;
case
303
:
// M303 PID autotune
gcode_M303
();
break
;
#endif
#ifdef PIDTEMPBED
#ifdef PIDTEMPBED
case
304
:
// M304
case
304
:
// M304
...
...
MarlinKimbra/temperature.cpp
View file @
a8e1e08b
...
@@ -184,175 +184,179 @@ static void updateTemperaturesFromRawValues();
...
@@ -184,175 +184,179 @@ static void updateTemperaturesFromRawValues();
//================================ Functions ================================
//================================ Functions ================================
//===========================================================================
//===========================================================================
void
PID_autotune
(
float
temp
,
int
hotend
,
int
ncycles
)
{
#if defined(PIDTEMP) || defined(PIDTEMPBED)
float
input
=
0.0
;
void
PID_autotune
(
float
temp
,
int
hotend
,
int
ncycles
)
{
int
cycles
=
0
;
float
input
=
0.0
;
bool
heating
=
true
;
int
cycles
=
0
;
bool
heating
=
true
;
millis_t
temp_ms
=
millis
(),
t1
=
temp_ms
,
t2
=
temp_ms
;
long
t_high
=
0
,
t_low
=
0
;
millis_t
temp_ms
=
millis
(),
t1
=
temp_ms
,
t2
=
temp_ms
;
long
t_high
=
0
,
t_low
=
0
;
long
bias
,
d
;
float
Ku
,
Tu
;
long
bias
,
d
;
float
Kp_temp
,
Ki_temp
,
Kd_temp
;
float
Ku
,
Tu
;
float
max
=
0
,
min
=
10000
;
float
Kp_temp
,
Ki_temp
,
Kd_temp
;
float
max
=
0
,
min
=
10000
;
#if HAS_AUTO_FAN
millis_t
next_auto_fan_check_ms
=
temp_ms
+
2500
;
#if HAS_AUTO_FAN
#endif
millis_t
next_auto_fan_check_ms
=
temp_ms
+
2500
;
if
(
hotend
>=
HOTENDS
#if !HAS_TEMP_BED
||
hotend
<
0
#endif
#endif
)
{
ECHO_LM
(
ER
,
MSG_PID_BAD_EXTRUDER_NUM
);
return
;
}
ECHO_LM
(
DB
,
MSG_PID_AUTOTUNE_START
);
if
(
hotend
>=
HOTENDS
if
(
hotend
<
0
)
{
#if !HAS_TEMP_BED
ECHO_SM
(
DB
,
"BED"
);
||
hotend
<
0
}
#endif
else
{
)
{
ECHO_SMV
(
DB
,
"Hotend: "
,
hotend
);
ECHO_LM
(
ER
,
MSG_PID_BAD_EXTRUDER_NUM
);
}
return
;
ECHO_MV
(
" Temp: "
,
temp
);
}
ECHO_EMV
(
" Cycles: "
,
ncycles
);
disable_all_heaters
();
// switch off all heaters.
ECHO_LM
(
DB
,
MSG_PID_AUTOTUNE_START
);
if
(
hotend
<
0
)
{
ECHO_SM
(
DB
,
"BED"
);
}
else
{
ECHO_SMV
(
DB
,
"Hotend: "
,
hotend
);
}
ECHO_MV
(
" Temp: "
,
temp
);
ECHO_EMV
(
" Cycles: "
,
ncycles
);
if
(
hotend
<
0
)
disable_all_heaters
();
// switch off all heaters.
soft_pwm_bed
=
bias
=
d
=
MAX_BED_POWER
/
2
;
else
soft_pwm
[
hotend
]
=
bias
=
d
=
PID_MAX
/
2
;
// PID Tuning loop
if
(
hotend
<
0
)
for
(;;)
{
soft_pwm_bed
=
bias
=
d
=
MAX_BED_POWER
/
2
;
else
soft_pwm
[
hotend
]
=
bias
=
d
=
PID_MAX
/
2
;
millis_t
ms
=
millis
();
// PID Tuning loop
for
(;;)
{
if
(
temp_meas_ready
)
{
// temp sample ready
millis_t
ms
=
millis
();
updateTemperaturesFromRawValues
();
input
=
(
hotend
<
0
)
?
current_temperature_bed
:
current_temperature
[
hotend
];
if
(
temp_meas_ready
)
{
// temp sample ready
updateTemperaturesFromRawValues
();
max
=
max
(
max
,
input
);
input
=
(
hotend
<
0
)
?
current_temperature_bed
:
current_temperature
[
hotend
];
min
=
min
(
min
,
input
);
#if HAS_AUTO_FAN
max
=
max
(
max
,
input
);
if
(
ms
>
next_auto_fan_check_ms
)
{
min
=
min
(
min
,
input
);
checkExtruderAutoFans
();
next_auto_fan_check_ms
=
ms
+
2500
;
}
#endif
if
(
heating
&&
input
>
temp
)
{
#if HAS_AUTO_FAN
if
(
ms
>
t2
+
5000
)
{
if
(
ms
>
next_auto_fan_check_ms
)
{
heating
=
false
;
checkExtruderAutoFans
();
if
(
hotend
<
0
)
next_auto_fan_check_ms
=
ms
+
2500
;
soft_pwm_bed
=
(
bias
-
d
)
>>
1
;
}
else
#endif
soft_pwm
[
hotend
]
=
(
bias
-
d
)
>>
1
;
t1
=
ms
;
if
(
heating
&&
input
>
temp
)
{
t_high
=
t1
-
t2
;
if
(
ms
>
t2
+
5000
)
{
max
=
temp
;
heating
=
false
;
if
(
hotend
<
0
)
soft_pwm_bed
=
(
bias
-
d
)
>>
1
;
else
soft_pwm
[
hotend
]
=
(
bias
-
d
)
>>
1
;
t1
=
ms
;
t_high
=
t1
-
t2
;
max
=
temp
;
}
}
}
}
if
(
!
heating
&&
input
<
temp
)
{
if
(
!
heating
&&
input
<
temp
)
{
if
(
ms
>
t1
+
5000
)
{
if
(
ms
>
t1
+
5000
)
{
heating
=
true
;
heating
=
true
;
t2
=
ms
;
t2
=
ms
;
t_low
=
t2
-
t1
;
t_low
=
t2
-
t1
;
if
(
cycles
>
0
)
{
if
(
cycles
>
0
)
{
long
max_pow
=
hotend
<
0
?
MAX_BED_POWER
:
PID_MAX
;
long
max_pow
=
hotend
<
0
?
MAX_BED_POWER
:
PID_MAX
;
bias
+=
(
d
*
(
t_high
-
t_low
))
/
(
t_low
+
t_high
);
bias
+=
(
d
*
(
t_high
-
t_low
))
/
(
t_low
+
t_high
);
bias
=
constrain
(
bias
,
20
,
max_pow
-
20
);
bias
=
constrain
(
bias
,
20
,
max_pow
-
20
);
d
=
(
bias
>
max_pow
/
2
)
?
max_pow
-
1
-
bias
:
bias
;
d
=
(
bias
>
max_pow
/
2
)
?
max_pow
-
1
-
bias
:
bias
;
ECHO_MV
(
MSG_BIAS
,
bias
);
ECHO_MV
(
MSG_BIAS
,
bias
);
ECHO_MV
(
MSG_D
,
d
);
ECHO_MV
(
MSG_D
,
d
);
ECHO_MV
(
MSG_T_MIN
,
min
);
ECHO_MV
(
MSG_T_MIN
,
min
);
ECHO_MV
(
MSG_T_MAX
,
max
);
ECHO_MV
(
MSG_T_MAX
,
max
);
if
(
cycles
>
2
)
{
if
(
cycles
>
2
)
{
Ku
=
(
4.0
*
d
)
/
(
3.14159265
*
(
max
-
min
)
/
2.0
);
Ku
=
(
4.0
*
d
)
/
(
3.14159265
*
(
max
-
min
)
/
2.0
);
Tu
=
((
float
)(
t_low
+
t_high
)
/
1000.0
);
Tu
=
((
float
)(
t_low
+
t_high
)
/
1000.0
);
ECHO_MV
(
MSG_KU
,
Ku
);
ECHO_MV
(
MSG_KU
,
Ku
);
ECHO_EMV
(
MSG_TU
,
Tu
);
ECHO_EMV
(
MSG_TU
,
Tu
);
Kp_temp
=
0.6
*
Ku
;
Kp_temp
=
0.6
*
Ku
;
Ki_temp
=
2
*
Kp_temp
/
Tu
;
Ki_temp
=
2
*
Kp_temp
/
Tu
;
Kd_temp
=
Kp_temp
*
Tu
/
8
;
Kd_temp
=
Kp_temp
*
Tu
/
8
;
ECHO_EM
(
MSG_CLASSIC_PID
);
ECHO_EM
(
MSG_CLASSIC_PID
);
ECHO_MV
(
MSG_KP
,
Kp_temp
);
ECHO_MV
(
MSG_KP
,
Kp_temp
);
ECHO_MV
(
MSG_KI
,
Ki_temp
);
ECHO_MV
(
MSG_KI
,
Ki_temp
);
ECHO_EMV
(
MSG_KD
,
Kd_temp
);
ECHO_EMV
(
MSG_KD
,
Kd_temp
);
}
}
else
{
else
{
ECHO_E
;
ECHO_E
;
}
}
}
if
(
hotend
<
0
)
soft_pwm_bed
=
(
bias
+
d
)
>>
1
;
else
soft_pwm
[
hotend
]
=
(
bias
+
d
)
>>
1
;
cycles
++
;
min
=
temp
;
}
}
if
(
hotend
<
0
)
soft_pwm_bed
=
(
bias
+
d
)
>>
1
;
else
soft_pwm
[
hotend
]
=
(
bias
+
d
)
>>
1
;
cycles
++
;
min
=
temp
;
}
}
}
}
}
if
(
input
>
temp
+
MAX_OVERSHOOT_PID_AUTOTUNE
)
{
if
(
input
>
temp
+
MAX_OVERSHOOT_PID_AUTOTUNE
)
{
ECHO_LM
(
ER
,
MSG_PID_TEMP_TOO_HIGH
);
ECHO_LM
(
ER
,
MSG_PID_TEMP_TOO_HIGH
);
return
;
return
;
}
// Every 2 seconds...
if
(
ms
>
temp_ms
+
2000
)
{
int
p
;
if
(
hotend
<
0
)
{
p
=
soft_pwm_bed
;
ECHO_MV
(
MSG_B
,
input
);
ECHO_MV
(
" /"
,
temp
,
1
);
ECHO_EMV
(
" "
MSG_AT
,
p
);
}
else
{
p
=
soft_pwm
[
hotend
];
ECHO_MV
(
MSG_T
,
input
,
1
);
ECHO_MV
(
" /"
,
temp
,
1
);
ECHO_EMV
(
" "
MSG_AT
,
p
);
}
}
temp_ms
=
ms
;
// Every 2 seconds...
}
// every 2 seconds
if
(
ms
>
temp_ms
+
2000
)
{
int
p
;
if
(
hotend
<
0
)
{
p
=
soft_pwm_bed
;
ECHO_MV
(
MSG_B
,
input
);
ECHO_MV
(
" /"
,
temp
,
1
);
ECHO_EMV
(
" "
MSG_AT
,
p
);
}
else
{
p
=
soft_pwm
[
hotend
];
ECHO_MV
(
MSG_T
,
input
,
1
);
ECHO_MV
(
" /"
,
temp
,
1
);
ECHO_EMV
(
" "
MSG_AT
,
p
);
}
// Over 2 minutes?
temp_ms
=
ms
;
if
(((
ms
-
t1
)
+
(
ms
-
t2
))
>
(
10L
*
60L
*
1000L
*
2L
))
{
}
// every 2 seconds
ECHO_LM
(
ER
,
MSG_PID_TIMEOUT
);
return
;
// Over 2 minutes?
}
if
(((
ms
-
t1
)
+
(
ms
-
t2
))
>
(
10L
*
60L
*
1000L
*
2L
))
{
if
(
cycles
>
ncycles
)
{
ECHO_LM
(
ER
,
MSG_PID_TIMEOUT
);
ECHO_LM
(
DB
,
MSG_PID_AUTOTUNE_FINISHED
);
return
;
if
(
hotend
>=
0
)
{
PID_PARAM
(
Kp
,
hotend
)
=
Kp_temp
;
PID_PARAM
(
Ki
,
hotend
)
=
scalePID_i
(
Ki_temp
);
PID_PARAM
(
Kd
,
hotend
)
=
scalePID_d
(
Kd_temp
);
updatePID
();
ECHO_SMV
(
DB
,
MSG_KP
,
PID_PARAM
(
Kp
,
hotend
));
ECHO_MV
(
MSG_KI
,
unscalePID_i
(
PID_PARAM
(
Ki
,
hotend
)));
ECHO_EMV
(
MSG_KD
,
unscalePID_d
(
PID_PARAM
(
Kd
,
hotend
)));
}
}
else
{
if
(
cycles
>
ncycles
)
{
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKp "
,
Kp_temp
);
ECHO_LM
(
DB
,
MSG_PID_AUTOTUNE_FINISHED
);
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKi "
,
unscalePID_i
(
Ki_temp
));
#ifdef PIDTEMP
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKd "
,
unscalePID_d
(
Kd_temp
));
if
(
hotend
>=
0
)
{
PID_PARAM
(
Kp
,
hotend
)
=
Kp_temp
;
PID_PARAM
(
Ki
,
hotend
)
=
scalePID_i
(
Ki_temp
);
PID_PARAM
(
Kd
,
hotend
)
=
scalePID_d
(
Kd_temp
);
updatePID
();
ECHO_SMV
(
DB
,
MSG_KP
,
PID_PARAM
(
Kp
,
hotend
));
ECHO_MV
(
MSG_KI
,
unscalePID_i
(
PID_PARAM
(
Ki
,
hotend
)));
ECHO_EMV
(
MSG_KD
,
unscalePID_d
(
PID_PARAM
(
Kd
,
hotend
)));
}
else
{
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKp "
,
Kp_temp
);
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKi "
,
unscalePID_i
(
Ki_temp
));
ECHO_LMV
(
DB
,
"#define DEFAULT_bedKd "
,
unscalePID_d
(
Kd_temp
));
}
#endif
return
;
}
}
return
;
lcd_update
()
;
}
}
lcd_update
();
}
}
}
#endif
void
updatePID
()
{
void
updatePID
()
{
#ifdef PIDTEMP
#ifdef PIDTEMP
...
@@ -1646,10 +1650,10 @@ ISR(TIMER0_COMPB_vect) {
...
@@ -1646,10 +1650,10 @@ ISR(TIMER0_COMPB_vect) {
#endif //BABYSTEPPING
#endif //BABYSTEPPING
}
}
#if
def PIDTEMP
#if
defined(PIDTEMP) || defined(PIDTEMPBED)
// Apply the scale factors to the PID values
// Apply the scale factors to the PID values
float
scalePID_i
(
float
i
)
{
return
i
*
PID_dT
;
}
float
scalePID_i
(
float
i
)
{
return
i
*
PID_dT
;
}
float
unscalePID_i
(
float
i
)
{
return
i
/
PID_dT
;
}
float
unscalePID_i
(
float
i
)
{
return
i
/
PID_dT
;
}
float
scalePID_d
(
float
d
)
{
return
d
/
PID_dT
;
}
float
scalePID_d
(
float
d
)
{
return
d
/
PID_dT
;
}
float
unscalePID_d
(
float
d
)
{
return
d
*
PID_dT
;
}
float
unscalePID_d
(
float
d
)
{
return
d
*
PID_dT
;
}
#endif //
PIDTEMP
#endif //
defined(PIDTEMP) || defined(PIDTEMPBED)
MarlinKimbra/temperature.h
View file @
a8e1e08b
...
@@ -64,16 +64,19 @@ extern float current_temperature_bed;
...
@@ -64,16 +64,19 @@ extern float current_temperature_bed;
#ifdef PIDTEMP
#ifdef PIDTEMP
extern
float
Kp
[
HOTENDS
],
Ki
[
HOTENDS
],
Kd
[
HOTENDS
];
extern
float
Kp
[
HOTENDS
],
Ki
[
HOTENDS
],
Kd
[
HOTENDS
];
#define PID_PARAM(param, e) param[e] // use macro to point to array value
#define PID_PARAM(param, e) param[e] // use macro to point to array value
float
scalePID_i
(
float
i
);
float
scalePID_d
(
float
d
);
float
unscalePID_i
(
float
i
);
float
unscalePID_d
(
float
d
);
#endif
#endif
#ifdef PIDTEMPBED
#ifdef PIDTEMPBED
extern
float
bedKp
,
bedKi
,
bedKd
;
extern
float
bedKp
,
bedKi
,
bedKd
;
#endif
#endif
#if defined(PIDTEMP) || defined(PIDTEMPBED)
float
scalePID_i
(
float
i
);
float
scalePID_d
(
float
d
);
float
unscalePID_i
(
float
i
);
float
unscalePID_d
(
float
d
);
#endif
#ifdef BABYSTEPPING
#ifdef BABYSTEPPING
extern
volatile
int
babystepsTodo
[
3
];
extern
volatile
int
babystepsTodo
[
3
];
#endif
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment