diff --git a/Configs/FYSETC_AIOII/README.md b/Configs/FYSETC_AIOII/README.md
index bb40715..956c8af 100644
--- a/Configs/FYSETC_AIOII/README.md
+++ b/Configs/FYSETC_AIOII/README.md
@@ -1,8 +1 @@
-# Sample Configuration Files
-
-Copy one of these files as "SMUFF.CFG" onto the SMuFFs SD-Card before you start it up.
-
-The \*_Duet.CFG defines all settings needed if you're running the SMuFF with a Duet3D controller board.
-The \*_PMMU.CFG defines all settings needed if you're running the SMuFF in Prusa MMU emulation mode.
-
-Configuration files with *Servo* in the name were needed if you've built the SMuFF servo version.
+# Please use the SKR_mini config files
diff --git a/Configs/FYSETC_AIOII/SMUFF_Duet.CFG b/Configs/FYSETC_AIOII/SMUFF_Duet.CFG
deleted file mode 100644
index 7463c2e..0000000
--- a/Configs/FYSETC_AIOII/SMUFF_Duet.CFG
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
- "ServoMinPwm": 550,
- "ServoMaxPwm": 2400,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": false,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
diff --git a/Configs/FYSETC_AIOII/SMUFF_PMMU.CFG b/Configs/FYSETC_AIOII/SMUFF_PMMU.CFG
deleted file mode 100644
index 26d9aec..0000000
--- a/Configs/FYSETC_AIOII/SMUFF_PMMU.CFG
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": false,
- "EmulatePrusa": true,
- "UnloadCommand": "",
- "ServoMinPwm": 550,
- "ServoMaxPwm": 2400,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": true,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": false,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
diff --git a/Configs/FYSETC_AIOII/SMUFF_Servo.CFG b/Configs/FYSETC_AIOII/SMUFF_Servo.CFG
deleted file mode 100644
index 715cf3b..0000000
--- a/Configs/FYSETC_AIOII/SMUFF_Servo.CFG
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": false,
- "EmulatePrusa": true,
- "UnloadCommand": "",
- "ServoMinPwm": 550,
- "ServoMaxPwm": 2400,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": true,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
diff --git a/Configs/FYSETC_AIOII/SMUFF_Servo_Duet.CFG b/Configs/FYSETC_AIOII/SMUFF_Servo_Duet.CFG
deleted file mode 100644
index b5e5dca..0000000
--- a/Configs/FYSETC_AIOII/SMUFF_Servo_Duet.CFG
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
- "ServoMinPwm": 550,
- "ServoMaxPwm": 2400,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
diff --git a/Configs/SKR_mini/SMUFF.CFG.json b/Configs/SKR_mini/SMUFF.CFG.json
new file mode 100644
index 0000000..af78030
--- /dev/null
+++ b/Configs/SKR_mini/SMUFF.CFG.json
@@ -0,0 +1,105 @@
+{
+ "Serial0Baudrate": 57600,
+ "Serial1Baudrate": 57600,
+ "Serial2Baudrate": 57600,
+ "Serial3Baudrate": 57600,
+ "ToolCount": 5,
+ "BowdenLength": 620.0,
+ "SelectorDist": 34.0,
+ "LCDContrast": 190,
+ "I2CAddress": 136,
+ "MenuAutoClose": 20,
+ "FanSpeed": 50,
+ "PowerSaveTimeout": 300,
+ "SendActionCmds": false,
+ "EmulatePrusa": true,
+ "UnloadCommand": "",
+ "ServoMinPwm": 800,
+ "ServoMaxPwm": 2400,
+ "WipeSequence": "S200 I140 J160 P90 R20",
+ "BacklightColor": 4,
+ "HasPanelDue": 0,
+ "EncoderTicks": false,
+ "SendPeriodicalStats": true,
+
+ "Selector": {
+ "Offset": 0.5,
+ "Spacing": 21.0,
+ "StepsPerMillimeter": 80,
+ "Acceleration": 12000,
+ "MaxSpeed": 2000,
+ "MaxSpeedHS": 2500,
+ "InvertDir": false,
+ "EndstopTrigger": 1,
+ "StepDelay": 10,
+ "Mode": 1,
+ "Power": 700,
+ "RSense": 0.11,
+ "Microsteps": 16,
+ "Stall": 0,
+ "CoolStepMin": 5,
+ "CoolStepMax": 2,
+ "CoolStepDown": 1,
+ "DriverAddress": 0
+ },
+ "Revolver": {
+ "StepsPerRevolution": 9600,
+ "Offset": 1275,
+ "Acceleration": 22000,
+ "MaxSpeed": 10000,
+ "ResetBeforeFeed": true,
+ "HomeAfterFeed": true,
+ "InvertDir": false,
+ "EndstopTrigger": 1,
+ "StepDelay": 5,
+ "Wiggle": false,
+ "UseServo": true,
+ "ServoOffPos": 30,
+ "ServoOnPos": 90,
+ "Power": 700,
+ "Mode": 1,
+ "RSense": 0.11,
+ "Microsteps": 16,
+ "Stall": 0,
+ "CoolStepMin": 5,
+ "CoolStepMax": 2,
+ "CoolStepDown": 1,
+ "DriverAddress": 0
+ },
+ "Feeder": {
+ "ExternalControl": true,
+ "StepsPerMillimeter": 410,
+ "Acceleration": 20000,
+ "MaxSpeed": 1400,
+ "InsertSpeed": 20000,
+ "ReinforceLength": 0,
+ "UnloadRetract": 0,
+ "UnloadPushback": 0,
+ "PushbackDelay": 2.0,
+ "InvertDir": true,
+ "EndstopTrigger": 1,
+ "StepDelay": 3,
+ "EnableChunks": false,
+ "FeedChunks": 20,
+ "InsertLength": 5,
+ "DuetLaser": false,
+ "SharedStepper": false,
+ "Mode": 1,
+ "Power": 700,
+ "RSense": 0.11,
+ "Microsteps": 16,
+ "Stall": 0,
+ "CoolStepMin": 5,
+ "CoolStepMax": 2,
+ "CoolStepDown": 1,
+ "DriverAddress": 0
+ },
+ "Materials": {
+ "T0": "PLA Green",
+ "T1": "PLA White",
+ "T2": "PLA Red",
+ "T3": "PLA Black",
+ "T4": "PLA Silver"
+ }
+}
+
diff --git a/Configs/SKR_mini/SMUFF_Duet.CFG b/Configs/SKR_mini/SMUFF_Duet.CFG
deleted file mode 100644
index 54f2b26..0000000
--- a/Configs/SKR_mini/SMUFF_Duet.CFG
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": false,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/SKR_mini/SMUFF_PMMU.CFG b/Configs/SKR_mini/SMUFF_PMMU.CFG
deleted file mode 100644
index 91b742c..0000000
--- a/Configs/SKR_mini/SMUFF_PMMU.CFG
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": false,
- "EmulatePrusa": true,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": true,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": false,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
-
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/SKR_mini/SMUFF_Servo.CFG b/Configs/SKR_mini/SMUFF_Servo.CFG
deleted file mode 100644
index 1e630a2..0000000
--- a/Configs/SKR_mini/SMUFF_Servo.CFG
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": false,
- "EmulatePrusa": true,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": true,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
-
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/SKR_mini/SMUFF_Servo_Duet.CFG b/Configs/SKR_mini/SMUFF_Servo_Duet.CFG
deleted file mode 100644
index 45c9daf..0000000
--- a/Configs/SKR_mini/SMUFF_Servo_Duet.CFG
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 12000,
- "MaxSpeed": 2000,
- "MaxSpeedHS": 2500,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 10
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 20000,
- "MaxSpeed": 1400,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 3,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/SMuFF_ESP32/README.md b/Configs/SMuFF_ESP32/README.md
index 70f7168..956c8af 100644
--- a/Configs/SMuFF_ESP32/README.md
+++ b/Configs/SMuFF_ESP32/README.md
@@ -1,3 +1 @@
-# Sample Configuration Files
-
-Copy one of these files as "SMUFF.CFG" onto the SMuFFs SD-Card before you start it up.
+# Please use the SKR_mini config files
diff --git a/Configs/SMuFF_ESP32/SMUFF_Servo.CFG b/Configs/SMuFF_ESP32/SMUFF_Servo.CFG
deleted file mode 100644
index ba890e1..0000000
--- a/Configs/SMuFF_ESP32/SMUFF_Servo.CFG
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": false,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 30,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": false,
- "EmulatePrusa": true,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 10000,
- "MaxSpeed": 2200,
- "MaxSpeedHS": 2000,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 0
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 1000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": true,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 0,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90,
- "ServoCycles": 0
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 10000,
- "MaxSpeed": 1000,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 0,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/SMuFF_ESP32/SMUFF_Servo_Duet.CFG b/Configs/SMuFF_ESP32/SMUFF_Servo_Duet.CFG
deleted file mode 100644
index 2fb4d1a..0000000
--- a/Configs/SMuFF_ESP32/SMUFF_Servo_Duet.CFG
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "HasPanelDue": true,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 30,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
- "ServoMinPwm": 1000,
- "ServoMaxPwm": 2000,
- "WipeSequence": "S200 I140 J160 P90 R20",
- "BacklightColor": 4,
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 10000,
- "MaxSpeed": 2200,
- "MaxSpeedHS": 2000,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 0
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 22000,
- "MaxSpeed": 10000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 5,
- "Wiggle": false,
- "UseServo": true,
- "ServoOffPos": 30,
- "ServoOnPos": 90,
- "ServoCycles": 0
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 10000,
- "MaxSpeed": 1000,
- "InsertSpeed": 20000,
- "ReinforceLength": 0,
- "UnloadRetract": 0,
- "UnloadPushback": 0,
- "PushbackDelay": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 0,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5
- },
- "Materials": {
- "T0": "PLA Green",
- "T1": "PLA White",
- "T2": "PLA Red",
- "T3": "PLA Black",
- "T4": "PLA Silver"
- }
-}
-
diff --git a/Configs/Wanhao_i3_mini/SMUFF_PMMU.CFG b/Configs/Wanhao_i3_mini/SMUFF.CFG.json
similarity index 90%
rename from Configs/Wanhao_i3_mini/SMUFF_PMMU.CFG
rename to Configs/Wanhao_i3_mini/SMUFF.CFG.json
index 33129c9..19090fe 100644
--- a/Configs/Wanhao_i3_mini/SMUFF_PMMU.CFG
+++ b/Configs/Wanhao_i3_mini/SMUFF.CFG.json
@@ -1,7 +1,8 @@
{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
+ "Serial0Baudrate": 57600,
+ "Serial1Baudrate": 57600,
+ "Serial2Baudrate": 57600,
+ "Serial3Baudrate": 57600,
"ToolCount": 5,
"BowdenLength": 620.0,
"SelectorDist": 34.0,
@@ -9,7 +10,6 @@
"I2CAddress": 136,
"MenuAutoClose": 20,
"FanSpeed": 50,
- "DelayBetweenPulses": false,
"PowerSaveTimeout": 300,
"Duet3DDirect": false,
"EmulatePrusa": true,
diff --git a/Configs/Wanhao_i3_mini/SMUFF_Duet.CFG b/Configs/Wanhao_i3_mini/SMUFF_Duet.CFG
deleted file mode 100644
index 9fda40e..0000000
--- a/Configs/Wanhao_i3_mini/SMUFF_Duet.CFG
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "Serial1Baudrate": 56700,
- "Serial2Baudrate": 56700,
- "SerialDueBaudrate": 56700,
- "ToolCount": 5,
- "BowdenLength": 620.0,
- "SelectorDist": 34.0,
- "LCDContrast": 190,
- "I2CAddress": 136,
- "MenuAutoClose": 20,
- "FanSpeed": 50,
- "DelayBetweenPulses": false,
- "PowerSaveTimeout": 300,
- "Duet3DDirect": true,
- "EmulatePrusa": false,
- "UnloadCommand": "",
-
- "Selector": {
- "Offset": 0.5,
- "Spacing": 21.0,
- "StepsPerMillimeter": 80,
- "Acceleration": 900,
- "MaxSpeed": 100,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 20
- },
- "Revolver": {
- "StepsPerRevolution": 9600,
- "Offset": 1275,
- "Acceleration": 6000,
- "MaxSpeed": 1000,
- "ResetBeforeFeed": true,
- "HomeAfterFeed": false,
- "InvertDir": false,
- "EndstopTrigger": 1,
- "StepDelay": 20,
- "Wiggle": false
- },
- "Feeder": {
- "ExternalControl": true,
- "StepsPerMillimeter": 410,
- "Acceleration": 1000,
- "MaxSpeed": 1,
- "InsertSpeed": 1000,
- "ReinforceLength": 2.0,
- "InvertDir": true,
- "EndstopTrigger": 1,
- "StepDelay": 20,
- "EnableChunks": false,
- "FeedChunks": 20,
- "InsertLength": 5,
- "DuetLaser": false
- }
-}
-
diff --git a/README.md b/README.md
index a9d08c1..262bc77 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ The basic configuration (SMuFF.cfg) must to be located on the SD-Card. Thus, cha
From version 1.6 on, the firmware has been enhanced in order to enable you making changes directly from the UI, which means: No more fiddling in the JSON file.
Also new in the 1.6 version is the option to run GCode scripts from the SD-Card for testing purposes. In the **test** folder you'll find some sample scripts. Copy those to your SD-Card and pick one from within the menu to start the test run. Once started, the test will run infinitelly and can be stopped by clicking the encoder button.
-For further information head over to the [Wiki pages](https://github.com/technik-gegg/SMuFF-1.1/wiki).
+For more information head over to [the SMuFF website](https://sites.google.com/view/the-smuff/).
## What else?
@@ -26,6 +26,31 @@ If you like this project and find it useful, feel free to place a donation via P
## Recent changes
+**2.10** - A lot of changes, such as TMC driver support; **Please read on**
+
++ finished the implementation of the Duet3D Laser Sensor (V2) which can be used as the Feeder endstop and is able to monitor filament jams.
++ added GCode **M412** which will switch on/off runout/jam detection or report its status, when using a Duet3D Laser Sensor.
++ removed configuration file variants. There's only one general config file left.
++ renamed configuration file from **.CFG** to **.CFG.json**. This makes it easier for some after market *VS-Code extensions* to validate and format its content. **Please notice:** This file is meant as a template for your initial configuration. Make sure you rename the template file to "**SMuFF.CFG**" after you've copied it onto the SMuFF's SD-Card.
++ added GCode **M17** which enables you to switch a relay in order to switch from external stepper (3D-Printer) to internal stepper (SMuFF). The parameter must either be **E** for the **external** or **I** for the **internal** stepper. The relay is controlled over the **RELAIS_PIN** in Pins.h. Read more about this [new feature here](https://sites.google.com/view/the-smuff/work-in-progress?authuser=0#h.qbpb6pvlq20x).
++ overhauled Settings Menu (moved additional settings into Options menu).
++ added **Serial0Baudrate** (for USB port) to config files, renamed **SerialDueBaudrate** to **Serial3Baudrate**.
++ fixed a bug for the old Revolver version where it refused to home correctly.
++ added defines for SERVO_LID and SERVO_WIPER for better code readability.
++ changed the behavior of boolean inputs (YES/NO and HI/LO) in the menus (they're single click now).
++ changed the increments on all stepper speeds (they'll now increment/decrement by 50).
++ moved some of the most common build flags (i.e. USE_xxx_DISPLAY) to the top of [platformio.ini](https://sites.google.com/view/the-smuff/how-to/tutorials/compile-the-firmware?authuser=0#h.3e6724efr6vl).
++ moved all initializing functions into **SetupInit.cpp**. SMuFF.cpp and setup() got much more streamlined now.
++ moved all periodical functions into **Periodicals.cpp**.
++ periodicals are now called from within **loop()**, which makes them more stable when handling serial I/O.
++ added the [SKR mini E3 V1.2](https://www.biqu.equipment/products/bigtreetech-skr-mini-e3-control-board-32-bit-integrated-tmc2209-uart-for-ender-4) and [SKR mini E3 DIP V1.1](https://www.biqu.equipment/products/bigtreetech-skr-e3-dip-v1-0-motherboard-for-ender-3) to the collection of usable boards.
++ rewrote the timers code. Encoder, Servos and Fans are now being served by one general purpose timer only. Servos are far more stable now.
++ added TMC-Stepper library for being able to support TMC2209 stepper drivers.
++ added TMC-Params to the stepper menus. You'll need those settings at least on the SKR mini **E3**, on the SKR mini **E3DIP** when using TMC2209s.
++ added GCodes **M122**, **M350**, **M569**, **M906** and **M914** for handling TMC stepper driver settings (see Marlin GCode what they're used for).
++ got the USB port working on E3 and E3 DIP on Windows.
++ added a couple of more parameters supported by the [M205 GCode](https://sites.google.com/view/the-smuff/tips-hints/talk-to-the-smuff?authuser=0#h.g5l7kws0923c) command.
+
**2.09** - Bugfix for PMMU mode
+ fixed the bug which didn't realize the **A**(bort) command comming from Marlins MMU code
diff --git a/Schematics/SKR mini E3 (DIP) LCD board/SKR mini E3 LCD board.pdf b/Schematics/SKR mini E3 (DIP) LCD board/SKR mini E3 LCD board.pdf
new file mode 100644
index 0000000..49b845f
Binary files /dev/null and b/Schematics/SKR mini E3 (DIP) LCD board/SKR mini E3 LCD board.pdf differ
diff --git a/Schematics/SKR mini LCD board/SKR mini E3 LCD board-cache.lib b/Schematics/SKR mini LCD board/SKR mini E3 LCD board-cache.lib
new file mode 100644
index 0000000..f9c509f
--- /dev/null
+++ b/Schematics/SKR mini LCD board/SKR mini E3 LCD board-cache.lib
@@ -0,0 +1,202 @@
+EESchema-LIBRARY Version 2.4
+#encoding utf-8
+#
+# Connector_Generic_Conn_02x05_Odd_Even
+#
+DEF Connector_Generic_Conn_02x05_Odd_Even J 0 40 Y N 1 F N
+F0 "J" 50 300 50 H V C CNN
+F1 "Connector_Generic_Conn_02x05_Odd_Even" 50 -300 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ Connector*:*_2x??_*
+$ENDFPLIST
+DRAW
+S -50 -195 0 -205 1 1 6 N
+S -50 -95 0 -105 1 1 6 N
+S -50 5 0 -5 1 1 6 N
+S -50 105 0 95 1 1 6 N
+S -50 205 0 195 1 1 6 N
+S -50 250 150 -250 1 1 10 f
+S 150 -195 100 -205 1 1 6 N
+S 150 -95 100 -105 1 1 6 N
+S 150 5 100 -5 1 1 6 N
+S 150 105 100 95 1 1 6 N
+S 150 205 100 195 1 1 6 N
+X Pin_1 1 -200 200 150 R 50 50 1 1 P
+X Pin_10 10 300 -200 150 L 50 50 1 1 P
+X Pin_2 2 300 200 150 L 50 50 1 1 P
+X Pin_3 3 -200 100 150 R 50 50 1 1 P
+X Pin_4 4 300 100 150 L 50 50 1 1 P
+X Pin_5 5 -200 0 150 R 50 50 1 1 P
+X Pin_6 6 300 0 150 L 50 50 1 1 P
+X Pin_7 7 -200 -100 150 R 50 50 1 1 P
+X Pin_8 8 300 -100 150 L 50 50 1 1 P
+X Pin_9 9 -200 -200 150 R 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_Buzzer
+#
+DEF Device_Buzzer BZ 0 1 Y N 1 F N
+F0 "BZ" 150 50 50 H V L CNN
+F1 "Device_Buzzer" 150 -50 50 H V L CNN
+F2 "" -25 100 50 V I C CNN
+F3 "" -25 100 50 V I C CNN
+$FPLIST
+ *Buzzer*
+$ENDFPLIST
+DRAW
+A 0 0 125 -899 899 0 1 0 N 0 -125 0 125
+P 2 0 1 0 -65 75 -45 75 N
+P 2 0 1 0 -55 85 -55 65 N
+P 2 0 1 0 0 125 0 -125 N
+X - 1 -100 100 100 R 50 50 1 1 P
+X + 2 -100 -100 100 R 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_R
+#
+DEF Device_R R 0 0 N Y 1 F N
+F0 "R" 80 0 50 V V C CNN
+F1 "Device_R" 0 0 50 V V C CNN
+F2 "" -70 0 50 V I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ R_*
+$ENDFPLIST
+DRAW
+S -40 -100 40 100 0 1 10 N
+X ~ 1 0 150 50 D 50 50 1 1 P
+X ~ 2 0 -150 50 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_Rotary_Encoder_Switch
+#
+DEF Device_Rotary_Encoder_Switch SW 0 10 Y N 1 F N
+F0 "SW" 0 260 50 H V C CNN
+F1 "Device_Rotary_Encoder_Switch" 0 -260 50 H V C CNN
+F2 "" -150 160 50 H I C CNN
+F3 "" 0 260 50 H I C CNN
+$FPLIST
+ RotaryEncoder*Switch*
+$ENDFPLIST
+DRAW
+A -15 -2 108 -899 899 0 1 10 N -15 -110 -15 105
+C -150 0 10 0 1 0 F
+C -15 0 75 0 1 10 N
+C 170 -40 5 0 1 10 N
+C 170 40 5 0 1 10 N
+S -200 200 200 -200 0 1 10 f
+P 2 0 1 10 -25 -70 -25 70 N
+P 2 0 1 10 -15 -70 -15 70 N
+P 2 0 1 10 -5 70 -5 -70 N
+P 2 0 1 10 150 0 135 0 N
+P 2 0 1 10 150 40 150 -40 N
+P 3 0 1 0 -200 -100 -150 -100 -150 -80 N
+P 3 0 1 0 -200 100 -150 100 -150 80 N
+P 3 0 1 10 10 -120 -20 -110 5 -95 N
+P 3 0 1 10 10 115 -20 105 5 90 N
+P 3 0 1 10 200 -100 170 -100 170 -40 N
+P 3 0 1 10 200 100 170 100 170 40 N
+P 4 0 1 0 -200 0 -150 0 -150 -40 -130 -80 N
+P 4 0 1 0 -170 0 -150 0 -150 40 -130 80 N
+X A A -300 100 100 R 50 50 1 1 P
+X B B -300 -100 100 R 50 50 1 1 P
+X C C -300 0 100 R 50 50 1 1 P
+X S1 S1 300 100 100 L 50 50 1 1 P
+X S2 S2 300 -100 100 L 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32
+#
+DEF SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32 U 0 40 Y Y 1 F N
+F0 "U" -600 600 60 H V R TNN
+F1 "SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32" -1350 600 60 H V L TNN
+F2 "" 0 0 60 H I C CNN
+F3 "" 0 0 60 H I C CNN
+DRAW
+S -1400 650 -450 100 0 1 0 N
+X VCC 1 -1250 0 100 U 50 50 1 1 I
+X VSS 2 -1050 0 100 U 50 50 1 1 O
+X SCL 3 -850 0 100 U 50 50 1 1 I
+X SDA 4 -650 0 100 U 50 50 1 1 I
+ENDDRAW
+ENDDEF
+#
+# Switch_SW_DIP_x01
+#
+DEF Switch_SW_DIP_x01 SW 0 0 Y N 1 F N
+F0 "SW" 0 150 50 H V C CNN
+F1 "Switch_SW_DIP_x01" 0 -150 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ SW?DIP?x1*
+$ENDFPLIST
+DRAW
+C -80 0 20 0 0 0 N
+C 80 0 20 0 0 0 N
+S -150 100 150 -100 0 1 10 f
+P 2 0 0 0 -60 5 93 46 N
+X ~ 1 -300 0 200 R 50 50 1 1 P
+X ~ 2 300 0 200 L 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Transistor_BJT_BC547
+#
+DEF Transistor_BJT_BC547 Q 0 0 Y N 1 F N
+F0 "Q" 200 75 50 H V L CNN
+F1 "Transistor_BJT_BC547" 200 0 50 H V L CNN
+F2 "Package_TO_SOT_THT:TO-92_Inline" 200 -75 50 H I L CIN
+F3 "" 0 0 50 H I L CNN
+ALIAS BC546 BC548 BC549 BC550 BC337 BC338
+$FPLIST
+ TO?92*
+$ENDFPLIST
+DRAW
+C 50 0 111 0 1 10 N
+P 2 0 1 0 0 0 25 0 N
+P 2 0 1 0 25 25 100 100 N
+P 3 0 1 0 25 -25 100 -100 100 -100 N
+P 3 0 1 20 25 75 25 -75 25 -75 N
+P 5 0 1 0 50 -70 70 -50 90 -90 50 -70 50 -70 F
+X C 1 100 200 100 D 50 50 1 1 P
+X B 2 -200 0 200 R 50 50 1 1 I
+X E 3 100 -200 100 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# power_+5V
+#
+DEF power_+5V #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 -150 50 H I C CNN
+F1 "power_+5V" 0 140 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+DRAW
+P 2 0 1 0 -30 50 0 100 N
+P 2 0 1 0 0 0 0 100 N
+P 2 0 1 0 0 100 30 50 N
+X +5V 1 0 0 0 U 50 50 1 1 W N
+ENDDRAW
+ENDDEF
+#
+# power_GND
+#
+DEF power_GND #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 -250 50 H I C CNN
+F1 "power_GND" 0 -150 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+DRAW
+P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
+X GND 1 0 0 0 D 50 50 1 1 W N
+ENDDRAW
+ENDDEF
+#
+#End Library
diff --git a/Schematics/SKR mini LCD board/SKR mini E3 LCD board.pro b/Schematics/SKR mini LCD board/SKR mini E3 LCD board.pro
new file mode 100644
index 0000000..9c12f44
--- /dev/null
+++ b/Schematics/SKR mini LCD board/SKR mini E3 LCD board.pro
@@ -0,0 +1,43 @@
+update=15.08.2020 07:20:00
+version=1
+last_client=kicad
+[general]
+version=1
+RootSch=
+BoardNm=
+[pcbnew]
+version=1
+LastNetListRead=
+UseCmpFile=1
+PadDrill=0.600000000000
+PadDrillOvalY=0.600000000000
+PadSizeH=1.500000000000
+PadSizeV=1.500000000000
+PcbTextSizeV=1.500000000000
+PcbTextSizeH=1.500000000000
+PcbTextThickness=0.300000000000
+ModuleTextSizeV=1.000000000000
+ModuleTextSizeH=1.000000000000
+ModuleTextSizeThickness=0.150000000000
+SolderMaskClearance=0.000000000000
+SolderMaskMinWidth=0.000000000000
+DrawSegmentWidth=0.200000000000
+BoardOutlineThickness=0.100000000000
+ModuleOutlineThickness=0.150000000000
+[cvpcb]
+version=1
+NetIExt=net
+[eeschema]
+version=1
+LibDir=
+[eeschema/libraries]
+[schematic_editor]
+version=1
+PageLayoutDescrFile=
+PlotDirectoryName=D:/Data/PlatformIO/SMuFF/Schematics/SKR mini E3 (DIP) LCD board/
+SubpartIdSeparator=0
+SubpartFirstId=65
+NetFmtName=
+SpiceAjustPassiveValues=0
+LabSize=50
+ERC_TestSimilarLabels=1
diff --git a/Schematics/SKR mini LCD board/SKR mini E3 LCD board.sch b/Schematics/SKR mini LCD board/SKR mini E3 LCD board.sch
new file mode 100644
index 0000000..d08d7b7
--- /dev/null
+++ b/Schematics/SKR mini LCD board/SKR mini E3 LCD board.sch
@@ -0,0 +1,315 @@
+EESchema Schematic File Version 4
+LIBS:SKR mini LCD board-cache
+EELAYER 29 0
+EELAYER END
+$Descr A4 11693 8268
+encoding utf-8
+Sheet 1 1
+Title "SKR Mini E3 (DIP) LCD board"
+Date "2020-08-15"
+Rev "1"
+Comp "Technik Gegg"
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+$Comp
+L SKR-mini-LCD-board-rescue:SSD1306-SSD1306_OLED-0.91-128x32 U1
+U 1 1 5D888A8E
+P 3150 3550
+F 0 "U1" V 1563 3867 60 0000 C CNN
+F 1 "SSD1306 0.96\" OLED" V 1669 3867 60 0000 C CNN
+F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical" H 3150 3550 60 0001 C CNN
+F 3 "" H 3150 3550 60 0001 C CNN
+ 1 3150 3550
+ 0 -1 1 0
+$EndComp
+$Comp
+L Device:Rotary_Encoder_Switch ENC1
+U 1 1 5D88B3FF
+P 5000 5500
+F 0 "ENC1" H 5000 5867 50 0000 C CNN
+F 1 "Rotary Encoder" H 5000 5776 50 0000 C CNN
+F 2 "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_CircularMountingHoles" H 4850 5660 50 0001 C CNN
+F 3 "~" H 5000 5760 50 0001 C CNN
+ 1 5000 5500
+ 1 0 0 -1
+$EndComp
+$Comp
+L Connector_Generic:Conn_02x05_Odd_Even J1
+U 1 1 5D88D2F1
+P 5850 4400
+F 0 "J1" H 5900 4817 50 0000 C CNN
+F 1 "Connector 5x2" H 5900 4726 50 0000 C CNN
+F 2 "Connector_PinSocket_2.54mm:PinSocket_2x05_P2.54mm_Vertical" H 5850 4400 50 0001 C CNN
+F 3 "~" H 5850 4400 50 0001 C CNN
+ 1 5850 4400
+ 1 0 0 -1
+$EndComp
+$Comp
+L Device:R R1
+U 1 1 5D8937B1
+P 3850 5400
+F 0 "R1" V 4057 5400 50 0000 C CNN
+F 1 "10K" V 3966 5400 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5400 50 0001 C CNN
+F 3 "~" H 3850 5400 50 0001 C CNN
+ 1 3850 5400
+ 0 -1 -1 0
+$EndComp
+$Comp
+L Device:Buzzer BZ1
+U 1 1 5D893D6F
+P 7400 4100
+F 0 "BZ1" H 7600 4150 50 0000 L CNN
+F 1 "Buzzer" H 7600 4050 50 0000 L CNN
+F 2 "Buzzer_Beeper:Buzzer_12x9.5RM7.6" V 7375 4200 50 0001 C CNN
+F 3 "~" V 7375 4200 50 0001 C CNN
+ 1 7400 4100
+ 1 0 0 -1
+$EndComp
+$Comp
+L Switch:SW_DIP_x01 SW1
+U 1 1 5D894E2A
+P 3750 4500
+F 0 "SW1" H 3750 4767 50 0000 C CNN
+F 1 "Reset" H 3750 4676 50 0000 C CNN
+F 2 "Button_Switch_THT:SW_PUSH_6mm_H7.3mm" H 3750 4500 50 0001 C CNN
+F 3 "~" H 3750 4500 50 0001 C CNN
+ 1 3750 4500
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:+5V #PWR0101
+U 1 1 5D89576B
+P 3400 5400
+F 0 "#PWR0101" H 3400 5250 50 0001 C CNN
+F 1 "+5V" V 3415 5528 50 0000 L CNN
+F 2 "" H 3400 5400 50 0001 C CNN
+F 3 "" H 3400 5400 50 0001 C CNN
+ 1 3400 5400
+ 0 -1 -1 0
+$EndComp
+$Comp
+L power:+5V #PWR0102
+U 1 1 5D896CC4
+P 5450 3800
+F 0 "#PWR0102" H 5450 3650 50 0001 C CNN
+F 1 "+5V" H 5465 3973 50 0000 C CNN
+F 2 "" H 5450 3800 50 0001 C CNN
+F 3 "" H 5450 3800 50 0001 C CNN
+ 1 5450 3800
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:+5V #PWR0103
+U 1 1 5D89755D
+P 3500 2100
+F 0 "#PWR0103" H 3500 1950 50 0001 C CNN
+F 1 "+5V" H 3515 2273 50 0000 C CNN
+F 2 "" H 3500 2100 50 0001 C CNN
+F 3 "" H 3500 2100 50 0001 C CNN
+ 1 3500 2100
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0104
+U 1 1 5D897F1D
+P 3300 4750
+F 0 "#PWR0104" H 3300 4500 50 0001 C CNN
+F 1 "GND" H 3305 4577 50 0000 C CNN
+F 2 "" H 3300 4750 50 0001 C CNN
+F 3 "" H 3300 4750 50 0001 C CNN
+ 1 3300 4750
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0105
+U 1 1 5D898A40
+P 3550 2500
+F 0 "#PWR0105" H 3550 2250 50 0001 C CNN
+F 1 "GND" H 3555 2327 50 0000 C CNN
+F 2 "" H 3550 2500 50 0001 C CNN
+F 3 "" H 3550 2500 50 0001 C CNN
+ 1 3550 2500
+ 0 -1 -1 0
+$EndComp
+$Comp
+L power:GND #PWR0106
+U 1 1 5D899BAF
+P 5650 5700
+F 0 "#PWR0106" H 5650 5450 50 0001 C CNN
+F 1 "GND" H 5655 5527 50 0000 C CNN
+F 2 "" H 5650 5700 50 0001 C CNN
+F 3 "" H 5650 5700 50 0001 C CNN
+ 1 5650 5700
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0107
+U 1 1 5D89A417
+P 7300 4900
+F 0 "#PWR0107" H 7300 4650 50 0001 C CNN
+F 1 "GND" H 7305 4727 50 0000 C CNN
+F 2 "" H 7300 4900 50 0001 C CNN
+F 3 "" H 7300 4900 50 0001 C CNN
+ 1 7300 4900
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 5650 4200 5450 4200
+Wire Wire Line
+ 5450 4200 5450 3800
+Wire Wire Line
+ 3150 2300 3500 2300
+Wire Wire Line
+ 3500 2300 3500 2100
+Wire Wire Line
+ 3150 2500 3550 2500
+Wire Wire Line
+ 3450 4500 3300 4500
+Wire Wire Line
+ 3300 4500 3300 4750
+Wire Wire Line
+ 7300 4800 7300 4900
+$Comp
+L power:GND #PWR0108
+U 1 1 5D89B98C
+P 6250 3800
+F 0 "#PWR0108" H 6250 3550 50 0001 C CNN
+F 1 "GND" H 6255 3627 50 0000 C CNN
+F 2 "" H 6250 3800 50 0001 C CNN
+F 3 "" H 6250 3800 50 0001 C CNN
+ 1 6250 3800
+ -1 0 0 1
+$EndComp
+Wire Wire Line
+ 6150 4200 6250 4200
+Wire Wire Line
+ 4700 5500 4400 5500
+Wire Wire Line
+ 5300 5600 5650 5600
+Wire Wire Line
+ 5650 5600 5650 5700
+$Comp
+L Device:R R2
+U 1 1 5D892B67
+P 3850 5950
+F 0 "R2" V 4057 5950 50 0000 C CNN
+F 1 "10K" V 3966 5950 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5950 50 0001 C CNN
+F 3 "~" H 3850 5950 50 0001 C CNN
+ 1 3850 5950
+ 0 -1 -1 0
+$EndComp
+Wire Wire Line
+ 4000 5950 4300 5950
+Wire Wire Line
+ 4300 5600 4300 5950
+$Comp
+L power:GND #PWR0109
+U 1 1 5D8A9A64
+P 4400 5500
+F 0 "#PWR0109" H 4400 5250 50 0001 C CNN
+F 1 "GND" V 4405 5372 50 0000 R CNN
+F 2 "" H 4400 5500 50 0001 C CNN
+F 3 "" H 4400 5500 50 0001 C CNN
+ 1 4400 5500
+ 0 1 1 0
+$EndComp
+Wire Wire Line
+ 3150 2700 4700 2700
+Wire Wire Line
+ 4500 2900 3150 2900
+Wire Wire Line
+ 3550 5400 3700 5400
+Wire Wire Line
+ 3550 5950 3700 5950
+Wire Wire Line
+ 4300 5600 4700 5600
+Connection ~ 4300 5950
+Wire Wire Line
+ 6250 3800 6250 4200
+Wire Wire Line
+ 3400 5400 3550 5400
+Connection ~ 3550 5400
+Wire Wire Line
+ 3550 5400 3550 5950
+$Comp
+L power:+5V #PWR?
+U 1 1 5F377DF5
+P 7300 3850
+F 0 "#PWR?" H 7300 3700 50 0001 C CNN
+F 1 "+5V" H 7315 4023 50 0000 C CNN
+F 2 "" H 7300 3850 50 0001 C CNN
+F 3 "" H 7300 3850 50 0001 C CNN
+ 1 7300 3850
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 7300 3850 7300 4000
+$Comp
+L Device:R R3
+U 1 1 5F3793FA
+P 6750 4600
+F 0 "R3" V 6750 4600 50 0000 C CNN
+F 1 "1K" V 6650 4600 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 6680 4600 50 0001 C CNN
+F 3 "~" H 6750 4600 50 0001 C CNN
+ 1 6750 4600
+ 0 -1 -1 0
+$EndComp
+$Comp
+L Transistor_BJT:BC547 Q1
+U 1 1 5F37DDBD
+P 7200 4600
+F 0 "Q1" H 7391 4646 50 0000 L CNN
+F 1 "BC547" H 7391 4555 50 0000 L CNN
+F 2 "Package_TO_SOT_THT:TO-92_Inline" H 7400 4525 50 0001 L CIN
+F 3 "http://www.fairchildsemi.com/ds/BC/BC547.pdf" H 7200 4600 50 0001 L CNN
+ 1 7200 4600
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 7300 4200 7300 4400
+Wire Wire Line
+ 6900 4600 7000 4600
+Wire Wire Line
+ 6150 4300 6250 4300
+Wire Wire Line
+ 6250 4300 6250 5400
+Wire Wire Line
+ 5300 5400 6250 5400
+Wire Wire Line
+ 4000 5400 4300 5400
+Wire Wire Line
+ 5650 4300 4500 4300
+Wire Wire Line
+ 4500 4300 4500 2900
+Wire Wire Line
+ 4700 4600 4700 2700
+Wire Wire Line
+ 4700 4600 5650 4600
+Wire Wire Line
+ 5650 4500 4050 4500
+Wire Wire Line
+ 6150 4400 6200 4400
+Wire Wire Line
+ 6200 4400 6200 5000
+Wire Wire Line
+ 6200 5000 4300 5000
+Wire Wire Line
+ 4300 5000 4300 5400
+Connection ~ 4300 5400
+Wire Wire Line
+ 4300 5400 4700 5400
+Wire Wire Line
+ 6300 4500 6300 5950
+Wire Wire Line
+ 4300 5950 6300 5950
+Wire Wire Line
+ 6300 4500 6150 4500
+Wire Wire Line
+ 6150 4600 6600 4600
+$EndSCHEMATC
diff --git a/Schematics/SKR mini LCD board/SKR mini LCD board-cache.lib b/Schematics/SKR mini LCD board/SKR mini LCD board-cache.lib
index 117cea7..f9c509f 100644
--- a/Schematics/SKR mini LCD board/SKR mini LCD board-cache.lib
+++ b/Schematics/SKR mini LCD board/SKR mini LCD board-cache.lib
@@ -1,205 +1,202 @@
-EESchema-LIBRARY Version 2.4
-#encoding utf-8
-#
-# Connector_Generic_Conn_02x05_Odd_Even
-#
-DEF Connector_Generic_Conn_02x05_Odd_Even J 0 40 Y N 1 F N
-F0 "J" 50 300 50 H V C CNN
-F1 "Connector_Generic_Conn_02x05_Odd_Even" 50 -300 50 H V C CNN
-F2 "" 0 0 50 H I C CNN
-F3 "" 0 0 50 H I C CNN
-$FPLIST
- Connector*:*_2x??_*
-$ENDFPLIST
-DRAW
-S -50 -195 0 -205 1 1 6 N
-S -50 -95 0 -105 1 1 6 N
-S -50 5 0 -5 1 1 6 N
-S -50 105 0 95 1 1 6 N
-S -50 205 0 195 1 1 6 N
-S -50 250 150 -250 1 1 10 f
-S 150 -195 100 -205 1 1 6 N
-S 150 -95 100 -105 1 1 6 N
-S 150 5 100 -5 1 1 6 N
-S 150 105 100 95 1 1 6 N
-S 150 205 100 195 1 1 6 N
-X Pin_1 1 -200 200 150 R 50 50 1 1 P
-X Pin_10 10 300 -200 150 L 50 50 1 1 P
-X Pin_2 2 300 200 150 L 50 50 1 1 P
-X Pin_3 3 -200 100 150 R 50 50 1 1 P
-X Pin_4 4 300 100 150 L 50 50 1 1 P
-X Pin_5 5 -200 0 150 R 50 50 1 1 P
-X Pin_6 6 300 0 150 L 50 50 1 1 P
-X Pin_7 7 -200 -100 150 R 50 50 1 1 P
-X Pin_8 8 300 -100 150 L 50 50 1 1 P
-X Pin_9 9 -200 -200 150 R 50 50 1 1 P
-ENDDRAW
-ENDDEF
-#
-# Device_Buzzer
-#
-DEF Device_Buzzer BZ 0 1 Y N 1 F N
-F0 "BZ" 150 50 50 H V L CNN
-F1 "Device_Buzzer" 150 -50 50 H V L CNN
-F2 "" -25 100 50 V I C CNN
-F3 "" -25 100 50 V I C CNN
-$FPLIST
- *Buzzer*
-$ENDFPLIST
-DRAW
-A 0 0 125 -899 899 0 1 0 N 0 -125 0 125
-P 2 0 1 0 -65 75 -45 75 N
-P 2 0 1 0 -55 85 -55 65 N
-P 2 0 1 0 0 125 0 -125 N
-X - 1 -100 100 100 R 50 50 1 1 P
-X + 2 -100 -100 100 R 50 50 1 1 P
-ENDDRAW
-ENDDEF
-#
-# Device_R
-#
-DEF Device_R R 0 0 N Y 1 F N
-F0 "R" 80 0 50 V V C CNN
-F1 "Device_R" 0 0 50 V V C CNN
-F2 "" -70 0 50 V I C CNN
-F3 "" 0 0 50 H I C CNN
-$FPLIST
- R_*
-$ENDFPLIST
-DRAW
-S -40 -100 40 100 0 1 10 N
-X ~ 1 0 150 50 D 50 50 1 1 P
-X ~ 2 0 -150 50 U 50 50 1 1 P
-ENDDRAW
-ENDDEF
-#
-# Device_Rotary_Encoder_Switch
-#
-DEF Device_Rotary_Encoder_Switch SW 0 10 Y N 1 F N
-F0 "SW" 0 260 50 H V C CNN
-F1 "Device_Rotary_Encoder_Switch" 0 -260 50 H V C CNN
-F2 "" -150 160 50 H I C CNN
-F3 "" 0 260 50 H I C CNN
-$FPLIST
- RotaryEncoder*Switch*
-$ENDFPLIST
-DRAW
-A -15 -2 108 -899 899 0 1 10 N -15 -110 -15 105
-C -150 0 10 0 1 0 F
-C -15 0 75 0 1 10 N
-C 170 -40 5 0 1 10 N
-C 170 40 5 0 1 10 N
-S -200 200 200 -200 0 1 10 f
-P 2 0 1 10 -25 -70 -25 70 N
-P 2 0 1 10 -15 -70 -15 70 N
-P 2 0 1 10 -5 70 -5 -70 N
-P 2 0 1 10 150 0 135 0 N
-P 2 0 1 10 150 40 150 -40 N
-P 3 0 1 0 -200 -100 -150 -100 -150 -80 N
-P 3 0 1 0 -200 100 -150 100 -150 80 N
-P 3 0 1 10 10 -120 -20 -110 5 -95 N
-P 3 0 1 10 10 115 -20 105 5 90 N
-P 3 0 1 10 200 -100 170 -100 170 -40 N
-P 3 0 1 10 200 100 170 100 170 40 N
-P 4 0 1 0 -200 0 -150 0 -150 -40 -130 -80 N
-P 4 0 1 0 -170 0 -150 0 -150 40 -130 80 N
-X A A -300 100 100 R 50 50 1 1 P
-X B B -300 -100 100 R 50 50 1 1 P
-X C C -300 0 100 R 50 50 1 1 P
-X S1 S1 300 100 100 L 50 50 1 1 P
-X S2 S2 300 -100 100 L 50 50 1 1 P
-ENDDRAW
-ENDDEF
-#
-# LED_WS2812B
-#
-DEF LED_WS2812B D 0 10 Y Y 1 F N
-F0 "D" 200 225 50 H V R BNN
-F1 "LED_WS2812B" 50 -225 50 H V L TNN
-F2 "LED_SMD:LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm" 50 -300 50 H I L TNN
-F3 "" 100 -375 50 H I L TNN
-$FPLIST
- LED*WS2812*PLCC*5.0x5.0mm*P3.2mm*
-$ENDFPLIST
-DRAW
-T 0 90 -165 30 0 0 0 RGB Normal 0 C C
-S 200 200 -200 -200 0 1 10 f
-P 2 0 1 0 50 -140 70 -140 N
-P 2 0 1 0 50 -100 70 -100 N
-P 2 0 1 0 185 -140 105 -140 N
-P 3 0 1 0 90 -100 50 -140 50 -120 N
-P 3 0 1 0 90 -60 50 -100 50 -80 N
-P 3 0 1 0 145 -40 145 -140 145 -160 N
-P 4 0 1 0 185 -60 105 -60 145 -140 185 -60 N
-X VDD 1 0 300 100 D 50 50 1 1 W
-X DOUT 2 300 0 100 L 50 50 1 1 O
-X VSS 3 0 -300 100 U 50 50 1 1 W
-X DIN 4 -300 0 100 R 50 50 1 1 I
-ENDDRAW
-ENDDEF
-#
-# SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32
-#
-DEF SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32 U 0 40 Y Y 1 F N
-F0 "U" -600 600 60 H V R TNN
-F1 "SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32" -1350 600 60 H V L TNN
-F2 "" 0 0 60 H I C CNN
-F3 "" 0 0 60 H I C CNN
-DRAW
-S -1400 650 -450 100 0 1 0 N
-X VCC 1 -1250 0 100 U 50 50 1 1 I
-X VSS 2 -1050 0 100 U 50 50 1 1 O
-X SCL 3 -850 0 100 U 50 50 1 1 I
-X SDA 4 -650 0 100 U 50 50 1 1 I
-ENDDRAW
-ENDDEF
-#
-# Switch_SW_DIP_x01
-#
-DEF Switch_SW_DIP_x01 SW 0 0 Y N 1 F N
-F0 "SW" 0 150 50 H V C CNN
-F1 "Switch_SW_DIP_x01" 0 -150 50 H V C CNN
-F2 "" 0 0 50 H I C CNN
-F3 "" 0 0 50 H I C CNN
-$FPLIST
- SW?DIP?x1*
-$ENDFPLIST
-DRAW
-C -80 0 20 0 0 0 N
-C 80 0 20 0 0 0 N
-S -150 100 150 -100 0 1 10 f
-P 2 0 0 0 -60 5 93 46 N
-X ~ 1 -300 0 200 R 50 50 1 1 P
-X ~ 2 300 0 200 L 50 50 1 1 P
-ENDDRAW
-ENDDEF
-#
-# power_+5V
-#
-DEF power_+5V #PWR 0 0 Y Y 1 F P
-F0 "#PWR" 0 -150 50 H I C CNN
-F1 "power_+5V" 0 140 50 H V C CNN
-F2 "" 0 0 50 H I C CNN
-F3 "" 0 0 50 H I C CNN
-DRAW
-P 2 0 1 0 -30 50 0 100 N
-P 2 0 1 0 0 0 0 100 N
-P 2 0 1 0 0 100 30 50 N
-X +5V 1 0 0 0 U 50 50 1 1 W N
-ENDDRAW
-ENDDEF
-#
-# power_GND
-#
-DEF power_GND #PWR 0 0 Y Y 1 F P
-F0 "#PWR" 0 -250 50 H I C CNN
-F1 "power_GND" 0 -150 50 H V C CNN
-F2 "" 0 0 50 H I C CNN
-F3 "" 0 0 50 H I C CNN
-DRAW
-P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
-X GND 1 0 0 0 D 50 50 1 1 W N
-ENDDRAW
-ENDDEF
-#
-#End Library
+EESchema-LIBRARY Version 2.4
+#encoding utf-8
+#
+# Connector_Generic_Conn_02x05_Odd_Even
+#
+DEF Connector_Generic_Conn_02x05_Odd_Even J 0 40 Y N 1 F N
+F0 "J" 50 300 50 H V C CNN
+F1 "Connector_Generic_Conn_02x05_Odd_Even" 50 -300 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ Connector*:*_2x??_*
+$ENDFPLIST
+DRAW
+S -50 -195 0 -205 1 1 6 N
+S -50 -95 0 -105 1 1 6 N
+S -50 5 0 -5 1 1 6 N
+S -50 105 0 95 1 1 6 N
+S -50 205 0 195 1 1 6 N
+S -50 250 150 -250 1 1 10 f
+S 150 -195 100 -205 1 1 6 N
+S 150 -95 100 -105 1 1 6 N
+S 150 5 100 -5 1 1 6 N
+S 150 105 100 95 1 1 6 N
+S 150 205 100 195 1 1 6 N
+X Pin_1 1 -200 200 150 R 50 50 1 1 P
+X Pin_10 10 300 -200 150 L 50 50 1 1 P
+X Pin_2 2 300 200 150 L 50 50 1 1 P
+X Pin_3 3 -200 100 150 R 50 50 1 1 P
+X Pin_4 4 300 100 150 L 50 50 1 1 P
+X Pin_5 5 -200 0 150 R 50 50 1 1 P
+X Pin_6 6 300 0 150 L 50 50 1 1 P
+X Pin_7 7 -200 -100 150 R 50 50 1 1 P
+X Pin_8 8 300 -100 150 L 50 50 1 1 P
+X Pin_9 9 -200 -200 150 R 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_Buzzer
+#
+DEF Device_Buzzer BZ 0 1 Y N 1 F N
+F0 "BZ" 150 50 50 H V L CNN
+F1 "Device_Buzzer" 150 -50 50 H V L CNN
+F2 "" -25 100 50 V I C CNN
+F3 "" -25 100 50 V I C CNN
+$FPLIST
+ *Buzzer*
+$ENDFPLIST
+DRAW
+A 0 0 125 -899 899 0 1 0 N 0 -125 0 125
+P 2 0 1 0 -65 75 -45 75 N
+P 2 0 1 0 -55 85 -55 65 N
+P 2 0 1 0 0 125 0 -125 N
+X - 1 -100 100 100 R 50 50 1 1 P
+X + 2 -100 -100 100 R 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_R
+#
+DEF Device_R R 0 0 N Y 1 F N
+F0 "R" 80 0 50 V V C CNN
+F1 "Device_R" 0 0 50 V V C CNN
+F2 "" -70 0 50 V I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ R_*
+$ENDFPLIST
+DRAW
+S -40 -100 40 100 0 1 10 N
+X ~ 1 0 150 50 D 50 50 1 1 P
+X ~ 2 0 -150 50 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Device_Rotary_Encoder_Switch
+#
+DEF Device_Rotary_Encoder_Switch SW 0 10 Y N 1 F N
+F0 "SW" 0 260 50 H V C CNN
+F1 "Device_Rotary_Encoder_Switch" 0 -260 50 H V C CNN
+F2 "" -150 160 50 H I C CNN
+F3 "" 0 260 50 H I C CNN
+$FPLIST
+ RotaryEncoder*Switch*
+$ENDFPLIST
+DRAW
+A -15 -2 108 -899 899 0 1 10 N -15 -110 -15 105
+C -150 0 10 0 1 0 F
+C -15 0 75 0 1 10 N
+C 170 -40 5 0 1 10 N
+C 170 40 5 0 1 10 N
+S -200 200 200 -200 0 1 10 f
+P 2 0 1 10 -25 -70 -25 70 N
+P 2 0 1 10 -15 -70 -15 70 N
+P 2 0 1 10 -5 70 -5 -70 N
+P 2 0 1 10 150 0 135 0 N
+P 2 0 1 10 150 40 150 -40 N
+P 3 0 1 0 -200 -100 -150 -100 -150 -80 N
+P 3 0 1 0 -200 100 -150 100 -150 80 N
+P 3 0 1 10 10 -120 -20 -110 5 -95 N
+P 3 0 1 10 10 115 -20 105 5 90 N
+P 3 0 1 10 200 -100 170 -100 170 -40 N
+P 3 0 1 10 200 100 170 100 170 40 N
+P 4 0 1 0 -200 0 -150 0 -150 -40 -130 -80 N
+P 4 0 1 0 -170 0 -150 0 -150 40 -130 80 N
+X A A -300 100 100 R 50 50 1 1 P
+X B B -300 -100 100 R 50 50 1 1 P
+X C C -300 0 100 R 50 50 1 1 P
+X S1 S1 300 100 100 L 50 50 1 1 P
+X S2 S2 300 -100 100 L 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32
+#
+DEF SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32 U 0 40 Y Y 1 F N
+F0 "U" -600 600 60 H V R TNN
+F1 "SKR-mini-LCD-board-rescue_SSD1306-SSD1306_OLED-0.91-128x32" -1350 600 60 H V L TNN
+F2 "" 0 0 60 H I C CNN
+F3 "" 0 0 60 H I C CNN
+DRAW
+S -1400 650 -450 100 0 1 0 N
+X VCC 1 -1250 0 100 U 50 50 1 1 I
+X VSS 2 -1050 0 100 U 50 50 1 1 O
+X SCL 3 -850 0 100 U 50 50 1 1 I
+X SDA 4 -650 0 100 U 50 50 1 1 I
+ENDDRAW
+ENDDEF
+#
+# Switch_SW_DIP_x01
+#
+DEF Switch_SW_DIP_x01 SW 0 0 Y N 1 F N
+F0 "SW" 0 150 50 H V C CNN
+F1 "Switch_SW_DIP_x01" 0 -150 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ SW?DIP?x1*
+$ENDFPLIST
+DRAW
+C -80 0 20 0 0 0 N
+C 80 0 20 0 0 0 N
+S -150 100 150 -100 0 1 10 f
+P 2 0 0 0 -60 5 93 46 N
+X ~ 1 -300 0 200 R 50 50 1 1 P
+X ~ 2 300 0 200 L 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# Transistor_BJT_BC547
+#
+DEF Transistor_BJT_BC547 Q 0 0 Y N 1 F N
+F0 "Q" 200 75 50 H V L CNN
+F1 "Transistor_BJT_BC547" 200 0 50 H V L CNN
+F2 "Package_TO_SOT_THT:TO-92_Inline" 200 -75 50 H I L CIN
+F3 "" 0 0 50 H I L CNN
+ALIAS BC546 BC548 BC549 BC550 BC337 BC338
+$FPLIST
+ TO?92*
+$ENDFPLIST
+DRAW
+C 50 0 111 0 1 10 N
+P 2 0 1 0 0 0 25 0 N
+P 2 0 1 0 25 25 100 100 N
+P 3 0 1 0 25 -25 100 -100 100 -100 N
+P 3 0 1 20 25 75 25 -75 25 -75 N
+P 5 0 1 0 50 -70 70 -50 90 -90 50 -70 50 -70 F
+X C 1 100 200 100 D 50 50 1 1 P
+X B 2 -200 0 200 R 50 50 1 1 I
+X E 3 100 -200 100 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# power_+5V
+#
+DEF power_+5V #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 -150 50 H I C CNN
+F1 "power_+5V" 0 140 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+DRAW
+P 2 0 1 0 -30 50 0 100 N
+P 2 0 1 0 0 0 0 100 N
+P 2 0 1 0 0 100 30 50 N
+X +5V 1 0 0 0 U 50 50 1 1 W N
+ENDDRAW
+ENDDEF
+#
+# power_GND
+#
+DEF power_GND #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 -250 50 H I C CNN
+F1 "power_GND" 0 -150 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+DRAW
+P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
+X GND 1 0 0 0 D 50 50 1 1 W N
+ENDDRAW
+ENDDEF
+#
+#End Library
diff --git a/Schematics/SKR mini LCD board/SKR mini LCD board.pdf b/Schematics/SKR mini LCD board/SKR mini LCD board.pdf
index facb943..2f34a44 100644
Binary files a/Schematics/SKR mini LCD board/SKR mini LCD board.pdf and b/Schematics/SKR mini LCD board/SKR mini LCD board.pdf differ
diff --git a/Schematics/SKR mini LCD board/SKR mini LCD board.pro b/Schematics/SKR mini LCD board/SKR mini LCD board.pro
index 0e2dfa4..d3259a0 100644
--- a/Schematics/SKR mini LCD board/SKR mini LCD board.pro
+++ b/Schematics/SKR mini LCD board/SKR mini LCD board.pro
@@ -1,43 +1,43 @@
-update=14.12.2019 09:44:36
-version=1
-last_client=kicad
-[general]
-version=1
-RootSch=
-BoardNm=
-[pcbnew]
-version=1
-LastNetListRead=
-UseCmpFile=1
-PadDrill=0.600000000000
-PadDrillOvalY=0.600000000000
-PadSizeH=1.500000000000
-PadSizeV=1.500000000000
-PcbTextSizeV=1.500000000000
-PcbTextSizeH=1.500000000000
-PcbTextThickness=0.300000000000
-ModuleTextSizeV=1.000000000000
-ModuleTextSizeH=1.000000000000
-ModuleTextSizeThickness=0.150000000000
-SolderMaskClearance=0.000000000000
-SolderMaskMinWidth=0.000000000000
-DrawSegmentWidth=0.200000000000
-BoardOutlineThickness=0.100000000000
-ModuleOutlineThickness=0.150000000000
-[cvpcb]
-version=1
-NetIExt=net
-[eeschema]
-version=1
-LibDir=
-[eeschema/libraries]
-[schematic_editor]
-version=1
-PageLayoutDescrFile=
-PlotDirectoryName=D:/Data/PlatformIO/SMuFF/Schematics/SKR mini LCD board/
-SubpartIdSeparator=0
-SubpartFirstId=65
-NetFmtName=
-SpiceAjustPassiveValues=0
-LabSize=50
-ERC_TestSimilarLabels=1
+update=15.08.2020 07:08:57
+version=1
+last_client=kicad
+[general]
+version=1
+RootSch=
+BoardNm=
+[pcbnew]
+version=1
+LastNetListRead=
+UseCmpFile=1
+PadDrill=0.600000000000
+PadDrillOvalY=0.600000000000
+PadSizeH=1.500000000000
+PadSizeV=1.500000000000
+PcbTextSizeV=1.500000000000
+PcbTextSizeH=1.500000000000
+PcbTextThickness=0.300000000000
+ModuleTextSizeV=1.000000000000
+ModuleTextSizeH=1.000000000000
+ModuleTextSizeThickness=0.150000000000
+SolderMaskClearance=0.000000000000
+SolderMaskMinWidth=0.000000000000
+DrawSegmentWidth=0.200000000000
+BoardOutlineThickness=0.100000000000
+ModuleOutlineThickness=0.150000000000
+[cvpcb]
+version=1
+NetIExt=net
+[eeschema]
+version=1
+LibDir=
+[eeschema/libraries]
+[schematic_editor]
+version=1
+PageLayoutDescrFile=
+PlotDirectoryName=D:/Data/PlatformIO/SMuFF/Schematics/SKR mini LCD board/
+SubpartIdSeparator=0
+SubpartFirstId=65
+NetFmtName=
+SpiceAjustPassiveValues=0
+LabSize=50
+ERC_TestSimilarLabels=1
diff --git a/Schematics/SKR mini LCD board/SKR mini LCD board.sch b/Schematics/SKR mini LCD board/SKR mini LCD board.sch
index f5e7efb..92530f8 100644
--- a/Schematics/SKR mini LCD board/SKR mini LCD board.sch
+++ b/Schematics/SKR mini LCD board/SKR mini LCD board.sch
@@ -1,333 +1,334 @@
-EESchema Schematic File Version 4
-LIBS:SKR mini LCD board-cache
-EELAYER 29 0
-EELAYER END
-$Descr A4 11693 8268
-encoding utf-8
-Sheet 1 1
-Title "SKR Mini V1.1 LCD board"
-Date "2019-09-23"
-Rev "1"
-Comp "Technik Gegg"
-Comment1 ""
-Comment2 ""
-Comment3 ""
-Comment4 ""
-$EndDescr
-$Comp
-L SKR-mini-LCD-board-rescue:SSD1306-SSD1306_OLED-0.91-128x32 U1
-U 1 1 5D888A8E
-P 3150 3550
-F 0 "U1" V 1563 3867 60 0000 C CNN
-F 1 "SSD1306 0.96\" OLED" V 1669 3867 60 0000 C CNN
-F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical" H 3150 3550 60 0001 C CNN
-F 3 "" H 3150 3550 60 0001 C CNN
- 1 3150 3550
- 0 -1 1 0
-$EndComp
-$Comp
-L Device:Rotary_Encoder_Switch ENC1
-U 1 1 5D88B3FF
-P 5000 5500
-F 0 "ENC1" H 5000 5867 50 0000 C CNN
-F 1 "Rotary Encoder" H 5000 5776 50 0000 C CNN
-F 2 "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_CircularMountingHoles" H 4850 5660 50 0001 C CNN
-F 3 "~" H 5000 5760 50 0001 C CNN
- 1 5000 5500
- 1 0 0 -1
-$EndComp
-$Comp
-L Connector_Generic:Conn_02x05_Odd_Even J1
-U 1 1 5D88D2F1
-P 5850 4400
-F 0 "J1" H 5900 4817 50 0000 C CNN
-F 1 "Connector 5x2" H 5900 4726 50 0000 C CNN
-F 2 "Connector_PinSocket_2.54mm:PinSocket_2x05_P2.54mm_Vertical" H 5850 4400 50 0001 C CNN
-F 3 "~" H 5850 4400 50 0001 C CNN
- 1 5850 4400
- 1 0 0 -1
-$EndComp
-$Comp
-L Device:R R1
-U 1 1 5D8937B1
-P 3850 5400
-F 0 "R1" V 4057 5400 50 0000 C CNN
-F 1 "10K" V 3966 5400 50 0000 C CNN
-F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5400 50 0001 C CNN
-F 3 "~" H 3850 5400 50 0001 C CNN
- 1 3850 5400
- 0 -1 -1 0
-$EndComp
-$Comp
-L Device:Buzzer BZ1
-U 1 1 5D893D6F
-P 6300 4950
-F 0 "BZ1" H 6200 4750 50 0000 L CNN
-F 1 "Buzzer" H 6200 4650 50 0000 L CNN
-F 2 "Buzzer_Beeper:Buzzer_12x9.5RM7.6" V 6275 5050 50 0001 C CNN
-F 3 "~" V 6275 5050 50 0001 C CNN
- 1 6300 4950
- 1 0 0 -1
-$EndComp
-$Comp
-L Switch:SW_DIP_x01 SW1
-U 1 1 5D894E2A
-P 5050 1600
-F 0 "SW1" H 5050 1867 50 0000 C CNN
-F 1 "Reset" H 5050 1776 50 0000 C CNN
-F 2 "Button_Switch_THT:SW_PUSH_6mm_H7.3mm" H 5050 1600 50 0001 C CNN
-F 3 "~" H 5050 1600 50 0001 C CNN
- 1 5050 1600
- 1 0 0 -1
-$EndComp
-$Comp
-L power:+5V #PWR0101
-U 1 1 5D89576B
-P 3400 5400
-F 0 "#PWR0101" H 3400 5250 50 0001 C CNN
-F 1 "+5V" V 3415 5528 50 0000 L CNN
-F 2 "" H 3400 5400 50 0001 C CNN
-F 3 "" H 3400 5400 50 0001 C CNN
- 1 3400 5400
- 0 -1 -1 0
-$EndComp
-$Comp
-L power:+5V #PWR0102
-U 1 1 5D896CC4
-P 5450 3800
-F 0 "#PWR0102" H 5450 3650 50 0001 C CNN
-F 1 "+5V" H 5465 3973 50 0000 C CNN
-F 2 "" H 5450 3800 50 0001 C CNN
-F 3 "" H 5450 3800 50 0001 C CNN
- 1 5450 3800
- 1 0 0 -1
-$EndComp
-$Comp
-L power:+5V #PWR0103
-U 1 1 5D89755D
-P 3500 2100
-F 0 "#PWR0103" H 3500 1950 50 0001 C CNN
-F 1 "+5V" H 3515 2273 50 0000 C CNN
-F 2 "" H 3500 2100 50 0001 C CNN
-F 3 "" H 3500 2100 50 0001 C CNN
- 1 3500 2100
- 1 0 0 -1
-$EndComp
-$Comp
-L power:GND #PWR0104
-U 1 1 5D897F1D
-P 4600 1850
-F 0 "#PWR0104" H 4600 1600 50 0001 C CNN
-F 1 "GND" H 4605 1677 50 0000 C CNN
-F 2 "" H 4600 1850 50 0001 C CNN
-F 3 "" H 4600 1850 50 0001 C CNN
- 1 4600 1850
- 1 0 0 -1
-$EndComp
-$Comp
-L power:GND #PWR0105
-U 1 1 5D898A40
-P 3550 2500
-F 0 "#PWR0105" H 3550 2250 50 0001 C CNN
-F 1 "GND" H 3555 2327 50 0000 C CNN
-F 2 "" H 3550 2500 50 0001 C CNN
-F 3 "" H 3550 2500 50 0001 C CNN
- 1 3550 2500
- 1 0 0 -1
-$EndComp
-$Comp
-L power:GND #PWR0106
-U 1 1 5D899BAF
-P 5650 5700
-F 0 "#PWR0106" H 5650 5450 50 0001 C CNN
-F 1 "GND" H 5655 5527 50 0000 C CNN
-F 2 "" H 5650 5700 50 0001 C CNN
-F 3 "" H 5650 5700 50 0001 C CNN
- 1 5650 5700
- 1 0 0 -1
-$EndComp
-$Comp
-L power:GND #PWR0107
-U 1 1 5D89A417
-P 5950 5150
-F 0 "#PWR0107" H 5950 4900 50 0001 C CNN
-F 1 "GND" H 5955 4977 50 0000 C CNN
-F 2 "" H 5950 5150 50 0001 C CNN
-F 3 "" H 5950 5150 50 0001 C CNN
- 1 5950 5150
- 1 0 0 -1
-$EndComp
-Wire Wire Line
- 5650 4200 5450 4200
-Wire Wire Line
- 5450 4200 5450 3800
-Wire Wire Line
- 3150 2300 3500 2300
-Wire Wire Line
- 3500 2300 3500 2100
-Wire Wire Line
- 3150 2500 3550 2500
-Wire Wire Line
- 4750 1600 4600 1600
-Wire Wire Line
- 4600 1600 4600 1850
-Wire Wire Line
- 6200 5050 5950 5050
-Wire Wire Line
- 5950 5050 5950 5150
-$Comp
-L power:GND #PWR0108
-U 1 1 5D89B98C
-P 6250 3800
-F 0 "#PWR0108" H 6250 3550 50 0001 C CNN
-F 1 "GND" H 6255 3627 50 0000 C CNN
-F 2 "" H 6250 3800 50 0001 C CNN
-F 3 "" H 6250 3800 50 0001 C CNN
- 1 6250 3800
- -1 0 0 1
-$EndComp
-Wire Wire Line
- 6150 4200 6250 4200
-Wire Wire Line
- 4700 5500 4400 5500
-Wire Wire Line
- 4700 5400 4300 5400
-Wire Wire Line
- 5300 5600 5650 5600
-Wire Wire Line
- 5650 5600 5650 5700
-Wire Wire Line
- 5650 4600 5600 4600
-Wire Wire Line
- 5600 4600 5600 5400
-Wire Wire Line
- 5600 5400 5300 5400
-Wire Wire Line
- 5650 4300 4300 4300
-Wire Wire Line
- 4300 4300 4300 5400
-Connection ~ 4300 5400
-Wire Wire Line
- 4300 5400 4000 5400
-Wire Wire Line
- 6150 4300 6500 4300
-Wire Wire Line
- 5650 4400 4500 4400
-Wire Wire Line
- 6400 4500 6150 4500
-$Comp
-L Device:R R2
-U 1 1 5D892B67
-P 3850 5950
-F 0 "R2" V 4057 5950 50 0000 C CNN
-F 1 "10K" V 3966 5950 50 0000 C CNN
-F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5950 50 0001 C CNN
-F 3 "~" H 3850 5950 50 0001 C CNN
- 1 3850 5950
- 0 -1 -1 0
-$EndComp
-Wire Wire Line
- 6500 4300 6500 5950
-Wire Wire Line
- 4000 5950 4300 5950
-Wire Wire Line
- 4300 5600 4300 5950
-Wire Wire Line
- 6150 4850 6200 4850
-Wire Wire Line
- 6150 4600 6150 4850
-$Comp
-L power:GND #PWR0109
-U 1 1 5D8A9A64
-P 4400 5500
-F 0 "#PWR0109" H 4400 5250 50 0001 C CNN
-F 1 "GND" V 4405 5372 50 0000 R CNN
-F 2 "" H 4400 5500 50 0001 C CNN
-F 3 "" H 4400 5500 50 0001 C CNN
- 1 4400 5500
- 0 1 1 0
-$EndComp
-$Comp
-L Connector_Generic:Conn_02x05_Odd_Even #EXT2
-U 1 1 5D8AB540
-P 6250 1700
-F 0 "#EXT2" H 6300 2117 50 0000 C CNN
-F 1 "Connector on Controller" H 6300 2026 50 0000 C CNN
-F 2 "" H 6250 1700 50 0001 C CNN
-F 3 "~" H 6250 1700 50 0001 C CNN
- 1 6250 1700
- 1 0 0 -1
-$EndComp
-Wire Wire Line
- 5350 1600 6050 1600
-Text Notes 5250 2200 0 50 ~ 0
-Optional\n
-Wire Notes Line width 20
- 6950 2350 6950 1000
-Wire Notes Line width 20
- 6950 1000 4450 1000
-Wire Notes Line width 20
- 4450 1000 4450 2350
-Wire Notes Line width 20
- 6950 2350 4450 2350
-Wire Wire Line
- 6400 2700 6400 4500
-Wire Wire Line
- 3150 2700 6400 2700
-Wire Wire Line
- 4500 4400 4500 2900
-Wire Wire Line
- 4500 2900 3150 2900
-Wire Wire Line
- 3550 5400 3700 5400
-Wire Wire Line
- 3550 5950 3700 5950
-Wire Wire Line
- 4300 5600 4700 5600
-Connection ~ 4300 5950
-Wire Wire Line
- 4300 5950 6500 5950
-Wire Wire Line
- 6250 3800 6250 4200
-$Comp
-L LED:WS2812B D1
-U 1 1 5D8C3DC4
-P 3550 4500
-F 0 "D1" H 3206 4454 50 0000 R CNN
-F 1 "WS2812B" H 3206 4545 50 0000 R CNN
-F 2 "LED_SMD:LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm" H 3600 4200 50 0001 L TNN
-F 3 "https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf" H 3650 4125 50 0001 L TNN
- 1 3550 4500
- -1 0 0 1
-$EndComp
-Wire Wire Line
- 3850 4500 5650 4500
-$Comp
-L power:GND #PWR0110
-U 1 1 5D8C682F
-P 3550 4200
-F 0 "#PWR0110" H 3550 3950 50 0001 C CNN
-F 1 "GND" H 3555 4027 50 0000 C CNN
-F 2 "" H 3550 4200 50 0001 C CNN
-F 3 "" H 3550 4200 50 0001 C CNN
- 1 3550 4200
- -1 0 0 1
-$EndComp
-Wire Wire Line
- 3400 5400 3550 5400
-Connection ~ 3550 5400
-Wire Wire Line
- 3550 4800 3550 5400
-Wire Wire Line
- 3550 5400 3550 5950
-Wire Notes Line width 12
- 2950 3850 4250 3850
-Wire Notes Line width 12
- 4250 3850 4250 5000
-Wire Notes Line width 12
- 4250 5000 2950 5000
-Wire Notes Line width 12
- 2950 5000 2950 3850
-Text Notes 3050 4950 0 50 ~ 0
-Optional
-$EndSCHEMATC
+EESchema Schematic File Version 4
+LIBS:SKR mini LCD board-cache
+EELAYER 29 0
+EELAYER END
+$Descr A4 11693 8268
+encoding utf-8
+Sheet 1 1
+Title "SKR Mini V1.1 LCD board"
+Date "2020-08-15"
+Rev "2"
+Comp "Technik Gegg"
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+$Comp
+L SKR-mini-LCD-board-rescue:SSD1306-SSD1306_OLED-0.91-128x32 U1
+U 1 1 5D888A8E
+P 3150 3550
+F 0 "U1" V 1563 3867 60 0000 C CNN
+F 1 "SSD1306 0.96\" OLED" V 1669 3867 60 0000 C CNN
+F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical" H 3150 3550 60 0001 C CNN
+F 3 "" H 3150 3550 60 0001 C CNN
+ 1 3150 3550
+ 0 -1 1 0
+$EndComp
+$Comp
+L Device:Rotary_Encoder_Switch ENC1
+U 1 1 5D88B3FF
+P 5000 5500
+F 0 "ENC1" H 5000 5867 50 0000 C CNN
+F 1 "Rotary Encoder" H 5000 5776 50 0000 C CNN
+F 2 "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_CircularMountingHoles" H 4850 5660 50 0001 C CNN
+F 3 "~" H 5000 5760 50 0001 C CNN
+ 1 5000 5500
+ 1 0 0 -1
+$EndComp
+$Comp
+L Connector_Generic:Conn_02x05_Odd_Even J1
+U 1 1 5D88D2F1
+P 5850 4400
+F 0 "J1" H 5900 4817 50 0000 C CNN
+F 1 "Connector 5x2" H 5900 4726 50 0000 C CNN
+F 2 "Connector_PinSocket_2.54mm:PinSocket_2x05_P2.54mm_Vertical" H 5850 4400 50 0001 C CNN
+F 3 "~" H 5850 4400 50 0001 C CNN
+ 1 5850 4400
+ 1 0 0 -1
+$EndComp
+$Comp
+L Device:R R1
+U 1 1 5D8937B1
+P 3850 5400
+F 0 "R1" V 4057 5400 50 0000 C CNN
+F 1 "10K" V 3966 5400 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5400 50 0001 C CNN
+F 3 "~" H 3850 5400 50 0001 C CNN
+ 1 3850 5400
+ 0 -1 -1 0
+$EndComp
+$Comp
+L Device:Buzzer BZ1
+U 1 1 5D893D6F
+P 7200 4550
+F 0 "BZ1" H 7400 4600 50 0000 L CNN
+F 1 "Buzzer" H 7400 4500 50 0000 L CNN
+F 2 "Buzzer_Beeper:Buzzer_12x9.5RM7.6" V 7175 4650 50 0001 C CNN
+F 3 "~" V 7175 4650 50 0001 C CNN
+ 1 7200 4550
+ 1 0 0 -1
+$EndComp
+$Comp
+L Switch:SW_DIP_x01 SW1
+U 1 1 5D894E2A
+P 5050 1600
+F 0 "SW1" H 5050 1867 50 0000 C CNN
+F 1 "Reset" H 5050 1776 50 0000 C CNN
+F 2 "Button_Switch_THT:SW_PUSH_6mm_H7.3mm" H 5050 1600 50 0001 C CNN
+F 3 "~" H 5050 1600 50 0001 C CNN
+ 1 5050 1600
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:+5V #PWR0101
+U 1 1 5D89576B
+P 3400 5400
+F 0 "#PWR0101" H 3400 5250 50 0001 C CNN
+F 1 "+5V" V 3415 5528 50 0000 L CNN
+F 2 "" H 3400 5400 50 0001 C CNN
+F 3 "" H 3400 5400 50 0001 C CNN
+ 1 3400 5400
+ 0 -1 -1 0
+$EndComp
+$Comp
+L power:+5V #PWR0102
+U 1 1 5D896CC4
+P 5450 3800
+F 0 "#PWR0102" H 5450 3650 50 0001 C CNN
+F 1 "+5V" H 5465 3973 50 0000 C CNN
+F 2 "" H 5450 3800 50 0001 C CNN
+F 3 "" H 5450 3800 50 0001 C CNN
+ 1 5450 3800
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:+5V #PWR0103
+U 1 1 5D89755D
+P 3500 2100
+F 0 "#PWR0103" H 3500 1950 50 0001 C CNN
+F 1 "+5V" H 3515 2273 50 0000 C CNN
+F 2 "" H 3500 2100 50 0001 C CNN
+F 3 "" H 3500 2100 50 0001 C CNN
+ 1 3500 2100
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0104
+U 1 1 5D897F1D
+P 4600 1850
+F 0 "#PWR0104" H 4600 1600 50 0001 C CNN
+F 1 "GND" H 4605 1677 50 0000 C CNN
+F 2 "" H 4600 1850 50 0001 C CNN
+F 3 "" H 4600 1850 50 0001 C CNN
+ 1 4600 1850
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0105
+U 1 1 5D898A40
+P 3550 2500
+F 0 "#PWR0105" H 3550 2250 50 0001 C CNN
+F 1 "GND" H 3555 2327 50 0000 C CNN
+F 2 "" H 3550 2500 50 0001 C CNN
+F 3 "" H 3550 2500 50 0001 C CNN
+ 1 3550 2500
+ 0 -1 -1 0
+$EndComp
+$Comp
+L power:GND #PWR0106
+U 1 1 5D899BAF
+P 5650 5700
+F 0 "#PWR0106" H 5650 5450 50 0001 C CNN
+F 1 "GND" H 5655 5527 50 0000 C CNN
+F 2 "" H 5650 5700 50 0001 C CNN
+F 3 "" H 5650 5700 50 0001 C CNN
+ 1 5650 5700
+ 1 0 0 -1
+$EndComp
+$Comp
+L power:GND #PWR0107
+U 1 1 5D89A417
+P 7100 5350
+F 0 "#PWR0107" H 7100 5100 50 0001 C CNN
+F 1 "GND" H 7105 5177 50 0000 C CNN
+F 2 "" H 7100 5350 50 0001 C CNN
+F 3 "" H 7100 5350 50 0001 C CNN
+ 1 7100 5350
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 5650 4200 5450 4200
+Wire Wire Line
+ 5450 4200 5450 3800
+Wire Wire Line
+ 3150 2300 3500 2300
+Wire Wire Line
+ 3500 2300 3500 2100
+Wire Wire Line
+ 3150 2500 3550 2500
+Wire Wire Line
+ 4750 1600 4600 1600
+Wire Wire Line
+ 4600 1600 4600 1850
+Wire Wire Line
+ 7100 5250 7100 5350
+$Comp
+L power:GND #PWR0108
+U 1 1 5D89B98C
+P 6250 3800
+F 0 "#PWR0108" H 6250 3550 50 0001 C CNN
+F 1 "GND" H 6255 3627 50 0000 C CNN
+F 2 "" H 6250 3800 50 0001 C CNN
+F 3 "" H 6250 3800 50 0001 C CNN
+ 1 6250 3800
+ -1 0 0 1
+$EndComp
+Wire Wire Line
+ 6150 4200 6250 4200
+Wire Wire Line
+ 4700 5500 4400 5500
+Wire Wire Line
+ 4700 5400 4300 5400
+Wire Wire Line
+ 5300 5600 5650 5600
+Wire Wire Line
+ 5650 5600 5650 5700
+Wire Wire Line
+ 5650 4600 5600 4600
+Wire Wire Line
+ 5600 4600 5600 5400
+Wire Wire Line
+ 5600 5400 5300 5400
+Wire Wire Line
+ 5650 4300 4300 4300
+Wire Wire Line
+ 4300 4300 4300 5400
+Connection ~ 4300 5400
+Wire Wire Line
+ 4300 5400 4000 5400
+Wire Wire Line
+ 5650 4400 4500 4400
+Wire Wire Line
+ 6400 4500 6150 4500
+$Comp
+L Device:R R2
+U 1 1 5D892B67
+P 3850 5950
+F 0 "R2" V 4057 5950 50 0000 C CNN
+F 1 "10K" V 3966 5950 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 3780 5950 50 0001 C CNN
+F 3 "~" H 3850 5950 50 0001 C CNN
+ 1 3850 5950
+ 0 -1 -1 0
+$EndComp
+Wire Wire Line
+ 4000 5950 4300 5950
+Wire Wire Line
+ 4300 5600 4300 5950
+$Comp
+L power:GND #PWR0109
+U 1 1 5D8A9A64
+P 4400 5500
+F 0 "#PWR0109" H 4400 5250 50 0001 C CNN
+F 1 "GND" V 4405 5372 50 0000 R CNN
+F 2 "" H 4400 5500 50 0001 C CNN
+F 3 "" H 4400 5500 50 0001 C CNN
+ 1 4400 5500
+ 0 1 1 0
+$EndComp
+$Comp
+L Connector_Generic:Conn_02x05_Odd_Even #EXT2
+U 1 1 5D8AB540
+P 6250 1700
+F 0 "#EXT2" H 6300 2117 50 0000 C CNN
+F 1 "Connector on Controller" H 6300 2026 50 0000 C CNN
+F 2 "" H 6250 1700 50 0001 C CNN
+F 3 "~" H 6250 1700 50 0001 C CNN
+ 1 6250 1700
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 5350 1600 6050 1600
+Text Notes 5250 2200 0 50 ~ 0
+Optional\n
+Wire Notes Line width 20
+ 6950 2350 6950 1000
+Wire Notes Line width 20
+ 6950 1000 4450 1000
+Wire Notes Line width 20
+ 4450 1000 4450 2350
+Wire Notes Line width 20
+ 6950 2350 4450 2350
+Wire Wire Line
+ 6400 2700 6400 4500
+Wire Wire Line
+ 3150 2700 6400 2700
+Wire Wire Line
+ 4500 4400 4500 2900
+Wire Wire Line
+ 4500 2900 3150 2900
+Wire Wire Line
+ 3550 5400 3700 5400
+Wire Wire Line
+ 3550 5950 3700 5950
+Wire Wire Line
+ 4300 5600 4700 5600
+Connection ~ 4300 5950
+Wire Wire Line
+ 4300 5950 6250 5950
+Wire Wire Line
+ 6250 3800 6250 4200
+Wire Wire Line
+ 3400 5400 3550 5400
+Connection ~ 3550 5400
+Wire Wire Line
+ 3550 5400 3550 5950
+$Comp
+L power:+5V #PWR?
+U 1 1 5F377DF5
+P 7100 4300
+F 0 "#PWR?" H 7100 4150 50 0001 C CNN
+F 1 "+5V" H 7115 4473 50 0000 C CNN
+F 2 "" H 7100 4300 50 0001 C CNN
+F 3 "" H 7100 4300 50 0001 C CNN
+ 1 7100 4300
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 7100 4300 7100 4450
+$Comp
+L Device:R R3
+U 1 1 5F3793FA
+P 6550 5050
+F 0 "R3" V 6550 5050 50 0000 C CNN
+F 1 "1K" V 6450 5050 50 0000 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal" V 6480 5050 50 0001 C CNN
+F 3 "~" H 6550 5050 50 0001 C CNN
+ 1 6550 5050
+ 0 -1 -1 0
+$EndComp
+$Comp
+L Transistor_BJT:BC547 Q1
+U 1 1 5F37DDBD
+P 7000 5050
+F 0 "Q1" H 7191 5096 50 0000 L CNN
+F 1 "BC547" H 7191 5005 50 0000 L CNN
+F 2 "Package_TO_SOT_THT:TO-92_Inline" H 7200 4975 50 0001 L CIN
+F 3 "http://www.fairchildsemi.com/ds/BC/BC547.pdf" H 7000 5050 50 0001 L CNN
+ 1 7000 5050
+ 1 0 0 -1
+$EndComp
+Wire Wire Line
+ 7100 4650 7100 4850
+Wire Wire Line
+ 6700 5050 6800 5050
+Wire Wire Line
+ 6150 4300 6250 4300
+Wire Wire Line
+ 6250 4300 6250 5950
+Wire Wire Line
+ 6150 4600 6400 4600
+Wire Wire Line
+ 6400 4600 6400 5050
+$EndSCHEMATC
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..c64c4ca
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,3 @@
+# Folder for documentation
+
+tbd.
\ No newline at end of file
diff --git a/include/ClickEncoder.h b/include/ClickEncoder.h
index a4c50e0..b55b147 100644
--- a/include/ClickEncoder.h
+++ b/include/ClickEncoder.h
@@ -68,6 +68,7 @@ private:
volatile uint16_t acceleration = 0;
bool accelerationEnabled;
uint8_t steps = 0;
+ bool enableSound;
#ifndef WITHOUT_BUTTON
volatile Button button;
@@ -107,6 +108,16 @@ public:
#endif
public:
+ void setEnableSound(const bool &d)
+ {
+ enableSound = d;
+ }
+
+ const bool getEnableSound()
+ {
+ return enableSound;
+ }
+
void setAccelerationEnabled(const bool &a)
{
accelerationEnabled = a;
diff --git a/include/Config.h b/include/Config.h
index 50816cf..775a036 100644
--- a/include/Config.h
+++ b/include/Config.h
@@ -21,12 +21,13 @@
#ifndef _SMUFF_CONFIG_H
#define _SMUFF_CONFIG_H
-#define VERSION_STRING "V2.09"
+#define VERSION_STRING "V2.10"
#define PMMU_VERSION 106 // Version number for Prusa MMU2 Emulation mode
#define PMMU_BUILD 372 // Build number for Prusa MMU2 Emulation mode
-#define VERSION_DATE "2020-07-06"
+#define VERSION_DATE "2020-08-24"
#define CONFIG_FILE "SMUFF.CFG"
#define DATASTORE_FILE "EEPROM.DAT"
+#define TUNE_FILE "TUNE.DAT"
#if defined(__STM32F1__)
#define MAX_JSON 2048 // 2K of temporary buffer for the JSON data
#elif defined(__ESP32__)
@@ -51,6 +52,10 @@
#define MAX_CONTRAST 250
#define I2C_SLAVE_ADDRESS 0x88
+#define I2C_DISPLAY_ADDRESS 0x3c
+
+#define SERVO_WIPER 0
+#define SERVO_LID 1
#include "Pins.h" // path is defined in build environment of platformio.ini (-I)
@@ -69,12 +74,21 @@
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#endif
+#define LED_BLACK_COLOR 0
+#define LED_RED_COLOR 1
+#define LED_GREEN_COLOR 2
+#define LED_BLUE_COLOR 3
+#define LED_CYAN_COLOR 4
+#define LED_MAGENTA_COLOR 5
+#define LED_YELLOW_COLOR 6
+#define LED_WHITE_COLOR 7
-#define BASE_FONT u8g2_font_6x12_t_symbols
-#define BASE_FONT_BIG u8g2_font_7x14B_tf
-#define SMALL_FONT u8g2_font_6x10_mr
-#define STATUS_FONT u8g2_font_7x14_tf
-#define LOGO_FONT u8g2_font_helvR08_tf
-#define ICONIC_FONT u8g2_font_open_iconic_check_2x_t
+#define BASE_FONT u8g2_font_6x12_t_symbols
+#define BASE_FONT_BIG u8g2_font_7x14B_tf
+#define SMALL_FONT u8g2_font_6x10_mr
+#define STATUS_FONT u8g2_font_7x14_tf
+#define LOGO_FONT u8g2_font_helvR08_tf
+#define ICONIC_FONT u8g2_font_open_iconic_check_2x_t
+#define SYMBOL_FONT u8g2_font_unifont_t_symbols
#endif
\ No newline at end of file
diff --git a/include/DuetLaserSensor.h b/include/DuetLaserSensor.h
index 36a838d..b6b6949 100644
--- a/include/DuetLaserSensor.h
+++ b/include/DuetLaserSensor.h
@@ -23,41 +23,76 @@
#ifndef _DUETLASER_H
#define _DUETLASER_H 1
+
+#define STATE_INIT 0x8000
+#define STATE_IDLE 0x8001
+#define STATE_WAIT_START 0x8002
+#define STATE_GOT_START 0x8003
+#define STATE_READING_DATA 0x8004
+#define STATE_GOT_ALL_BITS 0x8005
+#define STATE_PARITY_ERROR 0x8006
+#define STATE_PARITY_OK 0x8007
+#define STATE_GOT_POSITION 0x8008
+#define STATE_GOT_ERROR_MSG 0x8009
+#define STATE_GOT_QUALITY_V1 0x800A
+#define STATE_GOT_QUALITY_V2 0x800B
+#define STATE_INVALID 0x800C
+
+#define E_NONE 0x0
+#define E_WRONG_PARITY 0x8000
+#define E_INVALID_QUALITY 0x8001
+#define E_INVALID_DATA 0x8002
+#define E_INVALID_VERSION 0x8003
+
+#define E_SENSOR_VCC 4 // Sensor has reported an VCC error
+#define E_SENSOR_INIT 5 // Sensor has reported an init error
+
+#define DIR_EXTRUDE 1
+#define DIR_NONE 0
+#define DIR_RETRACT -1
+
class DuetLaserSensor {
public:
DuetLaserSensor() { _pin = -1; };
- DuetLaserSensor(int pin) { attach(pin); }
+ DuetLaserSensor(int pin, bool v1 = false) { attach(pin, v1); }
- void attach(int pin);
+ void attach(int pin, bool v1 = false);
void reset();
+ void resetPosition();
void service();
- unsigned getSwitch() { return _switch; }
+ bool getSwitch() { return _switch; }
+ int8_t getDirection() { return _dir; }
double getPositionMM() { return _positionMM; }
- unsigned getPosition() { return _position; }
- unsigned getBrightness() { return _brightness; }
- unsigned getVersion() { return _version; }
- unsigned getQuality() { return _quality; }
- unsigned getShutter() { return _shutter; }
- unsigned getError() { return _error; }
+ int32_t getPosition() { return _position; }
+ uint8_t getBrightness() { return _brightness; }
+ uint8_t getVersion() { return _version; }
+ uint8_t getQuality() { return _quality; }
+ uint8_t getShutter() { return _shutter; }
+ uint16_t getError() { return _error; }
+ uint8_t getSensorError() { return _sensorError; }
unsigned getState() { return _state; }
bool isValid() { return _isValid; }
- String getBits() { return _lastBits; }
- String getStuffBits() { return _lastStuff; }
- void resetBits() { _lastBits = ""; _lastStuff = ""; }
+ bool isMoving() { return _hasMoved; }
+ String getBits() { return _bits; }
+ String getStuffBits() { return _stuff; }
+ void resetBits() { _bits = ""; _stuff = ""; }
private:
int _pin = -1;
bool _switch;
bool _isV1;
+ bool _hasMoved;
+ int8_t _dir;
double _positionMM;
- unsigned _position;
- unsigned _version;
- unsigned _brightness;
- unsigned _quality;
- unsigned _shutter;
- unsigned _error;
- int _lastBit;
+ int32_t _position;
+ int32_t _prevpos;
+ uint8_t _version;
+ uint8_t _brightness;
+ uint8_t _quality;
+ uint8_t _shutter;
+ uint16_t _error;
+ uint8_t _sensorError;
unsigned _state;
unsigned _data;
@@ -65,12 +100,10 @@ private:
bool _gotStartbit;
bool _isValid;
int _bitCnt;
+ uint8_t _pbitCnt;
int _dataCnt;
String _bits;
String _stuff;
- String _lastBits;
- String _lastStuff;
-
};
#endif
\ No newline at end of file
diff --git a/include/ESP32/Pins.h b/include/ESP32/Pins.h
index 4f032bb..b070685 100644
--- a/include/ESP32/Pins.h
+++ b/include/ESP32/Pins.h
@@ -48,6 +48,9 @@
#define LED_PIN 2 // IO2
+#define DEBUG_PIN -1
+#define RELAIS_PIN -1 // Relais for stepper motor switching
+
#define BEEPER_CHANNEL 1
#define BEEPER_PIN 2 // IO2
@@ -77,6 +80,9 @@
#endif
#define ENCODER_BUTTON_PIN 32 // IO39 (aka SenseVN)
+#define CAN_USE_SERIAL1 true
+#define CAN_USE_SERIAL2 true
+#define CAN_USE_SERIAL3 false
#define TX1_PIN 17 // Serial 1
#define RX1_PIN 16
diff --git a/include/FYSETC_AIOII/Pins.h b/include/FYSETC_AIOII/Pins.h
index afc0fe7..c407bef 100644
--- a/include/FYSETC_AIOII/Pins.h
+++ b/include/FYSETC_AIOII/Pins.h
@@ -56,11 +56,13 @@
#define HEATBED_PIN PC6 // END
#define NEOPIXEL_PIN -1
+#define DEBUG_PIN -1
+#define RELAIS_PIN -1 // Relais for stepper motor switching
#define SDCS_PIN PA4
-#define DSP_CS_PIN PB5
-#define DSP_DC_PIN PA15
-#define DSP_RESET_PIN PB4
+#define DSP_CS_PIN PB5 // DOGLCD-CS
+#define DSP_DC_PIN PA15 // DOGLCD-A0
+#define DSP_RESET_PIN PB4 // DOGLCD-RST
#define ENCODER1_PIN PC10
#define ENCODER2_PIN PC11
@@ -68,6 +70,10 @@
#define DEBUG_OFF_PIN -1
+#define CAN_USE_SERIAL1 true
+#define CAN_USE_SERIAL2 false
+#define CAN_USE_SERIAL3 true
+
#define TX3_PIN PB10 // P4-7
#define RX3_PIN PB11 // P4-5
diff --git a/include/GCodes.h b/include/GCodes.h
index 06559a6..6288662 100644
--- a/include/GCodes.h
+++ b/include/GCodes.h
@@ -31,6 +31,7 @@ typedef struct {
extern unsigned int currentLine;
extern bool dummy(const char* msg, String buf, int serial);
+extern bool M17(const char* msg, String buf, int serial);
extern bool M18(const char* msg, String buf, int serial);
extern bool M20(const char* msg, String buf, int serial);
extern bool M42(const char* msg, String buf, int serial);
@@ -43,6 +44,7 @@ extern bool M114(const char* msg, String buf, int serial);
extern bool M115(const char* msg, String buf, int serial);
extern bool M117(const char* msg, String buf, int serial);
extern bool M119(const char* msg, String buf, int serial);
+extern bool M122(const char* msg, String buf, int serial);
extern bool M150(const char* msg, String buf, int serial);
extern bool M201(const char* msg, String buf, int serial);
extern bool M203(const char* msg, String buf, int serial);
@@ -51,11 +53,16 @@ extern bool M206(const char* msg, String buf, int serial);
extern bool M250(const char* msg, String buf, int serial);
extern bool M280(const char* msg, String buf, int serial);
extern bool M300(const char* msg, String buf, int serial);
+extern bool M350(const char* msg, String buf, int serial);
+extern bool M412(const char* msg, String buf, int serial);
extern bool M500(const char* msg, String buf, int serial);
extern bool M503(const char* msg, String buf, int serial);
+extern bool M569(const char* msg, String buf, int serial);
extern bool M575(const char* msg, String buf, int serial);
extern bool M700(const char* msg, String buf, int serial);
extern bool M701(const char* msg, String buf, int serial);
+extern bool M906(const char* msg, String buf, int serial);
+extern bool M914(const char* msg, String buf, int serial);
extern bool M999(const char* msg, String buf, int serial);
extern bool M2000(const char* msg, String buf, int serial);
extern bool M2001(const char* msg, String buf, int serial);
diff --git a/include/InputDialogs.h b/include/InputDialogs.h
index 444da25..8a67f8d 100644
--- a/include/InputDialogs.h
+++ b/include/InputDialogs.h
@@ -28,8 +28,8 @@ typedef void(*bCallback)(bool val);
void getEncoderButton(int* turn, int* button, bool* isHeld, bool* isClicked);
void drawValue(const char* title, const char* PROGMEM message, String val);
-bool showInputDialog(const char* title, const char* PROGMEM message, float* val, float min, float max, fCallback cb = NULL);
-bool showInputDialog(const char* title, const char* PROGMEM message, int* val, int min, int max, iCallback cb = NULL);
+bool showInputDialog(const char* title, const char* PROGMEM message, float* val, float min, float max, fCallback cb = NULL, float increment = 1.0f);
+bool showInputDialog(const char* title, const char* PROGMEM message, int* val, int min, int max, iCallback cb = NULL, int increment = 1);
bool showInputDialog(const char* title, const char* PROGMEM message, bool* val, bCallback cb = NULL);
bool showInputDialog(const char* title, const char* PROGMEM message, unsigned long* val, String list);
bool showInputDialog(const char* title, const char* PROGMEM message, int* val, String list, iCallback cb = NULL, bool valIsIndex = true);
diff --git a/include/Menus.h b/include/Menus.h
index 917f119..ccab030 100644
--- a/include/Menus.h
+++ b/include/Menus.h
@@ -23,19 +23,27 @@
extern void setupMainMenu(char* menu);
extern void setupToolsMenu(char* menu);
-extern void setupOffsetMenu(char* menu);
+extern void setupStatusInfoMenu(char* menu);
extern void setupSwapMenu(char* menu);
extern void setupSettingsMenu(char* menu);
extern void setupTestrunMenu(char* menu);
+extern void setupOptionsMenu(char* menu);
extern void showMainMenu();
extern void showToolsMenu();
-extern void showOffsetsMenu(char* menuTitle);
+extern void showStatusInfoMenu(char* menuTitle);
extern void showSwapMenu(char* menuTitle);
extern void showSettingsMenu(char* menuTitle);
extern void showBaudratesMenu(char* menuTitle);
+extern void showOptionsMenu(char* menuTitle);
extern void showTestrunMenu(char* menuTitle);
+extern void showTMCStatus(int axis);
extern void changeOffset(int index);
extern void drawOffsetPosition(int index);
+extern bool selectBaudrate(int port, char* menuTitle);
+extern void selectPanelDuePort(char* menuTitle);
+extern const char* translateColor(int color);
+extern const char* translatePanelDuePort(int port);
+extern const char* translateTMCDriverMode(int mode);
#endif
\ No newline at end of file
diff --git a/include/SKR_mini/Pins.h b/include/SKR_mini/Pins.h
index 696d672..f903d46 100644
--- a/include/SKR_mini/Pins.h
+++ b/include/SKR_mini/Pins.h
@@ -35,22 +35,23 @@
#define Y_STEP_PIN PB13
#define Y_DIR_PIN PB14
#define Y_ENABLE_PIN PB12
-#define Y_END_PIN PC1
+#define Y_END_PIN PC1 // Endstop Y-
// FEEDER (E)
-// moved from Z to E because of the pins for 2nd Serial port
+// moved from Z to E because of the pins for 3rd Serial port,
+// so don't get confused by the pin names
#define STEP_HIGH_Z digitalWrite(Z_STEP_PIN, HIGH);
#define STEP_LOW_Z digitalWrite(Z_STEP_PIN, LOW);
#define Z_STEP_PIN PC5
#define Z_DIR_PIN PB0
#define Z_ENABLE_PIN PC4
-#define Z_END_PIN PC0
-#define Z_END2_PIN PA2
-#define Z_END_DUET_PIN PC3 // for testing only
+#define Z_END_PIN PC0 // Endstop Z-
+#define Z_END2_PIN PA2 // Endstop X+
+#define Z_END_DUET_PIN Z_END2_PIN
#define BEEPER_PIN PC10
-//#define SERVO1_PIN PB1 // THB - Not usable. See SKR mini schematics
-//#define SERVO2_PIN PA0 // TH0 - Not usable. See SKR mini schematics
+#define DEBUG_PIN PA1 // Endstop Y+
+#define RELAIS_PIN PC1 // Endstop Y- (Relais for stepper motor switching)
#if !defined(SMUFF_V5)
#define SERVO1_PIN PA1 // Endstop Y+
@@ -83,6 +84,9 @@ _DEFPIN_ARM(PB9, 9, B);
#define SDCS_PIN -1 // use default
+#define USB_CONNECT_PIN -1 // not avail
+#define SD_DETECT_PIN PA3
+
#define DSP_SCL PB6 // By default we run the SMuFF controller display on TWI (I2C)
#define DSP_SDA PB7
@@ -124,13 +128,28 @@ _DEFPIN_ARM(PB9, 9, B);
#define DEBUG_OFF_PIN PC3 // (PC3) Z+ pin - set to GND to re-enable debugging via STLink
#endif
-#define TX3_PIN PB10 // on SKR Mini usually used for Z-Axis STEP
-#define RX3_PIN PB11 // on SKR Mini usually used for Z-Axis DIR
+// SERIAL1
+#define CAN_USE_SERIAL1 true
+
+#define TX1_PIN PA9 // TFT header TX
+#define RX1_PIN PA10 // TFT header RX
/*
Those pins cannot be used for serial data transfer because they're
already in use on the SKR Mini V1.1
*/
+// SERIAL2
+#define CAN_USE_SERIAL2 false
+
#define TX2_PIN PA2 // on SKR Mini already used for X+ endstop (but might be reconfigured)
#define RX2_PIN PA3 // on SKR Mini already used for SD-Card DATA2
+/*
+ Those pins can be used for serial data transfer if the Z-Axis
+ is not being used on the SKR Mini V1.1
+*/
+// SERIAL3
+#define CAN_USE_SERIAL3 true
+
+#define TX3_PIN PB10 // on SKR Mini usually used for Z-Axis STEP
+#define RX3_PIN PB11 // on SKR Mini usually used for Z-Axis DIR
\ No newline at end of file
diff --git a/include/SKR_mini_E3/Pins.h b/include/SKR_mini_E3/Pins.h
new file mode 100644
index 0000000..1bce3b8
--- /dev/null
+++ b/include/SKR_mini_E3/Pins.h
@@ -0,0 +1,134 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/*
+ * Pins configuration file for SKR mini E3 V1.2 board - NOT E3 DIP!
+ */
+#pragma once
+
+#define BOARD_INFO "SKR mini E3 V1.2"
+// SELECTOR (X)
+#define STEP_HIGH_X digitalWrite(X_STEP_PIN, HIGH);
+#define STEP_LOW_X digitalWrite(X_STEP_PIN, LOW);
+#define X_STEP_PIN PB13
+#define X_DIR_PIN PB12
+#define X_ENABLE_PIN PB14
+#define X_END_PIN PC0 // X-STOP
+// REVOLVER (Y)
+#define STEP_HIGH_Y digitalWrite(Y_STEP_PIN, HIGH);
+#define STEP_LOW_Y digitalWrite(Y_STEP_PIN, LOW);
+#define Y_STEP_PIN PB10
+#define Y_DIR_PIN PB2
+#define Y_ENABLE_PIN PB11
+#define Y_END_PIN PC1 // Y-STOP
+// FEEDER (Z)
+#define STEP_HIGH_Z digitalWrite(Z_STEP_PIN, HIGH);
+#define STEP_LOW_Z digitalWrite(Z_STEP_PIN, LOW);
+#define Z_STEP_PIN PB0
+#define Z_DIR_PIN PC5
+#define Z_ENABLE_PIN PB1
+#define Z_END_PIN PC2 // Z-STOP
+#define Z_END2_PIN PC15 // E0-STOP
+#define Z_END_DUET_PIN Z_END2_PIN
+
+// (E) - Not used yet, just in case
+#define STEP_HIGH_E digitalWrite(E_STEP_PIN, HIGH);
+#define STEP_LOW_E digitalWrite(E_STEP_PIN, LOW);
+#define E_STEP_PIN PB3
+#define E_DIR_PIN PB4
+#define E_ENABLE_PIN PD2
+#define E_END_PIN PC15 // E0-STOP
+
+#define BEEPER_PIN PB5 // EXP1.10
+
+#define DEBUG_PIN PB9 // EXP1.5
+#define RELAIS_PIN PC14 // PROBE (Relais for stepper motor switching)
+
+#define SERVO1_PIN PC12 // PT-DET
+#define SERVO2_PIN PA1 // SERVO
+
+#define FAN_PIN PA8 // FAN0
+#define HEATER0_PIN PC8 // HE0
+#define HEATBED_PIN PC9 // BED
+
+#define SW_SERIAL_TX_PIN PC7 // NEOPIXEL for testing only
+#define SW_SERIAL_RX_PIN PC7 // NEOPIXEL for testing only
+
+#include "FastLED.h"
+_DEFPIN_ARM(PC7, 7, C); // needed to compensate "Invalid pin specified" while compiling
+
+#define NEOPIXEL_PIN -1 //PC7 // NEOPIXEL
+#define NUM_LEDS 5 // number of Neopixel LEDS
+#define BRIGHTNESS 127
+#define LED_TYPE WS2812B
+#define COLOR_ORDER GRB
+
+#define SDCS_PIN -1 // use default
+
+#define USB_CONNECT_PIN PC13
+#define SD_DETECT_PIN PC4
+
+#if defined(USE_CREALITY_DISPLAY)
+// LCD_PINS_EN = EXP1.3 = ST9720 DAT
+// LCD_PINS_RS = EXP1.4 = ST9720 CS
+// LCD_PINS_D4 = EXP1.5 = ST9720 CLK
+#define DSP_DATA_PIN PB7 // EXP1.3
+#define DSP_CS_PIN PB8 // EXP1.4
+#define DSP_DC_PIN PB9 // EXP1.5
+#define DSP_RESET_PIN -1
+
+#define ENCODER1_PIN PA9 // EXP1.8
+#define ENCODER2_PIN PA10 // EXP1.6
+#define ENCODER_BUTTON_PIN PB6 // EXP1.9
+#else // USE_TWI_DISPLAY
+#define DSP_SCL PB6 // EXP1.9
+#define DSP_SDA PB7 // EXP1.3
+
+#define DSP_CS_PIN -1
+#define DSP_DC_PIN -1
+#define DSP_RESET_PIN -1
+
+#define ENCODER1_PIN PA9 // EXP1.8
+#define ENCODER2_PIN PA10 // EXP1.6
+#define ENCODER_BUTTON_PIN PB8 // EXP1.4
+#endif
+
+#define DEBUG_OFF_PIN -1 // not needed on TWI display
+
+#define X_SERIAL_TX_PIN PB15 // XUART - SPI2 MOSI
+#define Y_SERIAL_TX_PIN PC6 // YUART - I2S2_MCK / TIM8_CH1 / SDIO_D6
+#define Z_SERIAL_TX_PIN PC10 // ZUART - SERIAL4 TX
+#define E_SERIAL_TX_PIN PC11 // EUART - SERIAL4 RX
+
+// SERIAL1 - Cannot be used for serial comm.
+#define CAN_USE_SERIAL1 false
+
+#define TX1_PIN PA9 // EXP1.8 - ENCODER1_PIN
+#define RX1_PIN PA10 // EXP1.6 - ENCODER2_PIN
+
+// SERIAL2 - Can be used for serial comm.
+#define CAN_USE_SERIAL2 true
+
+#define TX2_PIN PA2 // TX on TFT header
+#define RX2_PIN PA3 // RX on TFT header
+
+// SERIAL3 - Cannot be used for serial comm. on E3 but can on E3-DIP
+#define CAN_USE_SERIAL3 false
+
+#define TX3_PIN PB10 // Y-Axis STEP
+#define RX3_PIN PB11 // Y-Axis ENABLE
\ No newline at end of file
diff --git a/include/SKR_mini_E3/STM32F103RC_SKR_MINI.py b/include/SKR_mini_E3/STM32F103RC_SKR_MINI.py
new file mode 100644
index 0000000..795961f
--- /dev/null
+++ b/include/SKR_mini_E3/STM32F103RC_SKR_MINI.py
@@ -0,0 +1,13 @@
+import os
+Import("env")
+
+STM32_FLASH_SIZE = 256
+
+for define in env['CPPDEFINES']:
+ if define[0] == "VECT_TAB_ADDR":
+ env['CPPDEFINES'].remove(define)
+ if define[0] == "STM32_FLASH_SIZE":
+ STM32_FLASH_SIZE = define[1]
+
+# Relocate firmware from 0x08000000 to 0x08007000
+env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000"))
diff --git a/include/SKR_mini_E3/STM32F103RC_SKR_MINI_256K.ld b/include/SKR_mini_E3/STM32F103RC_SKR_MINI_256K.ld
new file mode 100644
index 0000000..1e720c1
--- /dev/null
+++ b/include/SKR_mini_E3/STM32F103RC_SKR_MINI_256K.ld
@@ -0,0 +1,14 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40
+ rom (rx) : ORIGIN = 0x08007000, LENGTH = 256K - 28K - 4K
+}
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/include/SKR_mini_E3DIP/Pins.h b/include/SKR_mini_E3DIP/Pins.h
new file mode 100644
index 0000000..cab35f9
--- /dev/null
+++ b/include/SKR_mini_E3DIP/Pins.h
@@ -0,0 +1,140 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/*
+ * Pins configuration file for SKR mini E3-DIP V1.1 board - NOT E3 1.2
+ */
+#pragma once
+
+#define BOARD_INFO "SKR mini E3-DIP V1.1"
+// SELECTOR (X)
+#define STEP_HIGH_X digitalWrite(X_STEP_PIN, HIGH);
+#define STEP_LOW_X digitalWrite(X_STEP_PIN, LOW);
+#define X_STEP_PIN PC6
+#define X_DIR_PIN PB15
+#define X_ENABLE_PIN PC7
+#define X_END_PIN PC1 // X-STOP
+// REVOLVER (Y)
+#define STEP_HIGH_Y digitalWrite(Y_STEP_PIN, HIGH);
+#define STEP_LOW_Y digitalWrite(Y_STEP_PIN, LOW);
+#define Y_STEP_PIN PB13
+#define Y_DIR_PIN PB12
+#define Y_ENABLE_PIN PB14
+#define Y_END_PIN PC0 // Y-STOP
+// Feeder (E)
+// moved from Z to E because of the pins for 3rd Serial port,
+// so don't get confused by the pin names
+#define STEP_HIGH_Z digitalWrite(Z_STEP_PIN, HIGH);
+#define STEP_LOW_Z digitalWrite(Z_STEP_PIN, LOW);
+#define Z_STEP_PIN PB0
+#define Z_DIR_PIN PC5
+#define Z_ENABLE_PIN PB1
+#define Z_END_PIN PC15 // Z-STOP (because E0-STOP is being used for 2nd servo)
+#define Z_END2_PIN PC14 // PROBE
+#define Z_END_DUET_PIN Z_END2_PIN
+
+// SPI for stepper drivers
+#define ST_MISO_PIN PB4 // MISO3
+#define ST_MOSI_PIN PB5 // MOSI3
+#define ST_SCLK_PIN PB3 // SCK3
+#define X_CS_PIN PC10 // doubles as XUART when used in serial mode
+#define Y_CS_PIN PC11 // doubles as YUART when used in serial mode
+#define Z_CS_PIN PC12 // doubles as ZUART when used in serial mode
+#define E_CS_PIN PD2 // doubles as EUART when used in serial mode
+
+#define BEEPER_PIN PA15 // EXP1.10
+
+#define RELAIS_PIN PC14 // PROBE (Relais for stepper motor switching)
+
+#define SERVO1_PIN PC2 // E0-STOP
+#define SERVO2_PIN PA1 // SERVO
+
+#define FAN_PIN PA8 // FAN0
+#define HEATER0_PIN PC8 // HE0
+#define HEATBED_PIN PC9 // BED
+
+#if defined(USE_FASTLED_BACKLIGHT)
+#include "FastLED.h"
+//_DEFPIN_ARM(PC7, 7, C); // needed to compensate "Invalid pin specified"
+ // while compiling if NEOXPIXEL_PIN is in use
+#endif
+
+#define NEOPIXEL_PIN -1
+#define NUM_LEDS 5 // number of Neopixel LEDS
+#define BRIGHTNESS 127
+#define LED_TYPE WS2812B
+#define COLOR_ORDER GRB
+
+#define SDCS_PIN -1 // use default
+
+#define USB_CONNECT_PIN PC13
+#define SD_DETECT_PIN PC4
+
+#if defined(USE_CREALITY_DISPLAY)
+#define DSP_DATA_PIN PB7 // EXP1.3 = LCD_PINS_EN = ST9720 DAT
+#define DSP_CS_PIN PB8 // EXP1.4 = LCD_PINS_RS = ST9720 CS
+#define DSP_DC_PIN PB9 // EXP1.5 = LCD_PINS_D4 = ST9720 CLK
+#define DSP_RESET_PIN -1
+
+#define ENCODER1_PIN PA9 // EXP1.8
+#define ENCODER2_PIN PA10 // EXP1.6
+#define ENCODER_BUTTON_PIN PB6 // EXP1.9
+
+#define DEBUG_PIN -1
+
+#else // USE_TWI_DISPLAY
+
+#define DSP_SCL PB6 // EXP1.9
+#define DSP_SDA PB7 // EXP1.3
+
+#define DSP_CS_PIN -1
+#define DSP_DC_PIN -1
+#define DSP_RESET_PIN -1
+
+#define ENCODER1_PIN PA9 // EXP1.8
+#define ENCODER2_PIN PA10 // EXP1.6
+#define ENCODER_BUTTON_PIN PB8 // EXP1.4
+
+#define DEBUG_PIN PB9 // EXP1.5
+
+#endif
+
+#define DEBUG_OFF_PIN -1 // not needed on TWI display
+
+#define X_SERIAL_TX_PIN PC10 // XUART - UART4 TX
+#define Y_SERIAL_TX_PIN PC11 // YUART - UART4 RX
+#define Z_SERIAL_TX_PIN PC12 // ZUART - UART5 TX
+#define E_SERIAL_TX_PIN PD2 // EUART - UART5 RX
+
+// SERIAL1 - Cannot be used for serial comm.
+#define CAN_USE_SERIAL1 false // used for encoder on EXP1
+
+#define TX1_PIN PA9 // EXP1.8 - ENCODER1_PIN
+#define RX1_PIN PA10 // EXP1.6 - ENCODER2_PIN
+
+// SERIAL2 - Can be used for serial comm.
+#define CAN_USE_SERIAL2 true // TFT header
+
+#define TX2_PIN PA2 // TX on TFT header
+#define RX2_PIN PA3 // RX on TFT header
+
+// SERIAL3 - Cannot be used for serial comm. on E3 but can on E3-DIP
+#define CAN_USE_SERIAL3 true // if no Z-Axis driver is being used
+
+#define TX3_PIN PB10 // Z-Axis STEP
+#define RX3_PIN PB11 // Z-Axis ENABLE
\ No newline at end of file
diff --git a/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI.py b/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI.py
new file mode 100644
index 0000000..795961f
--- /dev/null
+++ b/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI.py
@@ -0,0 +1,13 @@
+import os
+Import("env")
+
+STM32_FLASH_SIZE = 256
+
+for define in env['CPPDEFINES']:
+ if define[0] == "VECT_TAB_ADDR":
+ env['CPPDEFINES'].remove(define)
+ if define[0] == "STM32_FLASH_SIZE":
+ STM32_FLASH_SIZE = define[1]
+
+# Relocate firmware from 0x08000000 to 0x08007000
+env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000"))
diff --git a/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI_256K.ld b/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI_256K.ld
new file mode 100644
index 0000000..1e720c1
--- /dev/null
+++ b/include/SKR_mini_E3DIP/STM32F103RC_SKR_MINI_256K.ld
@@ -0,0 +1,14 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40
+ rom (rx) : ORIGIN = 0x08007000, LENGTH = 256K - 28K - 4K
+}
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/include/SMuFF.h b/include/SMuFF.h
index 95168c2..204efd0 100644
--- a/include/SMuFF.h
+++ b/include/SMuFF.h
@@ -39,15 +39,34 @@
#include "U8g2lib.h"
#include "MemoryFree.h"
#include "DataStore.h"
+#if defined(USE_FASTLED_BACKLIGHT)
#include "FastLED.h"
+#endif
+#include "ZTimerLib.h"
+#include "ZStepperLib.h"
+#include "ZServo.h"
+#include "ZPortExpander.h"
+#include "ZFan.h"
+#include "DuetLaserSensor.h"
+#include "SoftwareSerial.h"
+#include
+
+#if !defined(USE_FASTLED_BACKLIGHT)
+#define CRGB uint32_t
+#endif
#if defined (__STM32F1__)
#include
#include
+#include
#undef sprintf_P
#define sprintf_P(s, f, ...) sprintf(s, f, ##__VA_ARGS__)
#define vsnprintf_P vsnprintf
+#define cli() nvic_globalirq_disable()
+#define sei() nvic_globalirq_enable()
+extern USBMassStorage MassStorage;
+extern USBCompositeSerial CompositeSerial;
#endif
#if defined(__ESP32__)
@@ -63,6 +82,11 @@
#define PORT_EXPANDER_ADDRESS 0x3F
+#define INTERNAL 1
+#define EXTERNAL 0
+
+#define ArraySize(arr) (sizeof(arr)/sizeof(arr[0]))
+
typedef enum {
ABSOLUTE,
RELATIVE
@@ -115,7 +139,19 @@ typedef struct {
float insertLength = 5.0;
unsigned maxSpeedHS_Z = 10;
unsigned accelDistance_Z = 5;
-
+ // values for TMC drivers via UART or SPI
+ int stepperPower[NUM_STEPPERS+1] = { 700, 700, 700, 700 };
+ int stepperMode[NUM_STEPPERS+1] = { 0, 0, 0, 0 }; // 0 = NONE, 1 = UART, 2 = SPI
+ float stepperRSense[NUM_STEPPERS+1] = { 0.11, 0.11, 0.11, 0.11 };
+ int stepperMicrosteps[NUM_STEPPERS+1] = { 16, 16, 16,16 };
+ int stepperStall[NUM_STEPPERS+1] = { 0, 0, 0, 0 };
+ int stepperCSmin[NUM_STEPPERS+1] = { 0, 0, 0, 0 };
+ int stepperCSmax[NUM_STEPPERS+1] = { 0, 0, 0, 0 };
+ int stepperCSdown[NUM_STEPPERS+1] = { 0, 0, 0, 0 };
+ int stepperAddr[NUM_STEPPERS+1] = { 0, 0, 0, 0 };
+ int stepperToff[NUM_STEPPERS+1] = { 2, 2, 2, 2 };
+ bool stepperSpread[NUM_STEPPERS+1] = { true, true, true, true };
+
float unloadRetract = -20.0f;
float unloadPushback = 5.0f;
float pushbackDelay = 1.5f;
@@ -126,11 +162,11 @@ typedef struct {
int i2cAddress = 0x58;
int lcdContrast = DSP_CONTRAST;
int menuAutoClose = 20;
- bool delayBetweenPulses = false;
+ unsigned long serial0Baudrate = 57600;
unsigned long serial1Baudrate = 57600;
unsigned long serial2Baudrate = 57600;
- unsigned long serialDueBaudrate = 57600;
- bool duetDirect = false;
+ unsigned long serial3Baudrate = 57600;
+ bool sendActionCmds = false;
int fanSpeed = 0;
char materials[MAX_TOOLS][20];
long powerSaveTimeout = 300;
@@ -138,18 +174,22 @@ typedef struct {
char wipeSequence[30] = { 0 };
bool prusaMMU2 = true;
bool useDuetLaser = false;
- bool hasPanelDue = false;
+ int hasPanelDue = 0; // Serial Port for PanelDue (0=None)
int servoMinPwm = 550;
int servoMaxPwm = 2400;
bool sendPeriodicalStats = true;
int backlightColor = 0x4; // Cyan by default
+ bool runoutDetection = false;
+ bool isSharedStepper = false;
+ bool externalStepper = false;
+ bool encoderTickSound = false;
} SMuFFConfig;
#ifdef __BRD_I3_MINI
extern U8G2_ST7565_64128N_F_4W_HW_SPI display;
#endif
-#ifdef __BRD_SKR_MINI
+#if defined(__BRD_SKR_MINI) || defined(__BRD_SKR_MINI_E3) || defined(__BRD_SKR_MINI_E3DIP)
extern "C" uint8_t __wrap_u8x8_byte_arduino_2nd_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
#ifdef USE_TWI_DISPLAY
extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C display;
@@ -158,6 +198,8 @@ extern U8G2_ST7565_64128N_F_4W_HW_SPI display;
// extern U8G2_ST7920_128X64_F_SW_SPI display;
#elif USE_MINI12864_PANEL_V21
extern U8G2_ST7567_JLX12864_F_2ND_4W_HW_SPI display;
+ #elif USE_CREALITY_DISPLAY
+ extern U8G2_ST7920_128X64_F_SW_SPI display;
#else
extern U8G2_ST7567_ENH_DG128064_F_2ND_4W_HW_SPI display;
//extern U8G2_UC1701_MINI12864_1_2ND_4W_HW_SPI display;
@@ -169,25 +211,37 @@ extern U8G2_ST7565_64128N_F_4W_HW_SPI display;
#else
extern U8G2_ST7567_ENH_DG128064_F_4W_HW_SPI display;
#endif
+ extern HardwareSerial Serial3;
#endif
#ifdef __BRD_FYSETC_AIOII
extern U8G2_UC1701_MINI12864_F_4W_HW_SPI display;
#endif
+extern ZStepper steppers[];
+extern ZTimer stepperTimer;
+extern ZTimer gpTimer;
+extern ZServo servo;
+extern ZServo servoRevolver;
+extern ZFan fan;
extern ClickEncoder encoder;
+#if defined(USE_FASTLED_BACKLIGHT)
extern CRGB leds[];
+#else
+#endif
extern SMuFFConfig smuffConfig;
extern GCodeFunctions gCodeFuncsM[];
extern GCodeFunctions gCodeFuncsG[];
extern const char brand[];
+extern int swapTools[];
extern volatile byte nextStepperFlag;
extern volatile byte remainingSteppersFlag;
extern volatile unsigned long lastEncoderButtonTime;
extern byte toolSelected;
extern PositionMode positionMode;
-extern String serialBuffer0, serialBuffer2, serialBuffer9, traceSerial2;
+extern String serialBuffer0, serialBuffer2, serialBuffer9, traceSerial2;
+extern String tuneSequence;
extern bool displayingUserMessage;
extern unsigned int userMessageTime;
extern bool testMode;
@@ -199,14 +253,49 @@ extern volatile bool sendingResponse;
extern unsigned long endstopZ2HitCnt;
extern volatile bool showMenu;
extern bool maintainingMode;
+extern volatile double lastDuetPos;
+extern DuetLaserSensor duetLS;
+extern String wirelessHostname;
+extern volatile bool enablePeriStat;
+extern volatile bool interval20ms;
+extern volatile bool interval100ms;
+extern volatile bool interval250ms;
+extern volatile bool interval500ms;
+extern volatile bool interval1s;
+extern volatile bool interval2s;
+extern volatile bool interval5s;
+extern TMC2209Stepper* driverX;
+extern TMC2209Stepper* driverY;
+extern TMC2209Stepper* driverZ;
+extern TMC2209Stepper* driverE;
+
+
+extern void setupSerial();
+extern void setupSwSerial0();
extern void setupDisplay();
extern void setupTimers();
extern void setupSteppers();
+extern void setupTMCDrivers();
+extern void setupServos();
+extern void setupHeaterBed();
+extern void setupFan();
+extern void setupPortExpander();
+extern void setupRelay();
+extern void setupI2C();
+extern void setupDeviceName();
+extern void setupSerialBT();
+extern void setupBuzzer();
+extern void setupEncoder();
+extern void setupBacklight();
+extern void setupDuetLaserSensor();
+extern void initHwDebug();
+extern void initFastLED();
+extern void initUSB();
extern void drawLogo();
extern void drawStatus();
extern void drawSelectingMessage();
-extern void drawUserMessage(String message);
+extern void drawUserMessage(String message, bool smallFont = false, bool center = true, void (*drawCallbackFunc)() = NULL);
extern void drawSDStatus(int stat);
extern void drawFeed();
extern void resetDisplay();
@@ -242,7 +331,8 @@ extern void wireReceiveEvent(int numBytes);
extern void beep(int count);
extern void longBeep(int count);
extern void userBeep();
-extern void initBeep();
+extern void encoderBeep(int count);
+extern void startupBeep();
extern void setSignalPort(int port, bool state);
extern void signalNoTool();
extern void signalLoadFilament();
@@ -254,6 +344,7 @@ extern bool setServoMS(int servoNum, int microseconds);
extern void setServoMinPwm(int servoNum, int pwm);
extern void setServoMaxPwm(int servoNum, int pwm);
extern void getStoredData();
+extern void readTune();
extern void readConfig();
extern bool writeConfig(Print* dumpTo = NULL);
extern bool checkAutoClose();
@@ -278,6 +369,31 @@ extern bool checkStopMenu(unsigned startTime);
extern void drawTestrunMessage(unsigned long loop, char* msg);
extern bool getFiles(const char* rootFolder, const char* pattern, int maxFiles, bool cutExtension, char* files);
extern void testRun(String fname);
+extern void moveFeeder(float distanceMM);
+extern void overrideStepX();
+extern void overrideStepY();
+extern void overrideStepZ();
+extern bool stallCheckX();
+extern bool stallCheckY();
+extern bool stallCheckZ();
+extern void endstopEventY();
+extern void endstopEventZ();
+extern void endstopEventZ2();
+extern bool checkDuetEndstop();
+extern void setToneTimerChannel(uint8_t ntimer, uint8_t channel);
+extern void isrStepperHandler();
+extern void isrGPTimerHandler();
+extern void refreshStatus(bool withLogo, bool feedOnly);
+extern void every10ms();
+extern void every20ms();
+extern void every50ms();
+extern void every100ms();
+extern void every250ms();
+extern void every500ms();
+extern void every1s();
+extern void every2s();
+extern void every5s();
+extern void blinkLED();
extern void printEndstopState(int serial);
extern void printPos(int index, int serial);
@@ -298,6 +414,7 @@ extern bool parse_PMMU2(char cmd, const String& buf, int serial);
extern bool parse_Action(const String& buf, int serial);
extern int getParam(String buf, char* token);
extern long getParamL(String buf, char* token);
+extern float getParamF(String buf, char* token);
extern int hasParam(String buf, char* token);
extern bool getParamString(String buf, char* token, char* dest, int bufLen);
extern void prepStepping(int index, long param, bool Millimeter = true, bool ignoreEndstop = false);
@@ -308,6 +425,7 @@ extern void printResponseP(const char* response, int serial);
extern void printOffsets(int serial);
extern void maintainTool();
extern void printPeriodicalState(int serial);
+extern void playSequence(const char* sequence);
extern void showLed(int mode, int count);
extern void setBacklightIndex(int color);
@@ -318,4 +436,9 @@ extern void setFastLED(int index, CRGB color);
extern void setFastLEDIndex(int index, int color);
extern void setFastLEDIntensity(int intensity);
extern void testFastLED();
+
+extern void showDuetLS();
+extern void switchFeederStepper(int stepper);
+extern void removeFirmwareBin();
+
#endif
diff --git a/include/Strings.h b/include/Strings.h
index 979b6e1..da5bfb5 100644
--- a/include/Strings.h
+++ b/include/Strings.h
@@ -30,15 +30,17 @@
#if defined (__STM32F1__) || defined (__ESP32__)
const char P_MenuItemBack [] PROGMEM = { "\u25c0 BACK\n" };
-const char P_MenuItemSeparator [] PROGMEM = { "\u25ab\u25ab\u25ab\u25ab\u25ab\n"};
-#if defined(SMUFF_V5)
-const char P_MenuItems [] PROGMEM = { "Home All\nMotors %s\nServo %s\nTool Maint. %s\nReset Feeder Jam\nSwap Tools \u25b8\nLoad Filament\nUnload Filament\n%s%s%s" };
-const char P_MenuItemsDefault[] PROGMEM = { "Settings \u25b8\n%sTestrun \u25b8" };
-#else
-const char P_MenuItems [] PROGMEM = { "Home All\nMotors %s\nReset Feeder Jam\nSwap Tools \u25b8\nLoad Filament\nUnload Filament\n%s%s%s" };
+const char P_MenuItemSeparator [] PROGMEM = { "\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\u00ad\n"};
+const char P_MenuItems [] PROGMEM = { "Home All\nMotors %s\n%sTool Maint. %s\nReset Feeder Jam\nLoad Filament\nUnload Filament\n%s%s" };
+const char P_MenuItemsDefault[] PROGMEM = { "%sSwap Tools \u25b8\nStatus Info \u25b8\n%sSettings \u25b8\n%sTestrun \u25b8" };
+#if !defined(SMUFF_V5)
const char P_MenuItemsDefault[] PROGMEM = { "Settings \u25b8\n%sTestrun \u25b8" };
#endif
-const char P_OfsMenuItems [] PROGMEM = { "Selector %4s\nRevolver %5s" };
+const char P_StatusInfoMenuItems [] PROGMEM = { "Duet Laser Sensor \u25b8%s%s%s" };
+const char P_StatusInfoMenuItemsX [] PROGMEM= { "\nTMC Driver X \u25b8" };
+const char P_StatusInfoMenuItemsY [] PROGMEM= { "\nTMC Driver Y \u25b8" };
+const char P_StatusInfoMenuItemsZ [] PROGMEM= { "\nTMC Driver Z \u25b8" };
+
#else
const char P_MenuItemBack [] PROGMEM = { "< BACK\n" };
const char P_MenuItemSeparator [] PROGMEM = { "-----\n"};
@@ -47,6 +49,7 @@ const char P_MenuItems [] PROGMEM = { "Home All\nMotors %s\nReset Feed
const char P_MenuItemsDefault[] PROGMEM = { "Settings >" };
const char P_OfsMenuItems [] PROGMEM = { "Selector %4s\nRevolver %5s" };
#endif
+const char P_MenuItemsServo [] PROGMEM = { "%s Servo\n" };
const char P_MenuItemsPMMU [] PROGMEM = { "Load To Nozzle\n" };
const char P_OkButtonOnly [] PROGMEM = { " Ok " };
const char P_CancelButtonOnly [] PROGMEM = { " Cancel " };
@@ -80,18 +83,23 @@ const char P_Busy[] PROGMEM = { "busy..." };
const char P_Ready[] PROGMEM = { "ready." };
const char P_Pemu[] PROGMEM = { "PMMU2" };
#if defined (__STM32F1__) || defined (__ESP32__)
-const char P_SettingsMenuItems[] PROGMEM = { "Tool Count %5s\nBowden Length %5s\nSelector Dist. %5s\nMenu Auto Close %4s\nFan Speed %5s\nPrusa MMU2 Emul. %4s\nSend Status Info %4s\nBaudrates %4s\nOffsets %4s\nSteppers/Servo %4s\nDisplay %4s\n%s\u25b9 SAVE TO SD-CARD \u25c3" };
+const char P_SettingsMenuItems[] PROGMEM = { "Tool Count %5s\nBowden Length %5s\nSelector Dist. %5s\n%sOptions %4s\nBaudrates %4s\nSteppers/Servo %4s\nDisplay %4s\n%s\u25b9 SAVE TO SD-CARD \u25c3" };
#else
-const char P_SettingsMenuItems[] PROGMEM = { "Tool Count %5s\nBowden Length %5s\nSelector Dist. %5s\nMenu Auto Close %4s\nFan Speed %5s\nPower Save Time %5s\nPrusa MMU2 Emul. %4S\nBaudrates %s\nOffsets %s\nSteppers %s\n%S> SAVE TO SD-CARD <" };
+const char P_SettingsMenuItems[] PROGMEM = { "Tool Count %5s\nBowden Length %5s\nSelector Dist. %5s\n%sOptions %4S\nBaudrates %s\nSteppers %s\n%S> SAVE TO SD-CARD <" };
#endif
const char P_Off[] PROGMEM = { "OFF" };
const char P_On[] PROGMEM = { "ON" };
const char P_Yes[] PROGMEM = { "Yes" };
const char P_No[] PROGMEM = { "No" };
-const char P_High[] PROGMEM = { "HI" };
-const char P_Low[] PROGMEM = { "LO" };
+const char P_No_[] PROGMEM = { " " };
+const char P_Unknown[] PROGMEM = { "---" };
+const char P_High[] PROGMEM = { "HIGH" };
+const char P_Low[] PROGMEM = { "LOW" };
const char P_Open[] PROGMEM = { "OPEN" };
const char P_Close[] PROGMEM = { "CLOSE" };
+const char P_None[] PROGMEM = { "None" };
+const char P_Stealth[] PROGMEM = { "Stealth" };
+const char P_Spread[] PROGMEM = { "Spread" };
const char P_ToolCount[] PROGMEM = { "# of tools:" };
const char P_InMillimeter[] PROGMEM = { "in mm:" };
@@ -99,8 +107,8 @@ const char P_InSeconds[] PROGMEM = { "in seconds:" };
const char P_InPercent[] PROGMEM = { "in percent:" };
const char P_InValue[] PROGMEM = { "as value:" };
const char P_YesNo[] PROGMEM = { "yes / no:" };
-const char P_Baud[] PROGMEM = { "Baudrate:" };
-const char P_Color[] PROGMEM = { "Color:" };
+const char P_Baud[] PROGMEM = { "baudrate:" };
+const char P_Color[] PROGMEM = { "color:" };
const char P_InMicroseconds[] PROGMEM = { "in uS:" };
const char P_InTicks[] PROGMEM = { "in ticks:" };
const char P_InSteps[] PROGMEM = { "in steps:" };
@@ -109,24 +117,32 @@ const char P_OpenPos[] PROGMEM = { "open @:" };
const char P_ClosedPos[] PROGMEM = { "closed @:" };
const char P_ServoCycles[] PROGMEM = { "cycles:" };
const char P_NoOfChunks[] PROGMEM = { "# of chunks:" };
-const char P_BaudMenuItems[] PROGMEM = { "USB-Serial %6s\n2nd Serial %6s" };
+const char P_DriverMode[] PROGMEM = { "drvr. mode:" };
+const char P_InMilliAmpere[] PROGMEM = { "in mA:" };
+const char P_InOhm[] PROGMEM = { "in ohm:" };
+const char P_Threshold[] PROGMEM = { "threshold:" };
+const char P_Min[] PROGMEM = { "min.:" };
+const char P_Max[] PROGMEM = { "max.:" };
+const char P_Down[] PROGMEM = { "down:" };
+const char P_Address[] PROGMEM = { "address:" };
+const char P_Microsteps[] PROGMEM = { "microsteps:" };
+const char P_Value[] PROGMEM = { "value:" };
+const char P_MicrostepItems[] PROGMEM = { "1\n2\n4\n8\n16\n32\n64\n128" };
+const char P_TMCModeItems[] PROGMEM = { "OFF\nUART\nSPI" };
+const char P_BaudMenuItems[] PROGMEM = { "USB-Serial %6s\n1st Serial %6s\n2nd Serial %6s\n3rd Serial %6s" };
const char P_Baudrates[] PROGMEM = { "4800\n9600\n19200\n38400\n56700\n115200\n230400" };
const char P_Colors[] PROGMEM = { "Black\nRed\nGreen\nBlue\nCyan\nMagenta\nYellow\nWhite" };
+const char P_PanelDueOptions[] PROGMEM = { "None\nSer.2\nSer.3" };
+
#if defined (__STM32F1__) || defined (__ESP32__)
-#if defined(SMUFF_V5)
-const char P_SteppersMenuItems[] PROGMEM = { "Selector %2s\nFeeder %2s\nServo %2s" };
-#else
-const char P_SteppersMenuItems[] PROGMEM = { "Selector %2s\nFeeder %2s\nRevolver %2s" };
-#endif
-const char P_AllSteppersMenuItems[] PROGMEM = { "Invert DIR %4s\nEndstop Trigger %4s\nStep Delay %4s\nMax. Speed %5s\nMax. Speed HS %5s\nAcceleration %5s" };
-#if defined(SMUFF_V5)
-const char P_RevolverMenuItems[] PROGMEM = { "Home After Feed %4s\nReset Bef. Feed %4s\nUse Servo 2 %4s\nServo 2 opened %5s\nServo 2 closed %5s\nServo 1 cycles %5s\nServo 2 cycles %5s" };
-#else
-const char P_RevolverMenuItems[] PROGMEM = { "\nSteps per Rev. %5s\nHome After Feed %4s\nReset Bef. Feed %4s\nWiggle %4s\nUse Servo %4s\nServo 2 opened %5s\nServo 2 closed %5s\nServo 1 cycles %5s\nServo 2 cycles %5s" };
-#endif
-const char P_FeederMenuItems[] PROGMEM = { "\nSteps per MM %5s\nEnable Chunks %4s\nFeed Chunks %4s\nInsert Length %5s\nInsert Speed %5s\nReinforce Len. %5s" };
-const char P_SelectorMenuItems[] PROGMEM = { "\nSteps per MM %5s" };
-const char P_DisplayMenuItems[] PROGMEM = { "Screen Timeout %4s\nLCD Contrast %4s\nBacklight %8s" };
+const char P_SteppersMenuItems[] PROGMEM = { "Selector %2s\nFeeder %2s\n%-8s %2s" };
+const char P_AllSteppersMenuItems[] PROGMEM = { "TMC Settings %4s\u25b8\nInvert DIR %4s\nEndstop Trigger %4s\nStep Delay %4s\nMax. Speed %5s\nMax. Speed HS %5s\nAcceleration %5s" };
+const char P_RevolverMenuItems[] PROGMEM = { "\n1st Tool Offset %5s\nSteps per Rev. %5s\nHome After Feed %4s\nReset Bef. Feed %4s\nWiggle %4s\nUse Lid Servo %4s\nLid Servo open %5s" };
+const char P_FeederMenuItems[] PROGMEM = { "\nSteps per mm %5s\nEnable Chunks %4s\nFeed Chunks %4s\nInsert Length %5s\nInsert Speed %5s\nReinforce Len. %5s\nExternal Ctrl. %4s\nIs Shared %4s" };
+const char P_SelectorMenuItems[] PROGMEM = { "\n1st Tool Offset %5s\nSteps per mm %5s" };
+const char P_ServoMenuItems[] PROGMEM = { "Home After Feed %4s\nReset Bef. Feed %4s\nUse Lid Servo %4s\nLid Servo Open %5s\nLid Servo Close %5s\nWiper Servo Cycles%3s\nLid Servo Cycles %3s" };
+const char P_TMCMenuItems[] PROGMEM = { "Mode %4s\nPower %4s\nR-Sense %4s\nMicrosteps %4s\nStall Thrs. %5s\nCoolStep min. %4s\nCoolStep max. %4s\nCoolStep down %4s\nDriver Address %4s\nTOff %4s" };
+const char P_DisplayMenuItems[] PROGMEM = { "Screen Timeout %4s\nLCD Contrast %4s\nBacklight %8s\nEncoder Ticks %4s" };
#else
const char P_SteppersMenuItems[] PROGMEM = { "Selector >\nRevolver >\nFeeder >" };
const char P_AllSteppersMenuItems[] PROGMEM = { "Invert DIR %4S\nEndstop Trigger %4S\nStep Delay %4s\nMax. Speed %5s\nMax. Speed HS %5s\nAcceleration %5s" };
@@ -134,6 +150,12 @@ const char P_RevolverMenuItems[] PROGMEM = { "\nSteps per Rev. %5s\nHome Aft
const char P_FeederMenuItems[] PROGMEM = { "\nSteps per MM %5s\nEnable Chunks %4S\nFeed Chunks %4s\nInsert Length %5s\nInsert Speed %5s\nReinforce Len. %5s" };
const char P_SelectorMenuItems[] PROGMEM = { "\nSteps per MM %5s" };
#endif
+#if defined (__STM32F1__) || defined (__ESP32__)
+const char P_OptionsMenuItems[] PROGMEM = { "Menu Auto Close %4s\nFan Speed %5s\nPrusa MMU2 Emul. %4s\nSend Status Info %4s\nUse Laser Sensor %4s\nPanelDue Port %5s" };
+#else
+const char P_OptionsMenuItems[] PROGMEM = { "Menu Auto Close %4s\nFan Speed %5s\nPower Save Time %5s\nPrusa MMU2 Emul. %4S\n" };
+#endif
+
const char P_ConfigWriteSuccess[] PROGMEM = { "Config success-\nfully written." };
const char P_ConfigWriteFail[] PROGMEM = { "Config write failed!\nPlease check SD-Card." };
@@ -145,6 +167,10 @@ const char P_ToolChanges[] PROGMEM = { "Tool change: %5ld" };
const char P_TestTime[] PROGMEM = { "Elapsed: %3d:%02d:%02d" };
const char P_FeederErrors[] PROGMEM = { "Feed errors: %5ld" };
const char P_ButtonToStop[] PROGMEM = { "Press Button To Stop" };
+const char P_DuetLSStat[] PROGMEM = { "Duet3D LS Status" };
+const char P_DuetLSDisabled[] PROGMEM = { "Duet3D LaserSensor\nnot enabled!" };
+const char P_DuetLSData[] PROGMEM = { "Position:%s%6smm\nQ/B/S: %3d/%3d/%3d\nSwitch: %3s\nError: %4s\nVersion: %3d" };
+const char P_PanelDuePort[] PROGMEM = { "Use Port:" };
const char P_SD_ReadingConfig[] PROGMEM = { "Reading config..." };
const char P_SD_InitError[] PROGMEM = { "SD-Card not ready!" };
@@ -155,6 +181,8 @@ const char P_Start[] PROGMEM = { "start\n" };
const char P_Error[] PROGMEM = { "error: %s\n" };
const char P_Echo[] PROGMEM = { "echo: %s\n" };
const char P_UnknownCmd[] PROGMEM = { "Unknown command: %s" };
+const char P_UnknownParam[] PROGMEM = { "Unknown parameter '%s'\n" };
+const char P_NoValue[] PROGMEM = { "Value ('Sn') missing for parameter '%s'\n" };
const char P_AlreadySaved[] PROGMEM = { "Already saved.\n" };
const char P_GVersion[] PROGMEM = { "FIRMWARE_NAME: Smart.Multi.Filament.Feeder (SMuFF) FIRMWARE_VERSION: %s ELECTRONICS: %s DATE: %s MODE: %s\n" };
const char P_TResponse[] PROGMEM = { "T%d\n" };
@@ -168,11 +196,13 @@ const char P_FeederPos[] PROGMEM = { "Feeder position = %ld\n" };
const char P_ToolSelected[] PROGMEM = { "Tool selected = %d\n" };
const char P_Contrast[] PROGMEM = { "Display contrast = %d\n" };
const char P_ToolsConfig[] PROGMEM = { "Tools configured = %d\n" };
-const char P_AccelSpeed[] PROGMEM = { "X (Selector):\t%s, D:%s\nY (Revolver):\t%s, D:%s\nZ (Feeder):\t%s, D:%s\n" };
+const char P_AccelSpeed[] PROGMEM = { "X (Selector):\t%s, D:%s\nY (Revolver):\t%s, D:%s\nZ (Feeder):\t%s%s, D:%s\n" };
const char P_Positions[] PROGMEM = { "X (Selector): %s, Y (Revolver): %s, Z (Feeder): %s\n" };
const char P_CurrentTool[] PROGMEM = {"Tool " };
const char P_Feed[] PROGMEM = {"Feed " };
+const char P_External[] PROGMEM = {"EXT." };
+const char P_Internal[] PROGMEM = {"INT." };
const char P_NoTool [] PROGMEM = { "No tool set.\n" };
const char P_Aborting [] PROGMEM = { "Aborting..."};
@@ -180,14 +210,51 @@ const char P_FeederJammed [] PROGMEM = { "Feeder is jammed.\n" };
const char P_JamCleared [] PROGMEM = { "Feeder Jam has\nbeen reset." };
const char P_ToolAlreadySet [] PROGMEM= { "Tool already set." };
const char P_WrongTool [] PROGMEM = { "Tool index %d invalid." };
+const char P_ActionMsg [] PROGMEM = { "Controller says:\n%s" };
const char P_WrongFormat [] PROGMEM = { "Wrong format. Use Bdd:dd:dd...\n" };
-const char P_NoPrusa [] PROGMEM = { "Prusa MMU2 mode was not configured." };
+const char P_NoPrusa [] PROGMEM = { "Prusa MMU2 mode is not configured." };
const char P_PMMU_Title [] PROGMEM = { "Waiting..." };
const char P_PMMU_Wait [] PROGMEM = { "Please click the" };
const char P_PMMU_WaitAdd [] PROGMEM = { "encoder button" };
+const char P_StepperMode [] PROGMEM = { "%s: %s" };
+const char P_StepperNotCfg [] PROGMEM = { "Driver not in use!" };
+const char P_StepperUART [] PROGMEM = { "UART" };
+const char P_StepperPDN [] PROGMEM = { "PDN" };
+
+const char P_TMC_Setup00[] PROGMEM = { " -X- -Y- -Z- -E-\n" };
+const char P_TMC_Setup01[] PROGMEM = { "IC Version " };
+const char P_TMC_Setup02[] PROGMEM = { "Enabled " };
+const char P_TMC_Setup03[] PROGMEM = { "Current Config. " };
+const char P_TMC_Setup03a[] PROGMEM = { "RMS Current " };
+const char P_TMC_Setup04[] PROGMEM = { "Microsteps " };
+const char P_TMC_Setup05[] PROGMEM = { "Off Time " };
+const char P_TMC_Setup06[] PROGMEM = { "Blank Time " };
+const char P_TMC_Setup07[] PROGMEM = { "UART Mode " };
+const char P_TMC_Setup08[] PROGMEM = { "MS2 / MS1 " };
+const char P_TMC_Setup09[] PROGMEM = { "Diag " };
+const char P_TMC_Setup10[] PROGMEM = { "StallGuard THRS " };
+const char P_TMC_Setup11[] PROGMEM = { "StallGuard Result " };
+const char P_TMC_Setup12[] PROGMEM = { "CoolStep Min. " };
+const char P_TMC_Setup13[] PROGMEM = { "CoolStep Max. " };
+const char P_TMC_Setup14[] PROGMEM = { "CoolStep Down " };
+const char P_TMC_Setup15[] PROGMEM = { "CoolStep THRS " };
+const char P_TMC_Status00[] PROGMEM = { " -------------= STATUS =-------------\n" };
+const char P_TMC_Status01[] PROGMEM = { "Mode "};
+const char P_TMC_Status02[] PROGMEM = { "Stand Still "};
+const char P_TMC_Status03[] PROGMEM = { "Ph. A open "};
+const char P_TMC_Status04[] PROGMEM = { "Ph. B open "};
+const char P_TMC_Status05[] PROGMEM = { "Ph. A short "};
+const char P_TMC_Status06[] PROGMEM = { "Ph. B short "};
+const char P_TMC_Status07[] PROGMEM = { "Ph. A short MOS "};
+const char P_TMC_Status08[] PROGMEM = { "Ph. B short MOS "};
+const char P_TMC_Status09[] PROGMEM = { "Overtemp. Warning "};
+const char P_TMC_Status10[] PROGMEM = { "Overtemperature "};
+// .....................\n.....................\n.....................\n.....................\n.....................
+const char P_TMC_Status[] PROGMEM = { "Mode %7s\nRMS Cur. %4dmA\nPh. A/B open %3s/%3s\nPh. A/B short %3s/%3s\nOvertemperature %3s"};
+
const char P_GCmds[] PROGMEM = {
"G0\t-\tMove\n" \
"G1\t-\tMove\n" \
@@ -198,6 +265,7 @@ const char P_GCmds[] PROGMEM = {
"G91\t-\tRelative positioning\n" };
const char P_MCmds[] PROGMEM = {
+ "M17\t-\tSwitch feeder stepper control (Relay)\n" \
"M18\t-\tMotors off\n" \
"M84\t-\tMotors off\n" \
"M20\t-\tList SD-Card\n" \
@@ -209,21 +277,26 @@ const char P_MCmds[] PROGMEM = {
"M115\t-\tReport version\n" \
"M117\t-\tDisplay message\n" \
"M119\t-\tReport endstop status\n" \
+ "M122\t-\tReport TMC driver status\n" \
"M150\t-\tSet FastLED color\n" \
"M201\t-\tSet max acceleration\n" \
"M203\t-\tSet max feedrate\n" \
"M205\t-\tSet advanced options\n" \
"M206\t-\tSet offsets\n" \
"M250\t-\tLCD contrast\n" \
- "M300\t-\tBeep\n" \
+ "M412\t-\tJAM detection on/off\n" \
+ "M300\t-\tPlay a tone or a tune\n" \
+ "M350\t-\tSet motor microstepping\n" \
"M500\t-\tSave settings\n" \
"M503\t-\tReport settings\n" \
+ "M569\t-\tSet SpreadCycle on/off\n" \
"M575\t-\tSet serial port baudrate\n" \
"M700\t-\tLoad filament\n" \
"M701\t-\tUnload filament\n" \
+ "M906\t-\tSet motor current\n" \
+ "M914\t-\tSet motor stall sensitivity\n" \
"M999\t-\tReset\n" \
"M2000\t-\tText to decimal\n" \
"M2001\t-\tDecimal to text\n"};
-
#endif
diff --git a/include/Wanhao_i3_mini/Pins.h b/include/Wanhao_i3_mini/Pins.h
index 4cb0fbf..1beba9e 100644
--- a/include/Wanhao_i3_mini/Pins.h
+++ b/include/Wanhao_i3_mini/Pins.h
@@ -48,6 +48,9 @@
#define BEEPER_PIN 37
+#define DEBUG_PIN -1
+#define RELAIS_PIN -1 // Relais for stepper motor switching
+
#define SERVO1_PIN 44
#define SERVO2_PIN 14
#define FAN_PIN 12
@@ -62,6 +65,10 @@
#define DSP_DC_PIN 40
#define DSP_RESET_PIN 27
+#define CAN_USE_SERIAL1 true
+#define CAN_USE_SERIAL2 false
+#define CAN_USE_SERIAL3 false
+
#define TX2_PIN 16
#define RX2_PIN 17
diff --git a/include/ZFan.h b/include/ZFan.h
new file mode 100644
index 0000000..7aca6ac
--- /dev/null
+++ b/include/ZFan.h
@@ -0,0 +1,66 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include
+#include
+#include "Config.h"
+
+#ifndef _ZFAN_H
+#define _ZFAN_H
+
+#define MAX_FANS 2
+#define FAN_DUTY_CYCLE 150 // fan cycle in us (7500)
+
+extern void __debug(const char* fmt, ...);
+
+void isrFanTimerHandler();
+
+class ZFan {
+public:
+ ZFan() { _pin = 0; };
+
+ void attach(int pin);
+ void attach(int pin, int fanIndex) { attach(pin); setIndex(fanIndex); }
+ void setIndex(int fanIndex);
+ void detach();
+ void setFanSpeed(int speed);
+ void setFan();
+ void setFanPin(int state);
+ void setPulseWidthMinMax(int min, int max) { _minSpeed = min; _maxSpeed = max; }
+ void setPulseWidthMin(int min) { _minSpeed = min; }
+ void setPulseWidthMax(int max) { _maxSpeed = max; }
+
+private:
+ int _pin;
+ bool _useTimer = false;
+ bool _timerStopped = false;
+ int _fanIndex;
+ int _speed;
+ int _minSpeed = 0;
+ int _maxSpeed = FAN_DUTY_CYCLE;
+#ifdef __STM32F1__
+ volatile uint32_t _tickCnt;
+#else
+ volatile int _tickCnt;
+#endif
+ volatile int _dutyCnt;
+ int _loopCnt;
+ int _pulseLen;
+};
+#endif
\ No newline at end of file
diff --git a/include/ZServo.h b/include/ZServo.h
index 23a9a49..efdbe6b 100644
--- a/include/ZServo.h
+++ b/include/ZServo.h
@@ -37,7 +37,6 @@
extern void __debug(const char* fmt, ...);
void isrServoTimerHandler();
-static ZTimer servoTimer;
static volatile bool timerSet = false;
class ZServo {
@@ -59,7 +58,8 @@ public:
void setPulseWidthMinMax(int min, int max) { _minPw = min; _maxPw = max; }
void setPulseWidthMin(int min) { _minPw = min; }
void setPulseWidthMax(int max) { _maxPw = max; }
- void stop() { if(_useTimer) servoTimer.stopTimer(); }
+ void stop(bool state) { _timerStopped = state; }
+ bool isTimerStopped() { return _timerStopped; }
bool hasTimer() { return _useTimer; }
void setMaxCycles(int val) { _maxCycles = val;}
int getMaxCycles() { return _maxCycles;}
@@ -72,6 +72,7 @@ private:
void setServoPin(int state);
int _pin;
bool _useTimer = false;
+ bool _timerStopped = false;
int _servoIndex;
int _degree;
int _lastDegree;
@@ -84,7 +85,6 @@ private:
#endif
volatile int _dutyCnt;
int _maxCycles;
- int _loopCnt;
int _pulseLen;
int _minPw = US_PER_PULSE_0DEG;
int _maxPw = US_PER_PULSE_180DEG;
diff --git a/include/ZStepperLib.h b/include/ZStepperLib.h
index 498fc9c..dbfeaf8 100644
--- a/include/ZStepperLib.h
+++ b/include/ZStepperLib.h
@@ -43,7 +43,7 @@ public:
ZStepper();
ZStepper(int number, char* descriptor, int stepPin, int dirPin, int enablePin, unsigned int accelaration, unsigned int minStepInterval);
- void prepareMovement(long steps, boolean ignoreEndstop = false);
+ void prepareMovement(long steps, bool ignoreEndstop = false);
void handleISR();
void home();
@@ -51,6 +51,7 @@ public:
void (*endstopFunc)() = NULL;
void (*endstop2Func)() = NULL;
bool (*endstopCheck)() = NULL;
+ bool (*stallCheck)() = NULL;
void (*runAndWaitFunc)(int number) = NULL;
void (*runNoWaitFunc)(int number) = NULL;
void defaultStepFunc(); // default step method, uses digitalWrite on _stepPin
diff --git a/include/ZTimerLib.h b/include/ZTimerLib.h
index 318691e..3170a7c 100644
--- a/include/ZTimerLib.h
+++ b/include/ZTimerLib.h
@@ -39,6 +39,13 @@ public:
ZTIMER8 = 8
} IsrTimer;
+ typedef enum {
+ CH1 = 1,
+ CH2 = 2,
+ CH3 = 3,
+ CH4 = 4
+ } IsrTimerChannel;
+
typedef enum {
PRESCALER1 = 1,
PRESCALER8 = 2,
diff --git a/platformio.ini b/platformio.ini
index a74b455..6f88b8a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -8,30 +8,84 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
-default_envs = BIGTREE_SKR_MINI, BIGTREE_SKR_MINI_SD, SMUFF_ESP32
+default_envs = BIGTREE_SKR_MINI_E3DIP_SD, BIGTREE_SKR_MINI_E3_SD, BIGTREE_SKR_MINI_SD, FYSETC_AIOII_SD, SMUFF_ESP32
#default_envs = BIGTREE_SKR_13
+#
+# TODO: Pick a display type here by removing / setting
+# the comment char (#) accordingly
+#
+# WARNING: If you pick the ANET display, make sure you've checked
+# the wiring before attaching the display to the board!
+# Instructions to modify the ANET display can be found
+# here: https://www.thingiverse.com/thing:4009810
+[display]
+build_flags = -D USE_TWI_DISPLAY
+ #-D USE_ANET_DISPLAY
+ #-D USE_MINI12864_PANEL_V21
+ #-D USE_CREALITY_DISPLAY
+
+ # use either one of the backlight options or none, if your
+ # display doesn't support this feature
+ #-D USE_FASTLED_BACKLIGHT
+ #-D USE_RGB_BACKLIGHT
+
+#
+# STM32 common build flags for USB port usage
+#
+[USB]
+build_flags = -D ENABLE_USB_SERIAL
+ -D SERIAL_USB
+ -D USBD_USE_CDC
+ -D USBCON
+ # not sure about the next two
+ -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
+ -D HAL_PCD_MODULE_ENABLED
+#
+# include these if you're going to use TMC stepper drivers
+# and set the definitions accordingly
+#
+[TMC]
+lib_deps = # both libraries being used for TMC stepper drivers
+ https://github.com/teemuatlut/TMCStepper
+ https://github.com/FYSETC/SoftwareSerialM
+build_flags = -D TMC_BAUDRATE=19200
+
[common]
-lib_deps =
- # SD-Card file system library
- SdFs
- # JSON library for the configuration file
- ArduinoJson@6
- # LC-Display library
- U8G2
- # Rotary-Encoder library
- #https://github.com/Den-W/encoder.git
- #Free memory library
- https://github.com/McNeight/MemoryFree
- # FastLED library - use fork FastLED-STM32 instead of original one
- # because of the compile time circular reference issues
- #FastLED@>=3.3.3
- https://github.com/13rac1/FastLED-STM32
build_flags = -D SMUFF_V5
- -D xDEBUG
+ -D DEBUG
+ -D __HW_DEBUG__
+ # use the next two options only if you're compiling for Marlin MMU2
-D MARLIN2_ONLY
+ -D SOFTRESET
+ # some compiler options to get rid of not really critical messages while compiling
-Wno-unused-variable
-build_unflags =
+ -Wno-format-extra-args
+ -Wno-misleading-indentation
+ # U8G2 library wrappers
+ -Wl,--wrap=u8x8_byte_arduino_2nd_hw_spi,--wrap=__wrap_u8g2_UserInterfaceMessage
+ -std=gnu++14
+ # generate debug information
+ # use -g for default, -g1 for minimal, -g3 for maximal debug information or
+ # -g0 for turning debug information off
+ -g0
+build_unflags = -std=gnu++11
+lib_deps = # SD-Card file system library
+ SdFs
+ # JSON library for the configuration file
+ ArduinoJson@6
+ # LC-Display library
+ U8G2
+ # Rotary-Encoder library
+ #https://github.com/Den-W/encoder.git
+ #Free memory library
+ https://github.com/McNeight/MemoryFree
+ # FastLED library - use fork FastLED-STM32 instead of original one
+ # because of the compile time circular reference issues
+ #FastLED@>=3.3.3
+ https://github.com/13rac1/FastLED-STM32
+
+
#
# Please note: From version 2.x the 8-bit ATMega is
@@ -43,11 +97,11 @@ build_unflags =
platform = atmelavr
framework = arduino
board = megaatmega2560
+lib_deps = ${common.lib_deps}
build_flags = -D __BRD_I3_MINI
-D __AVR__
-I include/Wanhao_i3_mini
-build_unflags = $(common.build_unflags)
-lib_deps = ${common.lib_deps}
+build_unflags = ${common.build_unflags}
upload_port = COM[35]
monitor_speed = 57600
@@ -57,22 +111,20 @@ monitor_speed = 57600
# This is a specific controller board built for the SMuFF
# based on a ESP32 microcontroller.
#
-# For more information about it visit: https://{_smuff_esp32_controller_board_website_}.com
+# For more information about it visit: https://sites.google.com/view/the-smuff/ESP32-Board
#
[env:SMUFF_ESP32]
platform = espressif32
framework = arduino
board = esp32doit-devkit-v1
-build_flags = -D __BRD_ESP32
- -D __ESP32__
- -D __xDEBUG_BT__
- -D USE_TWI_DISPLAY
- -D USE_FASTLED_BACKLIGHT
- -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
- -I include/ESP32
- -Wl,--wrap=__wrap_u8g2_UserInterfaceMessage
lib_deps = https://github.com/lbernstone/Tone.git
${common.lib_deps}
+build_flags = ${display.build_flags}
+ -D __BRD_ESP32
+ -D __ESP32__
+ #-D __DEBUG_BT__
+ -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
+ -I include/ESP32
upload_port = COM[3]
monitor_speed = 115200
board_build.partitions = custompart.csv
@@ -80,65 +132,93 @@ board_build.partitions = custompart.csv
#
# BIGTREETECH SKR MINI V1.1
+#
+# IT'S NOT RECOMMENDED USING THIS ENV ANYMORE SINCE
+# IT WILL OVERWRITE THE FACTORY BOOTLOADER.
+# PLEASE USE BIGTREE_SKR_MINI_SD INSTEAD AND FLASH
+# THE FIRMWARE FROM SD-CARD!
#
-[env:BIGTREE_SKR_MINI]
-platform = ststm32
-framework = arduino
-board = genericSTM32F103RC
-board_build.core= maple
-build_flags = ${common.build_flags}
- -std=gnu++14
- -g
- -I include/SKR_mini
- -D __BRD_SKR_MINI
- -D __STM32F1__
- -D USE_TWI_DISPLAY
- -D USE_FASTLED_BACKLIGHT
- -D ENABLE_USB_SERIAL
- -D USBD_USE_CDC
- -D USBCON
- # Vendor STM (hardcoded to 0x1eaf in usb_cdcadm.c)
- #-D LEAFLABS_ID_VENDOR=0x0483
- # Product Virtual COM Port (hardcoded to 0x0004 in usb_cdcacm.c)
- #-D MAPLE_ID_PRODUCT=0x5740
- #-D HAL_PCD_MODULE_ENABLED
- -Wl,--wrap=u8x8_byte_arduino_2nd_hw_spi,--wrap=__wrap_u8g2_UserInterfaceMessage
-build_unflags = -std=gnu++11 $(common.build_unflags)
-lib_deps = ${common.lib_deps}
-monitor_speed = 115200
-upload_protocol = stlink
+#[env:BIGTREE_SKR_MINI]
+#platform = ststm32
+#framework = arduino
+#board = genericSTM32F103RC
+#board_build.core= maple
+#lib_deps = ${common.lib_deps}
+#build_flags = ${common.build_flags}
+# ${display.build_flags}
+# ${USB.build_flags}
+# -I include/SKR_mini
+# -D __BRD_SKR_MINI
+# -D __STM32F1__
+#build_unflags = ${common.build_unflags}
+#monitor_speed = 115200
+#upload_protocol = stlink
#upload_protocol = dfu
-debug_tool = stlink
+#debug_tool = stlink
#
-# BIGTREETECH SKR MINI V1.1 (flashing through SDcard, using the default bootloader)
+# BIGTREETECH SKR MINI V1.1 (flashing through SD-Card, using the default bootloader)
#
[env:BIGTREE_SKR_MINI_SD]
platform = ststm32
framework = arduino
board = genericSTM32F103RC
board_build.core = maple
+lib_deps = ${common.lib_deps}
+ ${TMC.lib_deps}
build_flags = ${common.build_flags}
- -std=gnu++14
- -g
+ ${display.build_flags}
+ ${USB.build_flags}
+ ${TMC.build_flags}
-I include/SKR_mini
-D __BRD_SKR_MINI
-D __STM32F1__
- -D SOFTRESET
- #-D USE_ANET_DISPLAY
- #-D USE_MINI12864_PANEL_V21
- #-D USE_FASTLED_BACKLIGHT
- -D ENABLE_USB_SERIAL
- -D USBD_USE_CDC
- -D USBCON
- #-D USBD_VID=0x1EAF
- #-D USB_MANUFACTURER="LeafLabs"
- #-D USB_PRODUCT="MAPLE R3"
- -Wl,--wrap=u8x8_byte_arduino_2nd_hw_spi,--wrap=__wrap_u8g2_UserInterfaceMessage
-build_unflags = -std=gnu++11 $(common.build_unflags)
+build_unflags = ${common.build_unflags}
extra_scripts = include/SKR_mini/STM32F103RC_SKR_MINI.py
board_build.ldscript = include/SKR_mini/STM32F103RC_SKR_MINI_256K.ld
+
+#
+# BIGTREETECH SKR MINI E3 V1.2 (flashing through SD-Card, using the default bootloader)
+#
+[env:BIGTREE_SKR_MINI_E3_SD]
+platform = ststm32
+framework = arduino
+board = genericSTM32F103RC
+board_build.core = maple
lib_deps = ${common.lib_deps}
+ ${TMC.lib_deps}
+build_flags = ${common.build_flags}
+ ${display.build_flags}
+ ${USB.build_flags}
+ ${TMC.build_flags}
+ -I include/SKR_mini_E3
+ -D __BRD_SKR_MINI_E3
+ -D __STM32F1__
+build_unflags = ${common.build_unflags}
+extra_scripts = include/SKR_mini/STM32F103RC_SKR_MINI.py
+board_build.ldscript = include/SKR_mini/STM32F103RC_SKR_MINI_256K.ld
+
+#
+# BIGTREETECH SKR MINI E3-DIP V1.1 (flashing through SD-Card, using the default bootloader)
+#
+[env:BIGTREE_SKR_MINI_E3DIP_SD]
+platform = ststm32
+framework = arduino
+board = genericSTM32F103RC
+board_build.core = maple
+lib_deps = ${common.lib_deps}
+ ${TMC.lib_deps}
+build_flags = ${common.build_flags}
+ ${display.build_flags}
+ ${USB.build_flags}
+ ${TMC.build_flags}
+ -I include/SKR_mini_E3DIP
+ -D __BRD_SKR_MINI_E3DIP
+ -D __STM32F1__
+build_unflags = ${common.build_unflags}
+extra_scripts = include/SKR_mini/STM32F103RC_SKR_MINI.py
+board_build.ldscript = include/SKR_mini/STM32F103RC_SKR_MINI_256K.ld
+
# !!! DO NOT USE - EXPERIMENTAL !!!
# Will fail to compile because of the lacking
@@ -147,47 +227,22 @@ lib_deps = ${common.lib_deps}
# BIGTREETECH SKR 1.3
#
[env:BIGTREE_SKR_13]
-platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/master.zip
+platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.3.zip
framework = arduino
board = nxp_lpc1768
+lib_deps = https://github.com/p3p/pio-framework-arduino-lpc176x.git
+ ${common.lib_deps}
build_flags = ${common.build_flags}
- -g
+ ${display.build_flags}
-I include/SKR_13
-D __BRD_SKR_13
-D __NXP__
- -D USE_TWI_DISPLAY
-build_unflags = $(common.build_unflags)
+build_unflags = ${common.build_unflags}
lib_ldf_mode = off
lib_compat_mode = strict
-lib_deps = https://github.com/p3p/pio-framework-arduino-lpc176x.git
- ${common.lib_deps}
monitor_speed = 250000
upload_port = COM1
-#
-# FYSETC AIO II v3.2
-#
-[env:FYSETC_AIOII]
-platform = ststm32
-framework = arduino
-board = genericSTM32F103RC
-board_build.core = maple
-platform_packages = tool-stm32duino
-build_flags = ${common.build_flags}
- -std=gnu++14
- -g
- -I include/FYSETC_AIOII
- -D __BRD_FYSETC_AIOII
- -D __STM32F1__
- -D USE_RGB_BACKLIGHT
- -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
- -D HAL_PCD_MODULE_ENABLED
-build_unflags = -std=gnu++11 $(common.build_unflags)
-extra_scripts = include/FYSETC_AIOII/FYSETC_AIOII.py
-lib_deps = ${common.lib_deps}
-debug_tool = stlink
-upload_protocol = serial
-
#
# FYSETC AIO II v3.2 (flashing through SDcard, using FYSECT STM32F103 bootloader)
# https://github.com/FYSETC/Bootloader-STM32F103
@@ -197,16 +252,12 @@ platform = ststm32
framework = arduino
board = genericSTM32F103RC
board_build.core = maple
+lib_deps = ${common.lib_deps}
build_flags = ${common.build_flags}
- -std=gnu++14
- -g
+ ${USB.build_flags}
-I include/FYSETC_AIOII
-D __BRD_FYSETC_AIOII
-D __STM32F1__
- -D SOFTRESET
-D USE_RGB_BACKLIGHT
- -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
- -D HAL_PCD_MODULE_ENABLED
-build_unflags = -std=gnu++11 $(common.build_unflags)
+build_unflags = ${common.build_unflags}
extra_scripts = include/FYSETC_AIOII/FYSETC_AIOII_SD.py
-lib_deps = ${common.lib_deps}
diff --git a/src/ClickEncoder.cpp b/src/ClickEncoder.cpp
index b331cb8..e0a0749 100644
--- a/src/ClickEncoder.cpp
+++ b/src/ClickEncoder.cpp
@@ -11,6 +11,9 @@
#include "ClickEncoder.h"
+extern void __debug(const char* fmt, ...);
+extern void encoderBeep(int);
+
// ----------------------------------------------------------------------------
// Button configuration (values for 1ms timer service calls)
//
@@ -56,6 +59,7 @@ ClickEncoder::ClickEncoder(uint8_t A, uint8_t B, uint8_t BTN, uint8_t stepsPerNo
pinB = B;
pinBTN = BTN;
pinsActive = active;
+ enableSound = false;
#if defined (__STM32F1__)
WiringPinMode configType = (pinsActive == LOW) ? INPUT_PULLUP : INPUT_PULLDOWN;
@@ -116,7 +120,6 @@ void ClickEncoder::service(void)
if (digitalRead(pinB) == pinsActive) {
curr ^= 1;
}
-
int8_t diff = last - curr;
if (diff & 1) { // bit 0 = step
@@ -195,17 +198,19 @@ int16_t ClickEncoder::getValue(void)
#else
cli();
#endif
+
val = delta;
if (steps == 2) delta = val & 1;
else if (steps == 4) delta = val & 3;
else delta = 0; // default to 1 step per notch
+
#if defined (__STM32F1__)
interrupts();
#else
sei();
#endif
-
+
if (steps == 4) val >>= 2;
if (steps == 2) val >>= 1;
diff --git a/src/Config.cpp b/src/Config.cpp
index e5627f0..47dcca8 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -27,7 +27,7 @@
SdFs SD;
#if defined(__STM32F1__)
-const size_t capacity = 2400;
+const size_t capacity = 3000;
#elif defined(__ESP32__)
const size_t capacity = 4800; // since the ESP32 has more memory, we can do this
#else
@@ -94,6 +94,17 @@ void readConfig()
smuffConfig.endstopTrigger_X = jsonDoc[selector][endstopTrig];
smuffConfig.stepDelay_X = jsonDoc[selector][stepDelay];
smuffConfig.maxSpeedHS_X = jsonDoc[selector][maxSpeedHS];
+ smuffConfig.stepperPower[SELECTOR] = jsonDoc[selector]["Power"];
+ smuffConfig.stepperMode[SELECTOR] = jsonDoc[selector]["Mode"];
+ smuffConfig.stepperRSense[SELECTOR] = jsonDoc[selector]["RSense"];
+ smuffConfig.stepperMicrosteps[SELECTOR] = jsonDoc[selector]["Microsteps"];
+ smuffConfig.stepperStall[SELECTOR] = jsonDoc[selector]["Stall"];
+ smuffConfig.stepperCSmin[SELECTOR] = jsonDoc[selector]["CoolStepMin"];
+ smuffConfig.stepperCSmax[SELECTOR] = jsonDoc[selector]["CoolStepMax"];
+ smuffConfig.stepperCSdown[SELECTOR] = jsonDoc[selector]["CoolStepDown"];
+ smuffConfig.stepperAddr[SELECTOR] = jsonDoc[selector]["DriverAddress"];
+ smuffConfig.stepperToff[SELECTOR] = jsonDoc[selector]["TOff"];
+
smuffConfig.stepsPerRevolution_Y= jsonDoc[revolver]["StepsPerRevolution"];
smuffConfig.firstRevolverOffset = jsonDoc[revolver]["Offset"];
smuffConfig.revolverSpacing = smuffConfig.stepsPerRevolution_Y / 10;
@@ -111,6 +122,16 @@ void readConfig()
smuffConfig.revolverOnPos = jsonDoc[revolver]["ServoOnPos"];
smuffConfig.servoCycles1 = jsonDoc[revolver]["Servo1Cycles"];
smuffConfig.servoCycles2 = jsonDoc[revolver]["Servo2Cycles"];
+ smuffConfig.stepperPower[REVOLVER] = jsonDoc[revolver]["Power"];
+ smuffConfig.stepperMode[REVOLVER] = jsonDoc[revolver]["Mode"];
+ smuffConfig.stepperRSense[REVOLVER] = jsonDoc[revolver]["RSense"];
+ smuffConfig.stepperMicrosteps[REVOLVER] = jsonDoc[revolver]["Microsteps"];
+ smuffConfig.stepperStall[REVOLVER] = jsonDoc[revolver]["Stall"];
+ smuffConfig.stepperCSmin[REVOLVER] = jsonDoc[revolver]["CoolStepMin"];
+ smuffConfig.stepperCSmax[REVOLVER] = jsonDoc[revolver]["CoolStepMax"];
+ smuffConfig.stepperCSdown[REVOLVER] = jsonDoc[revolver]["CoolStepDown"];
+ smuffConfig.stepperAddr[REVOLVER] = jsonDoc[revolver]["DriverAddress"];
+ smuffConfig.stepperToff[REVOLVER] = jsonDoc[revolver]["TOff"];
smuffConfig.externalControl_Z = jsonDoc[feeder]["ExternalControl"];
smuffConfig.stepsPerMM_Z = jsonDoc[feeder]["StepsPerMillimeter"];
@@ -135,24 +156,37 @@ void readConfig()
smuffConfig.insertLength = 5;
smuffConfig.maxSpeedHS_Z = jsonDoc[feeder][maxSpeedHS];
smuffConfig.useDuetLaser = jsonDoc[feeder]["DuetLaser"];
+ smuffConfig.isSharedStepper = jsonDoc[feeder]["SharedStepper"];
+ smuffConfig.stepperPower[FEEDER] = jsonDoc[feeder]["Power"];
+ smuffConfig.stepperMode[FEEDER] = jsonDoc[feeder]["Mode"];
+ smuffConfig.stepperRSense[FEEDER] = jsonDoc[feeder]["RSense"];
+ smuffConfig.stepperMicrosteps[FEEDER] = jsonDoc[feeder]["Microsteps"];
+ smuffConfig.stepperStall[FEEDER] = jsonDoc[feeder]["Stall"];
+ smuffConfig.stepperCSmin[FEEDER] = jsonDoc[feeder]["CoolStepMin"];
+ smuffConfig.stepperCSmax[FEEDER] = jsonDoc[feeder]["CoolStepMax"];
+ smuffConfig.stepperCSdown[FEEDER] = jsonDoc[feeder]["CoolStepDown"];
+ smuffConfig.stepperAddr[FEEDER] = jsonDoc[feeder]["DriverAddress"];
+ smuffConfig.stepperToff[FEEDER] = jsonDoc[feeder]["TOff"];
+ smuffConfig.sendPeriodicalStats = jsonDoc["SendPeriodicalStats"];
int contrast = jsonDoc["LCDContrast"];
smuffConfig.lcdContrast = (contrast >= MIN_CONTRAST && contrast <= MAX_CONTRAST) ? contrast : DSP_CONTRAST;
int backlightColor = jsonDoc["BacklightColor"];
smuffConfig.backlightColor = (backlightColor == 0 ? 7 : backlightColor); // set backlight color to white if not set
+ smuffConfig.encoderTickSound = jsonDoc["EncoderTicks"];
smuffConfig.bowdenLength = jsonDoc["BowdenLength"];
smuffConfig.selectorDistance = jsonDoc["SelectorDist"];
int i2cAdr = jsonDoc["I2CAddress"];
smuffConfig.i2cAddress = (i2cAdr > 0 && i2cAdr < 255) ? i2cAdr : I2C_SLAVE_ADDRESS;
smuffConfig.menuAutoClose = jsonDoc["MenuAutoClose"];
- smuffConfig.delayBetweenPulses = jsonDoc["DelayBetweenPulses"];
+ smuffConfig.serial0Baudrate = jsonDoc["Serial0Baudrate"];
smuffConfig.serial1Baudrate = jsonDoc["Serial1Baudrate"];
smuffConfig.serial2Baudrate = jsonDoc["Serial2Baudrate"];
- smuffConfig.serialDueBaudrate = jsonDoc["SerialDueBaudrate"];
+ smuffConfig.serial3Baudrate = jsonDoc["Serial3Baudrate"];
smuffConfig.fanSpeed = jsonDoc["FanSpeed"];
smuffConfig.powerSaveTimeout = jsonDoc["PowerSaveTimeout"];
- smuffConfig.duetDirect = jsonDoc["Duet3DDirect"];
+ smuffConfig.sendActionCmds = jsonDoc["SendActionCmds"];
const char* p1 = jsonDoc["UnloadCommand"];
const char* p2 = jsonDoc["WipeSequence"];
if(p1 != NULL && strlen(p1) > 0) {
@@ -177,7 +211,6 @@ void readConfig()
smuffConfig.servoMinPwm = 550;
if(smuffConfig.servoMaxPwm == 0)
smuffConfig.servoMaxPwm = 2400;
- smuffConfig.sendPeriodicalStats = jsonDoc["SendPeriodicalStats"];
// read materials if running on 32-Bit MCU
#if defined(__STM32F1__) || defined(__ESP32__)
@@ -234,9 +267,10 @@ bool writeConfig(Print* dumpTo)
}
}
JsonObject jsonObj = jsonDoc.to();
+ jsonDoc["Serial0Baudrate"] = smuffConfig.serial0Baudrate;
jsonDoc["Serial1Baudrate"] = smuffConfig.serial1Baudrate;
jsonDoc["Serial2Baudrate"] = smuffConfig.serial2Baudrate;
- jsonDoc["SerialDueBaudrate"] = smuffConfig.serialDueBaudrate;
+ jsonDoc["Serial3Baudrate"] = smuffConfig.serial3Baudrate;
jsonDoc["ToolCount"] = smuffConfig.toolCount;
jsonDoc["BowdenLength"] = smuffConfig.bowdenLength;
jsonDoc["SelectorDist"] = smuffConfig.selectorDistance;
@@ -244,9 +278,8 @@ bool writeConfig(Print* dumpTo)
jsonDoc["I2CAddress"] = smuffConfig.i2cAddress;
jsonDoc["MenuAutoClose"] = smuffConfig.menuAutoClose;
jsonDoc["FanSpeed"] = smuffConfig.fanSpeed;
- jsonDoc["DelayBetweenPulses"] = smuffConfig.delayBetweenPulses;
jsonDoc["PowerSaveTimeout"] = smuffConfig.powerSaveTimeout;
- jsonDoc["Duet3DDirect"] = smuffConfig.duetDirect;
+ jsonDoc["SendActionCmds"] = smuffConfig.sendActionCmds;
jsonDoc["EmulatePrusa"] = smuffConfig.prusaMMU2;
jsonDoc["UnloadCommand"] = smuffConfig.unloadCommand;
jsonDoc["HasPanelDue"] = smuffConfig.hasPanelDue;
@@ -255,6 +288,7 @@ bool writeConfig(Print* dumpTo)
jsonDoc["SendPeriodicalStats"] = smuffConfig.sendPeriodicalStats;
jsonDoc["WipeSequence"] = smuffConfig.wipeSequence;
jsonDoc["BacklightColor"] = smuffConfig.backlightColor;
+ jsonDoc["EncoderTicks"] = smuffConfig.encoderTickSound;
JsonObject node = jsonObj.createNestedObject("Selector");
@@ -267,6 +301,16 @@ bool writeConfig(Print* dumpTo)
node["Acceleration"] = smuffConfig.acceleration_X;
node["InvertDir"] = smuffConfig.invertDir_X;
node["EndstopTrigger"] = smuffConfig.endstopTrigger_X;
+ node["Power"] = smuffConfig.stepperPower[SELECTOR];
+ node["Mode"] = smuffConfig.stepperMode[SELECTOR];
+ node["RSense"] = smuffConfig.stepperRSense[SELECTOR];
+ node["Microsteps"] = smuffConfig.stepperMicrosteps[SELECTOR];
+ node["Stall"] = smuffConfig.stepperStall[SELECTOR];
+ node["CoolStepMin"] = smuffConfig.stepperCSmin[SELECTOR];
+ node["CoolStepMax"] = smuffConfig.stepperCSmax[SELECTOR];
+ node["CoolStepDown"] = smuffConfig.stepperCSdown[SELECTOR];
+ node["DriverAddress"] = smuffConfig.stepperAddr[SELECTOR];
+ node["TOff"] = smuffConfig.stepperToff[SELECTOR];
node = jsonObj.createNestedObject("Revolver");
node["Offset"] = smuffConfig.firstRevolverOffset;
@@ -285,6 +329,16 @@ bool writeConfig(Print* dumpTo)
node["ServoOnPos"] = smuffConfig.revolverOnPos;
node["Servo1Cycles"] = smuffConfig.servoCycles1;
node["Servo2Cycles"] = smuffConfig.servoCycles2;
+ node["Power"] = smuffConfig.stepperPower[REVOLVER];
+ node["Mode"] = smuffConfig.stepperMode[REVOLVER];
+ node["RSense"] = smuffConfig.stepperRSense[REVOLVER];
+ node["Microsteps"] = smuffConfig.stepperMicrosteps[REVOLVER];
+ node["Stall"] = smuffConfig.stepperStall[REVOLVER];
+ node["CoolStepMin"] = smuffConfig.stepperCSmin[REVOLVER];
+ node["CoolStepMax"] = smuffConfig.stepperCSmax[REVOLVER];
+ node["CoolStepDown"] = smuffConfig.stepperCSdown[REVOLVER];
+ node["DriverAddress"] = smuffConfig.stepperAddr[REVOLVER];
+ node["TOff"] = smuffConfig.stepperToff[REVOLVER];
node = jsonObj.createNestedObject("Feeder");
node["ExternalControl"] = smuffConfig.externalControl_Z;
@@ -305,6 +359,18 @@ bool writeConfig(Print* dumpTo)
node["EnableChunks"] = smuffConfig.enableChunks;
node["FeedChunks"] = smuffConfig.feedChunks;
node["InsertLength"] = smuffConfig.insertLength;
+ node["DuetLaser"] = smuffConfig.useDuetLaser;
+ node["SharedStepper"] = smuffConfig.isSharedStepper;
+ node["Power"] = smuffConfig.stepperPower[FEEDER];
+ node["Mode"] = smuffConfig.stepperMode[FEEDER];
+ node["RSense"] = smuffConfig.stepperRSense[FEEDER];
+ node["Microsteps"] = smuffConfig.stepperMicrosteps[FEEDER];
+ node["Stall"] = smuffConfig.stepperStall[FEEDER];
+ node["CoolStepMin"] = smuffConfig.stepperCSmin[FEEDER];
+ node["CoolStepMax"] = smuffConfig.stepperCSmax[FEEDER];
+ node["CoolStepDown"] = smuffConfig.stepperCSdown[FEEDER];
+ node["DriverAddress"] = smuffConfig.stepperAddr[FEEDER];
+ node["TOff"] = smuffConfig.stepperToff[FEEDER];
#if defined(__STM32F1__) || defined(__ESP32__)
node = jsonObj.createNestedObject("Materials");
diff --git a/src/DataStore.cpp b/src/DataStore.cpp
index 0b6061d..f716ff1 100644
--- a/src/DataStore.cpp
+++ b/src/DataStore.cpp
@@ -92,4 +92,23 @@ void recoverStore() {
cfg.close();
}
}
+}
+
+void readTune() {
+#if defined(__ESP32__)
+ if (SD.begin(SDCS_PIN, SD_SCK_MHZ(4))) {
+#else
+ if (SD.begin()) {
+#endif
+ FsFile tune;
+ if (!tune.open(TUNE_FILE)){
+ __debug(PSTR("Tune file '%s' not found!\n"), TUNE_FILE);
+ }
+ else {
+ String tmp = tune.readString();
+ if(tmp.length() > 0)
+ tuneSequence = tmp;
+ tune.close();
+ }
+ }
}
\ No newline at end of file
diff --git a/src/DuetLaserSensor.cpp b/src/DuetLaserSensor.cpp
index f44ddc0..7816d60 100644
--- a/src/DuetLaserSensor.cpp
+++ b/src/DuetLaserSensor.cpp
@@ -21,11 +21,33 @@
extern void __debug(const char* fmt, ...);
+/* ==============================================================================================================================
+ Duet3D laser Sensor Protocol (according to the Duet3D Wiki)
+ P = partity bit
+ ==============================================================================================================================
+ v1 Data word P00S 00pp pppp pppp S = switch open, pppppppppp = 10-bit filament position (50 counts/mm)
+ v1 Error word P010 0000 0000 0000
+ v1 Quality word P10s ssss bbbb bbbb sssss = shutter, bbbbbbbb = brightness
-void DuetLaserSensor::attach(int pin) {
+ v2 Data word P00S 1ppp pppp pppp S = switch open, ppppppppppp = 11-bit filament position (100 counts/mm)
+ v2 Error word P010 0000 0000 eeee eeee = error code, will not be zero
+ v2 Version word P110 0000 vvvv vvvv vvvvvvvv = sensor/firmware version, at least 2
+ v2 Image quality word P110 0001 qqqq qqqq qqqqqqqq = image quality
+ v2 Brightness word P110 0010 bbbb bbbb bbbbbbbb = brightness
+ v2 Shutter word P110 0011 ssss ssss ssssssss = shutter
+ ============================================================================================================================== */
+
+void DuetLaserSensor::attach(int pin, bool v1) {
_pin = pin;
+ _isV1 = v1;
pinMode(_pin, INPUT);
reset();
+ resetPosition();
+}
+
+void DuetLaserSensor::resetPosition() {
+ _position = 0;
+ _positionMM = 0;
}
void DuetLaserSensor::reset() {
@@ -34,19 +56,34 @@ void DuetLaserSensor::reset() {
_bitCnt = 0;
_dataCnt = 0;
_data = 0;
- _lastBit = -1;
- _lastBits = String(_bits);
- _lastStuff = String(_stuff);
- _bits = "";
- _stuff = "";
+ resetBits();
}
+/* Method which reads out the Duet3D laser Sensor.
+ This service method must be called once each milisecond.
+
+ The data is being transmitted from the sensor in the following format:
+
+ Idle state: the line must be be at 0 for at least 8 bit times
+ Start bits: 1 followed by 0
+ Data bits 15, 14, 13, 12
+ Stuffing bit (inverse of bit 12)
+ Data bits 11,10,9,8
+ Stuffing bit (inverse of bit 8)
+ Data bits 7,6,5,4
+ Stuffing bit (inverse of bit 4)
+ Data bits 3,2,1,0
+ Stuffing bit (inverse of bit 0)
+ After the last stuffing bit, the line returns to 0 until the next start bit.
+*/
void DuetLaserSensor::service() {
if(_pin == -1)
return;
+
volatile int _b = digitalRead(_pin);
+ // wait for idle to be signaled (=8 bits low)
if(!_gotIdle) {
- _state = 0x8000;
+ _state = STATE_INIT;
if(_b == LOW) {
_bitCnt++;
}
@@ -54,21 +91,24 @@ void DuetLaserSensor::service() {
if(_bitCnt >= 8) {
_gotIdle = true;
_bitCnt = 0;
+ _state = STATE_IDLE;
}
else {
reset();
}
}
}
+ // wait for startbits
if(_gotIdle && !_gotStartbit) {
- _state = 0x8001;
if(_b == HIGH && _bitCnt == 0) {
_bitCnt++;
+ _state = STATE_WAIT_START;
}
else if(_b == LOW && _bitCnt == 1) {
- _state = 0x8002;
+ _state = STATE_GOT_START;
_gotStartbit = true;
_bitCnt = 19;
+ _pbitCnt = 0;
_dataCnt = 15;
return;
}
@@ -77,96 +117,105 @@ void DuetLaserSensor::service() {
return;
}
}
+ // read data bits
if(_gotIdle && _gotStartbit) {
- _state = 0x8003;
- _bits += _bitCnt%5==0 ? " " : (_b ? "1" : "0");
+ _state = STATE_READING_DATA;
+ /* FOR DEBUGGING ONLY
+ _bits += _bitCnt%5==0 ? " " : (_b ? "1" : "0");
_stuff += _bitCnt%5==0 ? (_b ? "1" : "0") : " ";
+ */
if(_bitCnt%5!=0) {
_data |= (_b<<_dataCnt);
_dataCnt--;
+ _pbitCnt += _b ? 1 : 0; // count all '1's for parity check
}
_bitCnt--;
if(_bitCnt == -1) {
// all bits read
- /*
- volatile int v[4];
- int idx;
- int n;
- for(idx = 0, n=0; idx < 20; idx += 5, n++) {
- const char* p = _bits.substring(idx, idx+4).c_str();
- v[n] = strtol(p, NULL, 2);
- }
- unsigned dataWord = (v[0] << 12) | (v[1] << 8) | (v[2] << 4) | v[3];
- if(_data != dataWord)
- _state = 0x9000;
- else {
- */
- _isValid = false;
- if(_data > 0) {
- _state = 0x8005;
- uint8_t data8 = (uint8_t)((_data >> 8) ^ _data);
- data8 ^= (data8 >> 4);
- data8 ^= (data8 >> 2);
- data8 ^= (data8 >> 1);
- if ((data8 & 1) != 0)
- {
- _error = 0x8000;
- _state = 0x8006;
- reset();
- }
- else {
- _state = 0x8007;
- _isValid = true;
- int cmd = (_data & 0x6000)>>13;
- switch(cmd) {
- case 0:
- _state = 0x8008;
- _switch = (_data & 0x1000) == 0;
- _positionMM = _isV1 ? (double)((_data & 0x03ff)) * 0.02f : (double)((_data & 0x07ff)) *0.01f;
- _position = _isV1 ? (_data & 0x03ff) : (_data & 0x07ff);
- break;
- case 1:
- _state = 0x8009;
- _error = _data & 0x0f;
- break;
- case 2:
- _state = 0x800A;
- _isV1 = true;
+ _isValid = false;
+ if(_data > 0) {
+ _state = STATE_GOT_ALL_BITS;
+ _error = E_NONE;
+ // check parity
+ if (_pbitCnt % 2 != (uint8_t)(_data & 0x8000) >> 15)
+ {
+ _error = E_WRONG_PARITY;
+ _state = STATE_PARITY_ERROR;
+ reset();
+ }
+ else {
+ _state = STATE_PARITY_OK;
+ int cmd = (_data & 0x6000)>>13;
+ switch(cmd) {
+ case 0: {
+ _state = STATE_GOT_POSITION;
+ _switch = (_data & 0x1000) == 0;
+ _prevpos = _position;
+ int32_t pos = _isV1 ? (_data & 0x03ff) : (_data & 0x07ff);
+
+ if(pos == _prevpos) {
+ _dir = DIR_NONE;
+ }
+ else if(pos < _prevpos) {
+ _dir = (pos - _prevpos < 0) ? DIR_RETRACT : DIR_EXTRUDE;
+ }
+ else if(pos > _prevpos) {
+ _dir = (pos - _prevpos > 0) ? DIR_EXTRUDE : DIR_RETRACT;
+ }
+ _position = pos;
+ _positionMM = _isV1 ? (double)_position * 0.02f : (double)_position * 0.01f;
+ _hasMoved = _prevpos != _position;
+ }
+ break;
+ case 1:
+ _state = STATE_GOT_ERROR_MSG;
+ _sensorError = _data & 0x0f;
+ break;
+ case 2:
+ if(_isV1) {
+ _state = STATE_GOT_QUALITY_V1;
_version = 1;
_shutter = (_data & 0x1f00) >> 8;
_brightness = (_data & 0x00ff);
- break;
- case 3:
- {
- _state = 0x800B;
- int opt = (_data & 0x0f00) >> 8;
- switch(opt) {
- case 0:
- _version = _data & 0xff;
- break;
- case 1:
- _quality = _data & 0xff;
- break;
- case 2:
- _brightness = _data & 0xff;
- break;
- case 3:
- _shutter = _data & 0xff;
- break;
- default:
- _error = 0x8001;
- break;
- }
+ }
+ else {
+ _state = STATE_INVALID;
+ _error = E_INVALID_VERSION;
+ }
+ break;
+ case 3:
+ {
+ _state = STATE_GOT_QUALITY_V2;
+ _error = E_NONE;
+ int opt = (_data & 0x0f00) >> 8;
+ switch(opt) {
+ case 0:
+ _version = _data & 0xff;
+ break;
+ case 1:
+ _quality = _data & 0xff;
+ break;
+ case 2:
+ _brightness = _data & 0xff;
+ break;
+ case 3:
+ _shutter = _data & 0xff;
+ break;
+ default:
+ _error = E_INVALID_QUALITY;
+ break;
}
- break;
- default:
- _state = 0x800C;
- _error = 0x8002;
- break;
- }
+ }
+ break;
+ default:
+ _state = STATE_INVALID;
+ _error = E_INVALID_DATA;
+ break;
}
+ if(_error == E_NONE)
+ _isValid = true;
}
- //}
+ }
reset();
}
}
diff --git a/src/GCodes.cpp b/src/GCodes.cpp
index 21891e4..4f964d3 100644
--- a/src/GCodes.cpp
+++ b/src/GCodes.cpp
@@ -23,23 +23,7 @@
#include
#include "SMuFF.h"
-#include "ZTimerLib.h"
-#include "ZStepperLib.h"
-#include "ZServo.h"
-#include "ZPortExpander.h"
#include "GCodes.h"
-#ifdef __STM32F1__
-#include "libmaple/nvic.h"
-#endif
-#ifdef __ESP32__
-#include "Tone32.h"
-#endif
-
-extern ZStepper steppers[];
-extern ZServo servo;
-#if defined(__ESP32__)
-extern ZPortExpander portEx;
-#endif
char* S_Param = (char*)"S";
char* P_Param = (char*)"P";
@@ -71,6 +55,7 @@ GCodeFunctions gCodeFuncsM[] = {
{ 220, dummy },
{ 221, dummy },
+ { 17, M17 },
{ 18, M18 },
{ 20, M20 },
{ 42, M42 },
@@ -84,6 +69,7 @@ GCodeFunctions gCodeFuncsM[] = {
{ 115, M115 },
{ 117, M117 },
{ 119, M119 },
+ { 122, M122 },
{ 150, M150 },
{ 201, M201 },
{ 203, M203 },
@@ -92,11 +78,16 @@ GCodeFunctions gCodeFuncsM[] = {
{ 250, M250 },
{ 280, M280 },
{ 300, M300 },
+ { 350, M350 },
+ { 412, M412 },
{ 500, M500 },
{ 503, M503 },
+ { 569, M569 },
{ 575, M575 },
{ 700, M700 },
{ 701, M701 },
+ { 906, M906 },
+ { 914, M914 },
{ 999, M999 },
{ 2000, M2000 },
{ 2001, M2001 },
@@ -128,6 +119,27 @@ bool dummy(const char* msg, String buf, int serial) {
return true;
}
+/*
+ Deviating from the GCode standard, this method is used for switching the Feeder stepper motor
+ from internal (SMuFF) to external (3D-Printer).
+*/
+bool M17(const char* msg, String buf, int serial) {
+ bool stat = true;
+ int stepper;
+ if(buf.indexOf(E_Param) != -1) {
+ switchFeederStepper(EXTERNAL);
+ }
+ else if(buf.indexOf(I_Param) != -1) {
+ switchFeederStepper(INTERNAL);
+ }
+ else {
+ sprintf_P(tmp, "echo: %s\n", smuffConfig.externalStepper ? P_External : P_Internal);
+ printResponse(tmp, serial);
+ }
+ printResponse(msg, serial);
+ return stat;
+}
+
bool M18(const char* msg, String buf, int serial) {
bool stat = true;
printResponse(msg, serial);
@@ -274,7 +286,7 @@ bool M106(const char* msg, String buf, int serial) {
if((param = getParam(buf, S_Param)) == -1) {
param = 100;
}
- __debug(PSTR("Fan speed: %d%%"), param);
+ //__debug(PSTR("Fan speed: %d%%"), param);
#ifdef __STM32F1__
pwmWrite(FAN_PIN, map(param, 0, 100, 0, 65535));
#elif __ESP32__
@@ -345,10 +357,333 @@ bool M119(const char* msg, String buf, int serial) {
return true;
}
+/*
+ Print out all infomration available on the TMC steppers
+ if there are any configured.
+
+ Looks a bit messy and could have been done quite a bit more
+ modular, although, as you might need it only once or twice
+ it's ok for now.
+*/
+bool M122(const char* msg, String buf, int serial) {
+ char dbg[20];
+ printResponse(msg, serial);
+ TMC2209Stepper* drivers[] = { driverX, driverY, driverZ, driverE };
+
+ if(driverX != NULL) {
+ steppers[SELECTOR].setEnabled(true);
+ }
+ if(driverY != NULL) {
+ steppers[REVOLVER].setEnabled(true);
+ }
+ if(driverZ != NULL) {
+ steppers[FEEDER].setEnabled(true);
+ }
+ if(driverE != NULL) {
+ steppers[FEEDER].setEnabled(true);
+ }
+ char spacer[] = {" "};
+ char eol[] = {"\n"};
+
+ printResponseP(P_TMC_Setup00, serial);
+ // IC-Version
+ printResponseP(P_TMC_Setup01, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", String(drivers[i]->version()-0x20).c_str());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Enabled
+ printResponseP(P_TMC_Setup02, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->isEnabled() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Power set
+ printResponseP(P_TMC_Setup03, serial);
+ for(int i=0; i<2; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", smuffConfig.stepperPower[i]);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Power RMS
+ printResponseP(P_TMC_Setup03a, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->rms_current());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Microsteps
+ printResponseP(P_TMC_Setup04, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->microsteps());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // TOff
+ printResponseP(P_TMC_Setup05, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->toff());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Blank Time
+ printResponseP(P_TMC_Setup06, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->blank_time());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // PDN/UART
+ printResponseP(P_TMC_Setup07, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->pdn_uart() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // MS1 / MS2
+ printResponseP(P_TMC_Setup08, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, " %1d%1d ", drivers[i]->ms2(), drivers[i]->ms1());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Diag
+ printResponseP(P_TMC_Setup09, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->diag() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // StallGuard THRS
+ printResponseP(P_TMC_Setup10, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->SGTHRS());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // StallGuard Result
+ printResponseP(P_TMC_Setup11, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->SG_RESULT());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // semin
+ printResponseP(P_TMC_Setup12, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->semin());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // semax
+ printResponseP(P_TMC_Setup13, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->semax());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // sedn
+ printResponseP(P_TMC_Setup14, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4d ", drivers[i]->sedn());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // CoolStep THRS
+ printResponseP(P_TMC_Setup15, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%08lx ", drivers[i]->TCOOLTHRS());
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ printResponse(eol, serial);
+
+ // ---- STATUS ----
+ printResponseP(P_TMC_Status00, serial);
+ // Mode
+ printResponseP(P_TMC_Status01, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%-7s ", drivers[i]->stealth() ? P_Stealth : P_Spread);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Standstill
+ printResponseP(P_TMC_Status02, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->stst() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase A Open
+ printResponseP(P_TMC_Status03, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->ola() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase B Open
+ printResponseP(P_TMC_Status04, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->olb() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase A Short to GND
+ printResponseP(P_TMC_Status05, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->s2ga() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase B Short to GND
+ printResponseP(P_TMC_Status06, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->s2gb() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase A Short MOSFET
+ printResponseP(P_TMC_Status07, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->s2vsa() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Phase B Short MOSFET
+ printResponseP(P_TMC_Status08, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->s2vsb() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Overtemp. Warning
+ printResponseP(P_TMC_Status09, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->otpw() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ // Overtemp.
+ printResponseP(P_TMC_Status10, serial);
+ for(int i=0; i<3; i++) {
+ if(drivers[i] != NULL) {
+ sprintf(dbg, "%4s ", drivers[i]->ot() ? P_Yes : P_No);
+ printResponse(dbg, serial);
+ }
+ else
+ printResponse(spacer, serial);
+ }
+ printResponse(eol, serial);
+ return true;
+}
+
bool M150(const char* msg, String buf, int serial) {
int red=0, green=0, blue=0, index=-1, intensity = 255, colorNdx=-1;
printResponse(msg, serial);
+#if defined(USE_FASTLED_BACKLIGHT)
if(NEOPIXEL_PIN == -1)
return false;
@@ -385,6 +720,9 @@ bool M150(const char* msg, String buf, int serial) {
setFastLED(index, color);
}
return true;
+#else
+ return false;
+#endif
}
bool M201(const char* msg, String buf, int serial) {
@@ -480,24 +818,30 @@ bool M203(const char* msg, String buf, int serial) {
bool M205(const char* msg, String buf, int serial) {
bool stat = true;
printResponse(msg, serial);
- if(buf.length()==0) {
- //printAdvancedSettings(serial);
- return stat;
- }
+
char cmd[80];
+ char tmp[50];
if((param = getParamString(buf, P_Param, cmd, sizeof(cmd))) != -1) {
+ float fParam = getParamF(buf, S_Param);
if((param = getParam(buf, S_Param)) != -1) {
- if(strcmp_P(cmd, PSTR("BowdenLength"))==0) {
- smuffConfig.bowdenLength = param;
+ if(strcmp_P(cmd, PSTR("ToolCount"))==0) {
+ if(param >= 1 && param <= MAX_TOOLS)
+ smuffConfig.toolCount = param;
+ }
+ else if(strcmp_P(cmd, PSTR("ToolSpacing"))==0) {
+ smuffConfig.toolSpacing = fParam;
+ }
+ else if(strcmp_P(cmd, PSTR("BowdenLength"))==0) {
+ smuffConfig.bowdenLength = fParam;
}
else if(strcmp_P(cmd, PSTR("InsertLength"))==0) {
- smuffConfig.insertLength = param;
+ smuffConfig.insertLength = fParam;
}
else if(strcmp_P(cmd, PSTR("ReinforceLength"))==0) {
- smuffConfig.reinforceLength = param;
+ smuffConfig.reinforceLength = fParam;
}
else if(strcmp_P(cmd, PSTR("SelectorDist"))==0) {
- smuffConfig.selectorDistance = param;
+ smuffConfig.selectorDistance = fParam;
}
else if(strcmp_P(cmd, PSTR("HomeAfterFeed"))==0) {
smuffConfig.homeAfterFeed = (param > 0);
@@ -517,6 +861,212 @@ bool M205(const char* msg, String buf, int serial) {
else if(strcmp_P(cmd, PSTR("ServoClosed"))==0) {
smuffConfig.revolverOnPos = param;
}
+ else if(strcmp_P(cmd, PSTR("WipeSequence"))==0) {
+ getParamString(cmd, S_Param, tmp, sizeof(smuffConfig.wipeSequence));
+ #if defined(__STM32F1__) || defined(__ESP32__)
+ strncpy(smuffConfig.wipeSequence, tmp, sizeof(smuffConfig.wipeSequence));
+ #else
+ strlcpy(smuffConfig.wipeSequence, tmp, sizeof(smuffConfig.wipeSequence));
+ #endif
+ }
+ else if(strcmp_P(cmd, PSTR("StepsPerMM"))==0) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepsPerMM_X = param;
+ steppers[SELECTOR].setStepsPerMM(param);
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepsPerMM_Z = param;
+ steppers[FEEDER].setStepsPerMM(param);
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("StepsPerRev"))==0) {
+ smuffConfig.stepsPerRevolution_Y = param;
+ steppers[REVOLVER].setStepsPerDegree(param);
+ }
+ else if(strcmp_P(cmd, PSTR("InvertDir"))==0) {
+ if(hasParam(buf, X_Param))
+ smuffConfig.invertDir_X = (param > 0);
+ if(hasParam(buf, Y_Param))
+ smuffConfig.invertDir_Y = (param > 0);
+ if(hasParam(buf, Z_Param))
+ smuffConfig.invertDir_Z = (param > 0);
+ }
+ else if(strcmp_P(cmd, PSTR("EndstopTrigger"))==0) {
+ if(hasParam(buf, X_Param))
+ smuffConfig.endstopTrigger_X = param;
+ if(hasParam(buf, Y_Param))
+ smuffConfig.endstopTrigger_Y = param;
+ if(hasParam(buf, Z_Param))
+ smuffConfig.endstopTrigger_Z = param;
+ }
+ else if(strcmp_P(cmd, PSTR("MenuAutoClose"))==0) {
+ smuffConfig.menuAutoClose = param;
+ }
+ else if(strcmp_P(cmd, PSTR("PowerSaveTimeout"))==0) {
+ smuffConfig.powerSaveTimeout = param;
+ }
+ else if(strcmp_P(cmd, PSTR("SendActionCmds"))==0) {
+ smuffConfig.sendActionCmds = (param > 0);
+ }
+ else if(strcmp_P(cmd, PSTR("BacklightColor"))==0) {
+ if(param >=0 && param <=15)
+ smuffConfig.backlightColor = param;
+ }
+ else if(strcmp_P(cmd, PSTR("HasPanelDue"))==0) {
+ smuffConfig.hasPanelDue = (param > 0);
+ }
+ else if(strcmp_P(cmd, PSTR("EncoderTicks"))==0) {
+ smuffConfig.encoderTickSound = (param > 0);
+ }
+ else if(strcmp_P(cmd, PSTR("SendPeriodicalStats"))==0) {
+ smuffConfig.sendPeriodicalStats = (param > 0);
+ }
+ else if(strcmp_P(cmd, PSTR("Power"))==0) {
+ if(param >=0 && param <= 1400) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperPower[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperPower[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperPower[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("RSense"))==0) {
+ if(fParam >= 0 && fParam <= 1.0) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperRSense[SELECTOR] = fParam;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperPower[REVOLVER] = fParam;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperPower[FEEDER] = fParam;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("Mode"))==0) {
+ if(param >=0 && param <= 2) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperMode[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperMode[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperMode[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("Microsteps"))==0) {
+ if(param == 1 || param == 2 || param == 4 || param == 8 || param == 16 || param == 32 || param == 64 || param == 128) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperMicrosteps[SELECTOR] = param;
+ if(driverX != NULL)
+ driverX->microsteps(param);
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperMicrosteps[REVOLVER] = param;
+ if(driverY != NULL)
+ driverY->microsteps(param);
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperMicrosteps[FEEDER] = param;
+ if(driverZ != NULL)
+ driverZ->microsteps(param);
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("Stall"))==0) {
+ if(param >=0 && param <=255) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperStall[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperStall[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperStall[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("CoolStepMin"))==0) {
+ if(param >=0 && param <= 15) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperCSmin[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperCSmin[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperCSmin[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("CoolStepMax"))==0) {
+ if(param >=0 && param <= 15) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperCSmax[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperCSmax[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperCSmax[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("CoolStepDown"))==0) {
+ if(param >=0 && param <= 15) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperCSdown[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperCSdown[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperCSdown[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("DriverAddress"))==0) {
+ if(param >=0 && param <= 3) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperAddr[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperAddr[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperAddr[FEEDER] = param;
+ }
+ }
+ }
+ else if(strcmp_P(cmd, PSTR("TOff"))==0) {
+ if(param >=0 && param <= 15) {
+ if(hasParam(buf, X_Param)) {
+ smuffConfig.stepperAddr[SELECTOR] = param;
+ }
+ if(hasParam(buf, Y_Param)) {
+ smuffConfig.stepperAddr[REVOLVER] = param;
+ }
+ if(hasParam(buf, Z_Param)) {
+ smuffConfig.stepperAddr[FEEDER] = param;
+ }
+ }
+ }
+ else {
+ sprintf_P(tmp, P_UnknownParam, cmd);
+ printResponse(tmp, serial);
+ stat = false;
+ }
+ }
+ else {
+ sprintf_P(tmp, P_NoValue, cmd);
+ printResponse(tmp, serial);
+ stat = false;
}
}
return stat;
@@ -592,7 +1142,7 @@ bool M280(const char* msg, String buf, int serial) {
stat = true;
}
if((param = getParam(buf, T_Param)) != -1) {
- for(int i=10; i <= 170; i += 10) {
+ for(int i=0; i <= 180; i += 10) {
setServoPos(servoIndex, i);
sprintf(tmp,"Servo pos.: %d deg\n", i);
printResponse(tmp, serial);
@@ -607,6 +1157,7 @@ bool M280(const char* msg, String buf, int serial) {
bool M300(const char* msg, String buf, int serial) {
bool stat = true;
printResponse(msg, serial);
+ char sequence[500];
if((param = getParam(buf, S_Param)) != -1) {
int frequency = param;
if((param = getParam(buf, P_Param)) != -1) {
@@ -615,11 +1166,68 @@ bool M300(const char* msg, String buf, int serial) {
else
stat = false;
}
+ else if(getParamString(buf, T_Param, sequence, 499)) {
+ playSequence(sequence);
+ }
else
stat = false;
return stat;
}
+bool M350(const char* msg, String buf, int serial) {
+ bool stat = true;
+ printResponse(msg, serial);
+ if((param = getParam(buf, X_Param)) != -1) {
+ if(param==1 || param==2 || param==4 || param==8 || param==16 || param==32 || param==64 || param==128) {
+ smuffConfig.stepperMicrosteps[SELECTOR] = param;
+ steppers[SELECTOR].setEnabled(true);
+ if(driverX != NULL)
+ driverX->microsteps(param);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Y_Param)) != -1) {
+ if(param==1 || param==2 || param==4 || param==8 || param==16 || param==32 || param==64 || param==128) {
+ smuffConfig.stepperMicrosteps[REVOLVER] = param;
+ steppers[REVOLVER].setEnabled(true);
+ if(driverY != NULL)
+ driverY->microsteps(param);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Z_Param)) != -1) {
+ if(param==1 || param==2 || param==4 || param==8 || param==16 || param==32 || param==64 || param==128) {
+ smuffConfig.stepperMicrosteps[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverZ != NULL)
+ driverZ->microsteps(param);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, E_Param)) != -1) {
+ if(param==1 || param==2 || param==4 || param==8 || param==16 || param==32 || param==64 || param==128) {
+ smuffConfig.stepperMicrosteps[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverE != NULL)
+ driverE->microsteps(param);
+ }
+ else stat = false;
+ }
+ return stat;
+}
+
+bool M412(const char* msg, String buf, int serial) {
+ bool stat = true;
+ printResponse(msg, serial);
+ if((param = getParam(buf, S_Param)) != -1) {
+ smuffConfig.runoutDetection = param == 1;
+ }
+ else {
+ printResponseP(smuffConfig.runoutDetection ? P_On : P_Off ,serial);
+ }
+ return stat;
+}
+
bool M500(const char* msg, String buf, int serial) {
printResponse(msg, serial);
return writeConfig();
@@ -639,12 +1247,120 @@ bool M503(const char* msg, String buf, int serial) {
case 2:
_print = &Serial2;
break;
+ #if !defined(__ESP32__)
+ case 3:
+ _print = &Serial3;
+ break;
+ #endif
default:
break;
}
return writeConfig(_print);
}
+bool M569(const char* msg, String buf, int serial) {
+ bool stat = true;
+ char tmp[128];
+ printResponse(msg, serial);
+ if((param = getParam(buf, X_Param)) != -1) {
+ if(param >= 0 && param <= 1) {
+ steppers[SELECTOR].setEnabled(true);
+ if(driverX != NULL) {
+ smuffConfig.stepperSpread[SELECTOR] = (param > 0);
+ driverX->en_spreadCycle(param > 0);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ else {
+ if(buf.indexOf(X_Param) != -1) {
+ steppers[SELECTOR].setEnabled(true);
+ if(driverX != NULL) {
+ sprintf_P(tmp, P_StepperMode, "X (Selector)", driverX->stealth() ? P_Stealth : P_Spread);
+ printResponse(tmp, serial);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ }
+
+ if((param = getParam(buf, Y_Param)) != -1) {
+ if(param >= 0 && param <= 1) {
+ steppers[REVOLVER].setEnabled(true);
+ if(driverY != NULL){
+ smuffConfig.stepperSpread[REVOLVER] = (param > 0);
+ driverY->en_spreadCycle(param > 0);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ else {
+ if(buf.indexOf(Y_Param) != -1) {
+ steppers[REVOLVER].setEnabled(true);
+ if(driverY != NULL) {
+ sprintf_P(tmp, P_StepperMode, "Y (Revolver)", driverY->stealth() ? P_Stealth : P_Spread);
+ printResponse(tmp, serial);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ }
+
+ if((param = getParam(buf, Z_Param)) != -1) {
+ if(param >= 0 && param <= 1) {
+ steppers[FEEDER].setEnabled(true);
+ if(driverZ != NULL) {
+ smuffConfig.stepperSpread[FEEDER] = (param > 0);
+ driverZ->en_spreadCycle(param > 0);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ else {
+ if(buf.indexOf(Z_Param) != -1) {
+ steppers[FEEDER].setEnabled(true);
+ if(driverZ != NULL) {
+ sprintf_P(tmp, P_StepperMode, "Z (Feeder)", driverZ->stealth() ? P_Stealth : P_Spread);
+ printResponse(tmp, serial);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ }
+
+ if((param = getParam(buf, E_Param)) != -1) {
+ if(param >= 0 && param <= 1) {
+ steppers[FEEDER].setEnabled(true);
+ if(driverE != NULL) {
+ smuffConfig.stepperSpread[FEEDER] = (param > 0);
+ driverE->en_spreadCycle(param > 0);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ else {
+ if(buf.indexOf(E_Param) != -1) {
+ steppers[FEEDER].setEnabled(true);
+ if(driverE != NULL) {
+ sprintf_P(tmp, P_StepperMode, "E (Feeder)", driverE->stealth() ? P_Stealth : P_Spread);
+ printResponse(tmp, serial);
+ }
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ }
+
+ return stat;
+}
+
bool M575(const char* msg, String buf, int serial) {
bool stat = true;
long paramL;
@@ -656,14 +1372,23 @@ bool M575(const char* msg, String buf, int serial) {
if((paramL = getParamL(buf, S_Param)) != -1) {
if(port != -1) {
switch(port) {
+ case 0: smuffConfig.serial0Baudrate = paramL; break;
case 1: smuffConfig.serial1Baudrate = paramL; break;
case 2: smuffConfig.serial2Baudrate = paramL; break;
+ #if !defined(__ESP32__)
+ case 3: smuffConfig.serial3Baudrate = paramL; break;
+ #endif
}
}
else {
+ smuffConfig.serial0Baudrate = paramL;
smuffConfig.serial1Baudrate = paramL;
smuffConfig.serial2Baudrate = paramL;
+ #if !defined(__ESP32__)
+ smuffConfig.serial3Baudrate = paramL;
+ #endif
}
+ setupSerial();
}
else
stat = false;
@@ -688,6 +1413,107 @@ bool M701(const char* msg, String buf, int serial) {
return unloadFilament();
}
+bool M906(const char* msg, String buf, int serial) {
+ bool stat = true;
+ printResponse(msg, serial);
+
+ if((param = getParam(buf, X_Param)) != -1) {
+ if(param > 0 && param <= 1400) {
+ smuffConfig.stepperPower[SELECTOR] = param;
+ steppers[SELECTOR].setEnabled(true);
+ if(driverX != NULL)
+ driverX->rms_current(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Y_Param)) != -1) {
+ if(param > 0 && param <= 1400) {
+ smuffConfig.stepperPower[REVOLVER] = param;
+ steppers[REVOLVER].setEnabled(true);
+ if(driverY != NULL)
+ driverY->rms_current(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Z_Param)) != -1) {
+ if(param > 0 && param <= 1400) {
+ smuffConfig.stepperPower[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverZ != NULL)
+ driverZ->rms_current(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, E_Param)) != -1) {
+ if(param > 0 && param <= 1400) {
+ smuffConfig.stepperPower[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverE != NULL)
+ driverE->rms_current(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ return stat;
+}
+
+bool M914(const char* msg, String buf, int serial) {
+ bool stat = true;
+ printResponse(msg, serial);
+ if((param = getParam(buf, X_Param)) != -1) {
+ if(param > 0 && param <= 255) {
+ smuffConfig.stepperStall[SELECTOR] = param;
+ steppers[SELECTOR].setEnabled(true);
+ if(driverX != NULL)
+ driverX->SGTHRS(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Y_Param)) != -1) {
+ if(param > 0 && param <= 255) {
+ smuffConfig.stepperStall[REVOLVER] = param;
+ steppers[REVOLVER].setEnabled(true);
+ if(driverY != NULL)
+ driverY->SGTHRS(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, Z_Param)) != -1) {
+ if(param > 0 && param <= 255) {
+ smuffConfig.stepperStall[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverZ != NULL)
+ driverZ->SGTHRS(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ if((param = getParam(buf, E_Param)) != -1) {
+ if(param > 0 && param <= 255) {
+ smuffConfig.stepperStall[FEEDER] = param;
+ steppers[FEEDER].setEnabled(true);
+ if(driverE != NULL)
+ driverE->SGTHRS(param);
+ else
+ printResponseP(P_StepperNotCfg, serial);
+ }
+ else stat = false;
+ }
+ return stat;
+}
+
bool M999(const char* msg, String buf, int serial) {
printResponse(msg, serial);
delay(500);
diff --git a/src/InputDialogs.cpp b/src/InputDialogs.cpp
index 869bf03..08ae00e 100644
--- a/src/InputDialogs.cpp
+++ b/src/InputDialogs.cpp
@@ -45,9 +45,8 @@ void getEncoderButton(int* turn, int* button, bool* isHeld, bool* isClicked) {
}
}
-bool showInputDialog(const char* title, const char* PROGMEM message, float* val, float min, float max, fCallback cb) {
+bool showInputDialog(const char* title, const char* PROGMEM message, float* val, float min, float max, fCallback cb, float increment) {
bool stat = true;
- float steps = 1.0F;
int turn, btn;
bool isHeld, isClicked;
@@ -65,7 +64,7 @@ bool showInputDialog(const char* title, const char* PROGMEM message, float* val,
break;
}
if(turn != 0) {
- *val += steps*turn;
+ *val += increment*turn;
if(turn < 0) {
if(*val < min) {
*val = min;
@@ -88,11 +87,17 @@ bool showInputDialog(const char* title, const char* PROGMEM message, float* val,
return stat;
}
-bool showInputDialog(const char* title, const char* PROGMEM message, int* val, int min, int max, iCallback cb) {
+bool showInputDialog(const char* title, const char* PROGMEM message, int* val, int min, int max, iCallback cb, int increment) {
bool stat = true;
int turn, btn;
bool isHeld, isClicked;
+ if(cb == NULL && (min==0 && max==1)) {
+ // if there's no callback set, and min, max equals 0,1 don't show the dialog
+ // just return the inverted value (used for HI / LO)
+ *val = (*val==min ? max : min);
+ return true;
+ }
debounceButton();
encoder.setAccelerationEnabled(true);
drawValue(title, message, String(*val));
@@ -107,7 +112,7 @@ bool showInputDialog(const char* title, const char* PROGMEM message, int* val, i
break;
}
if(turn != 0) {
- *val += turn;
+ *val += (turn*increment);
if(turn < 0) {
if(*val < min) {
*val = min;
@@ -135,8 +140,14 @@ bool showInputDialog(const char* title, const char* PROGMEM message, bool* val,
bool stat = true;
int turn, btn;
bool isHeld, isClicked;
- char _yes[10], _no[10];
+ char _yes[5], _no[5];
+ if(cb == NULL) {
+ // if there's no callback set, don't show the dialog
+ // just return the inverted value
+ *val = !*val;
+ return true;
+ }
sprintf_P(_yes, P_Yes);
sprintf_P(_no, P_No);
@@ -177,17 +188,17 @@ bool showInputDialog(const char* title, const char* PROGMEM message, int* val, S
if(lineCnt==0)
return false;
- for(int i=0; i< lineCnt; i++) {
if(valIsIndex) {
opt = *val;
}
else {
- if(String(options[i]) == String(*val)) {
- opt = i;
- //__debug(PSTR("Current selection: %s"), options[i]);
+ for(int i=0; i< lineCnt; i++) {
+ if(String(options[i]) == String(*val)) {
+ opt = i;
+ //__debug(PSTR("Current selection: %s"), options[i]);
+ }
}
}
- }
drawValue(title, message, String(options[opt]));
while(1) {
@@ -228,7 +239,7 @@ bool showInputDialog(const char* title, const char* PROGMEM message, unsigned lo
char* options[10];
debounceButton();
- int lineCnt = splitStringLines(options, (int)(sizeof(options)/sizeof(options[0])), list.c_str());
+ int lineCnt = splitStringLines(options, (int)ArraySize(options), list.c_str());
if(lineCnt==0)
return false;
diff --git a/src/Led.cpp b/src/Led.cpp
index 599039a..930265c 100644
--- a/src/Led.cpp
+++ b/src/Led.cpp
@@ -17,11 +17,13 @@
*
*/
#include "SMuFF.h"
-#include "Config.h"
-#include "FastLED.h"
CRGB leds[NUM_LEDS];
+#if !defined(USE_FASTLED_BACKLIGHT)
+static CRGB ColorsFastLED[8];
+#else
static CRGB ColorsFastLED[8] = { CRGB::Black, CRGB::Red, CRGB::Green, CRGB::Blue, CRGB::Cyan, CRGB::Magenta, CRGB::Yellow, CRGB::White };
+#endif
// old function - meant to simulate beeps with
// different colors
@@ -61,50 +63,60 @@ void setBacklightRGB(byte R, byte G, byte B) {
void setBacklightRGB(int color) {
#if defined(RGB_LED_R_PIN)
- pinMode(RGB_LED_R_PIN, OUTPUT);
- digitalWrite(RGB_LED_R_PIN, color & 1);
+ pinMode(RGB_LED_R_PIN, OUTPUT);
+ digitalWrite(RGB_LED_R_PIN, color & 1);
#endif
#if defined(RGB_LED_G_PIN)
- pinMode(RGB_LED_G_PIN, OUTPUT);
- digitalWrite(RGB_LED_G_PIN, color & 2);
+ pinMode(RGB_LED_G_PIN, OUTPUT);
+ digitalWrite(RGB_LED_G_PIN, color & 2);
#endif
#if defined(RGB_LED_B_PIN)
- pinMode(RGB_LED_B_PIN, OUTPUT);
- digitalWrite(RGB_LED_B_PIN, color & 4);
+ pinMode(RGB_LED_B_PIN, OUTPUT);
+ digitalWrite(RGB_LED_B_PIN, color & 4);
#endif
}
void setBacklightCRGB(CRGB color) {
+#if defined(USE_FASTLED_BACKLIGHT)
FastLED.showColor(color);
+#endif
}
void setFastLED(int index, CRGB color) {
- leds[index] = color;
- FastLED.show();
+#if defined(USE_FASTLED_BACKLIGHT)
+ leds[index] = color;
+ FastLED.show();
+#endif
}
void setFastLEDIndex(int index, int color) {
+#if defined(USE_FASTLED_BACKLIGHT)
leds[index] = ColorsFastLED[color];
FastLED.show();
+#endif
}
void setFastLEDIntensity(int intensity) {
+#if defined(USE_FASTLED_BACKLIGHT)
FastLED.setBrightness(intensity);
+#endif
}
void setBacklightIndex(int color) {
#if defined(USE_RGB_BACKLIGHT)
setBacklightRGB(color);
-#else
+#elif defined(USE_FASTLED_BACKLIGHT)
setBacklightCRGB(ColorsFastLED[color]);
#endif
}
void testFastLED() {
+#if defined(USE_FASTLED_BACKLIGHT)
for(int i=0; i< NUM_LEDS; i++) {
leds[i] = ColorsFastLED[1];
FastLED.show();
delay(250);
leds[i] = ColorsFastLED[0];
}
+#endif
}
\ No newline at end of file
diff --git a/src/Menus.cpp b/src/Menus.cpp
index 9811daa..c65e312 100644
--- a/src/Menus.cpp
+++ b/src/Menus.cpp
@@ -25,7 +25,8 @@
extern int swapTools[];
extern ZStepper steppers[];
extern ZServo servo, servoRevolver;
-extern int toolSelections[];
+extern int toolSelections[];
+TMC2209Stepper* setupDriver = NULL;
char* extractTitle(const char* menu PROGMEM, int index) {
char* tok = strtok((char*)menu, "\n");
@@ -67,30 +68,50 @@ void setupToolsMenu(char* menu) {
menu[strlen(menu)-1] = '\0';
}
+int menuVariant = 0;
+int mainMenuIndex[4][20] = {
+ { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
+ { 0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16 },
+ { 0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16 },
+ { 0,1,2,3,5,6,7,8,10,11,12,13,14,15,16 }
+};
+
void setupMainMenu(char* menu) {
char items[450];
#ifndef __AVR__
char items2[200];
#endif
- char stat[10];
- char sstat[10];
- char mstat[10];
- char opt[30] = "";
+ char motors[10];
+ char servo[30];
+ char maint[10];
+ char pmmu[30] = "";
- steppers[SELECTOR].getEnabled() ? sprintf_P(stat, P_Off) : sprintf_P(stat, P_On);
- servoRevolver.getDegree() == smuffConfig.revolverOnPos ? sprintf_P(sstat, P_Open) : sprintf_P(sstat, P_Close);
- maintainingMode ? sprintf_P(mstat, P_Off) : sprintf_P(mstat, P_On);
+ steppers[SELECTOR].getEnabled() ? sprintf_P(motors, P_Off) : sprintf_P(motors, P_On);
+ servoRevolver.getDegree() == smuffConfig.revolverOnPos ? sprintf_P(servo, P_MenuItemsServo, P_Open) : sprintf_P(servo, P_MenuItemsServo, P_Close);
+ maintainingMode ? sprintf_P(maint, P_Off) : sprintf_P(maint, P_On);
+
if(smuffConfig.prusaMMU2) {
- sprintf_P(opt, P_MenuItemsPMMU);
+ sprintf_P(pmmu, P_MenuItemsPMMU);
}
sprintf_P(menu, P_MenuItemBack);
#ifndef __AVR__
- sprintf_P(items2, P_MenuItemsDefault, P_MenuItemSeparator);
- #if defined(SMUFF_V5)
- sprintf_P(items, P_MenuItems, stat, sstat, mstat, opt, P_MenuItemSeparator, items2);
- #else
- sprintf_P(items, P_MenuItems, stat, opt, P_MenuItemSeparator, items2);
- #endif
+ sprintf_P(items2, P_MenuItemsDefault, P_MenuItemSeparator, P_MenuItemSeparator, P_MenuItemSeparator);
+ if(smuffConfig.revolverIsServo && smuffConfig.prusaMMU2) {
+ sprintf_P(items, P_MenuItems, motors, servo, maint, pmmu, items2);
+ menuVariant = 0;
+ }
+ else if(smuffConfig.revolverIsServo && !smuffConfig.prusaMMU2) {
+ sprintf_P(items, P_MenuItems, motors, servo, maint, "", items2);
+ menuVariant = 1;
+ }
+ else if(!smuffConfig.revolverIsServo && smuffConfig.prusaMMU2) {
+ sprintf_P(items, P_MenuItems, motors, "", maint, pmmu, items2);
+ menuVariant = 2;
+ }
+ else {
+ sprintf_P(items, P_MenuItems, motors, "", maint, "", items2);
+ menuVariant = 3;
+ }
#else
// need two different menus because of low memory issues on the ATMEGA
sprintf_P(items, P_MenuItems, stat, opt);
@@ -98,10 +119,13 @@ void setupMainMenu(char* menu) {
strcat(menu, items);
}
-void setupOffsetMenu(char* menu) {
+void setupStatusInfoMenu(char* menu) {
char items[120];
sprintf_P(menu, P_MenuItemBack);
- sprintf_P(items, P_OfsMenuItems, String(smuffConfig.firstToolOffset).c_str(), String(smuffConfig.firstRevolverOffset).c_str());
+ sprintf_P(items, P_StatusInfoMenuItems,
+ /* driverX == NULL ? "" : */ P_StatusInfoMenuItemsX,
+ /* driverY == NULL ? "" : */ P_StatusInfoMenuItemsY,
+ /* driverZ == NULL ? "" : */ P_StatusInfoMenuItemsZ);
strcat(menu, items);
}
@@ -125,10 +149,7 @@ void setupSettingsMenu(char* menu) {
String(smuffConfig.toolCount).c_str(),
String(smuffConfig.bowdenLength).c_str(),
String(smuffConfig.selectorDistance).c_str(),
- String(smuffConfig.menuAutoClose).c_str(),
- String(smuffConfig.fanSpeed).c_str(),
- smuffConfig.prusaMMU2 ? P_Yes : P_No,
- smuffConfig.sendPeriodicalStats ? P_Yes : P_No,
+ P_MenuItemSeparator,
#ifndef __AVR__
"\u25b8",
"\u25b8",
@@ -143,12 +164,28 @@ void setupSettingsMenu(char* menu) {
strcat(menu, items);
}
+void setupOptionsMenu(char* menu) {
+ char items[400];
+ sprintf_P(menu, P_MenuItemBack);
+ sprintf_P(items, P_OptionsMenuItems,
+ String(smuffConfig.menuAutoClose).c_str(),
+ String(smuffConfig.fanSpeed).c_str(),
+ smuffConfig.prusaMMU2 ? P_Yes : P_No,
+ smuffConfig.sendPeriodicalStats ? P_Yes : P_No,
+ smuffConfig.useDuetLaser ? P_Yes : P_No,
+ smuffConfig.hasPanelDue==0 ? P_None : translatePanelDuePort(smuffConfig.hasPanelDue)
+ );
+ strcat(menu, items);
+}
+
void setupBaudrateMenu(char* menu) {
char items[128];
sprintf_P(menu, P_MenuItemBack);
sprintf_P(items, P_BaudMenuItems,
- String(smuffConfig.serial1Baudrate).c_str(),
- String(smuffConfig.serial2Baudrate).c_str());
+ String(smuffConfig.serial0Baudrate).c_str(),
+ CAN_USE_SERIAL1 ? String(smuffConfig.serial1Baudrate).c_str() : "---",
+ CAN_USE_SERIAL2 ? String(smuffConfig.serial2Baudrate).c_str() : "---",
+ CAN_USE_SERIAL3 ? String(smuffConfig.serial3Baudrate).c_str() : "---");
strcat(menu, items);
}
@@ -159,39 +196,47 @@ void setupSteppersMenu(char *menu) {
#ifndef __AVR__
"\u25b8",
"\u25b8",
+ (smuffConfig.revolverIsServo) ? "Servo" : "Revolver",
"\u25b8");
#else
">",
">",
+ (smuffConfig.revolverIsServo) ? "Servo" : "Revolver",
">");
#endif
strcat(menu, items);
}
+void setupTMCMenu(char* menu, int axis) {
+ char items1[250];
+ sprintf_P(menu, P_MenuItemBack);
+ sprintf_P(items1, P_TMCMenuItems,
+ translateTMCDriverMode(smuffConfig.stepperMode[axis]),
+ String(smuffConfig.stepperPower[axis]).c_str(),
+ String(smuffConfig.stepperRSense[axis]).c_str(),
+ String(smuffConfig.stepperMicrosteps[axis]).c_str(),
+ String(smuffConfig.stepperStall[axis]).c_str(),
+ String(smuffConfig.stepperCSmin[axis]).c_str(),
+ String(smuffConfig.stepperCSmax[axis]).c_str(),
+ String(smuffConfig.stepperCSdown[axis]).c_str(),
+ String(smuffConfig.stepperAddr[axis]).c_str(),
+ String(smuffConfig.stepperToff[axis]).c_str());
+ strcat(menu, items1);
+}
+
void setupRevolverMenu(char* menu) {
- char items1[170];
-#if !defined(SMUFF_V5)
+ char items1[200];
char items2[240];
-#endif
+
sprintf_P(menu, P_MenuItemBack);
sprintf_P(items1, P_AllSteppersMenuItems,
+ translateTMCDriverMode(smuffConfig.stepperMode[REVOLVER]),
smuffConfig.invertDir_Y ? P_Yes : P_No,
smuffConfig.endstopTrigger_Y ? P_High : P_Low,
String(smuffConfig.stepDelay_Y).c_str(),
String(smuffConfig.maxSpeed_Y).c_str(),
String(smuffConfig.maxSpeedHS_Y).c_str(),
String(smuffConfig.acceleration_Y).c_str());
- #if defined(SMUFF_V5)
- sprintf_P(items1, P_RevolverMenuItems,
- smuffConfig.homeAfterFeed ? P_Yes : P_No,
- smuffConfig.resetBeforeFeed_Y ? P_Yes : P_No,
- smuffConfig.revolverIsServo ? P_Yes : P_No,
- String(smuffConfig.revolverOffPos).c_str(),
- String(smuffConfig.revolverOnPos).c_str(),
- String(smuffConfig.servoCycles1).c_str(),
- String(smuffConfig.servoCycles2).c_str());
- strcat(menu, items1);
- #else
sprintf_P(items2, P_RevolverMenuItems,
String(smuffConfig.stepsPerRevolution_Y).c_str(),
smuffConfig.homeAfterFeed ? P_Yes : P_No,
@@ -204,7 +249,21 @@ void setupRevolverMenu(char* menu) {
String(smuffConfig.servoCycles2).c_str());
strcat(menu, items1);
strcat(menu, items2);
- #endif
+}
+
+void setupServoMenu(char* menu) {
+ char items1[170];
+
+ sprintf_P(menu, P_MenuItemBack);
+ sprintf_P(items1, P_ServoMenuItems,
+ smuffConfig.homeAfterFeed ? P_Yes : P_No,
+ smuffConfig.resetBeforeFeed_Y ? P_Yes : P_No,
+ smuffConfig.revolverIsServo ? P_Yes : P_No,
+ String(smuffConfig.revolverOffPos).c_str(),
+ String(smuffConfig.revolverOnPos).c_str(),
+ String(smuffConfig.servoCycles1).c_str(),
+ String(smuffConfig.servoCycles2).c_str());
+ strcat(menu, items1);
}
void setupFeederMenu(char* menu) {
@@ -212,6 +271,7 @@ void setupFeederMenu(char* menu) {
char items2[256];
sprintf_P(menu, P_MenuItemBack);
sprintf_P(items1, P_AllSteppersMenuItems,
+ translateTMCDriverMode(smuffConfig.stepperMode[FEEDER]),
smuffConfig.invertDir_Z ? P_Yes : P_No,
smuffConfig.endstopTrigger_Z ? P_High : P_Low,
String(smuffConfig.stepDelay_Z).c_str(),
@@ -224,16 +284,20 @@ void setupFeederMenu(char* menu) {
String(smuffConfig.feedChunks).c_str(),
String(smuffConfig.insertLength).c_str(),
String(smuffConfig.insertSpeed_Z).c_str(),
- String(smuffConfig.reinforceLength).c_str());
+ String(smuffConfig.reinforceLength).c_str(),
+ smuffConfig.externalControl_Z ? P_Yes : P_No,
+ smuffConfig.isSharedStepper ? P_Yes : P_No
+);
strcat(menu, items1);
strcat(menu, items2);
}
void setupSelectorMenu(char* menu) {
- char items1[150];
- char items2[56];
+ char items1[250];
+ char items2[60];
sprintf_P(menu, P_MenuItemBack);
sprintf_P(items1, P_AllSteppersMenuItems,
+ translateTMCDriverMode(smuffConfig.stepperMode[SELECTOR]),
smuffConfig.invertDir_X ? P_Yes : P_No,
smuffConfig.endstopTrigger_X ? P_High : P_Low,
String(smuffConfig.stepDelay_X).c_str(),
@@ -241,28 +305,20 @@ void setupSelectorMenu(char* menu) {
String(smuffConfig.maxSpeedHS_X).c_str(),
String(smuffConfig.acceleration_X).c_str());
sprintf_P(items2, P_SelectorMenuItems,
+ String(smuffConfig.firstToolOffset).c_str(),
String(smuffConfig.stepsPerMM_X).c_str());
strcat(menu, items1);
strcat(menu, items2);
}
-const char* translateColor(int color) {
- char* colorNames[16];
- char tmp[80];
- sprintf_P(tmp, P_Colors);
- splitStringLines(colorNames, (int)(sizeof(colorNames)/sizeof(colorNames[0])), tmp);
- if(color >= 0 && color < (int)sizeof(colorNames))
- return colorNames[color];
- return "???";
-}
-
void setupDisplayMenu(char* menu) {
char items1[200];
sprintf_P(menu, P_MenuItemBack);
sprintf_P(items1, P_DisplayMenuItems,
String(smuffConfig.powerSaveTimeout).c_str(),
String(smuffConfig.lcdContrast).c_str(),
- translateColor(smuffConfig.backlightColor));
+ translateColor(smuffConfig.backlightColor),
+ smuffConfig.encoderTickSound ? P_Yes : P_No);
strcat(menu, items1);
}
@@ -283,7 +339,8 @@ void showMainMenu() {
char tmp[128];
char _title[40];
char _menu[512];
-
+ int menuIdx[20];
+
do {
setupMainMenu(_menu);
//__debug(PSTR("MainList: %s %d"), _menu, strlen(_menu));
@@ -299,7 +356,7 @@ void showMainMenu() {
char* title = extractTitle(_menu, current_selection-1);
bool enabled = steppers[SELECTOR].getEnabled();
- switch(current_selection) {
+ switch(mainMenuIndex[menuVariant][current_selection]) {
case 1:
stopMenu = true;
break;
@@ -315,16 +372,16 @@ void showMainMenu() {
steppers[REVOLVER].setEnabled(!enabled);
steppers[FEEDER].setEnabled(!enabled);
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
startTime = millis();
break;
-#if defined(SMUFF_V5)
+
case 4:
if(servoRevolver.getDegree() == smuffConfig.revolverOffPos)
- setServoPos(1, smuffConfig.revolverOnPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOnPos);
else
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
startTime = millis();
break;
@@ -342,11 +399,6 @@ void showMainMenu() {
break;
case 7:
- showSwapMenu(title);
- startTime = millis();
- break;
-
- case 8:
if(smuffConfig.prusaMMU2)
loadFilamentPMMU2();
else
@@ -354,113 +406,37 @@ void showMainMenu() {
startTime = millis();
break;
- case 9:
+ case 8:
unloadFilament();
startTime = millis();
break;
- case 10:
-#ifndef __AVR__
- if(smuffConfig.prusaMMU2)
- loadFilament();
-#else
- showOffsetsMenu(title);
-#endif
+ case 9:
+ loadFilament();
startTime = millis();
break;
case 11:
- if(!smuffConfig.prusaMMU2)
- showSettingsMenu(title);
- current_selection = 1;
+ showSwapMenu(title);
+ startTime = millis();
+ break;
+
+ case 12:
+ showStatusInfoMenu(title);
startTime = millis();
break;
- case 12:
- if(smuffConfig.prusaMMU2)
- showSettingsMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-
- case 13:
- if(!smuffConfig.prusaMMU2)
- showTestrunMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-
case 14:
- if(smuffConfig.prusaMMU2)
- showTestrunMenu(title);
+ showSettingsMenu(title);
current_selection = 1;
startTime = millis();
break;
-#else
- case 4:
- feederJammed = false;
- beep(2);
- sprintf_P(tmp, P_JamCleared);
- drawUserMessage(tmp);
- startTime = millis();
- break;
- case 5:
- showSwapMenu(title);
- startTime = millis();
- break;
-
- case 6:
- if(smuffConfig.prusaMMU2)
- loadFilamentPMMU2();
- else
- loadFilament();
- startTime = millis();
- break;
-
- case 7:
- unloadFilament();
- startTime = millis();
- break;
-
- case 8:
-#ifndef __AVR__
- if(smuffConfig.prusaMMU2)
- loadFilament();
-#else
- showOffsetsMenu(title);
-#endif
- startTime = millis();
- break;
-
- case 9:
- if(!smuffConfig.prusaMMU2)
- showSettingsMenu(title);
+ case 16:
+ showTestrunMenu(title);
current_selection = 1;
startTime = millis();
break;
-
- case 10:
- if(smuffConfig.prusaMMU2)
- showSettingsMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-
- case 11:
- if(!smuffConfig.prusaMMU2)
- showTestrunMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-
- case 12:
- if(smuffConfig.prusaMMU2)
- showTestrunMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-#endif
}
}
debounceButton();
@@ -486,7 +462,7 @@ void showTestrunMenu(char* menuTitle) {
stopMenu = true;
}
else if(current_selection >= 2) {
- splitStringLines(fnames, (int)(sizeof(fnames)/sizeof(fnames[0])), (const char*)_menu);
+ splitStringLines(fnames, (int)ArraySize(fnames), (const char*)_menu);
_file = String(fnames[current_selection-1]);
_file.trim();
//__debug(PSTR("Selected file: %s"), _file.c_str());
@@ -495,20 +471,99 @@ void showTestrunMenu(char* menuTitle) {
} while(!stopMenu);
}
+char colorName[10];
+
+const char* translateColor(int color) {
+ char* colorNames[16];
+ char tmp[80];
+ sprintf_P(tmp, P_Colors);
+ splitStringLines(colorNames, (int)ArraySize(colorNames), tmp);
+ if(color >= 0 && color < (int)ArraySize(colorNames))
+ strcpy(colorName, colorNames[color]);
+ else sprintf(colorName, "???");
+ return colorName;
+}
+
+char duePort[10];
+
+const char* translatePanelDuePort(int port) {
+ char* ports[3];
+ char tmp[40];
+ sprintf_P(tmp, P_PanelDueOptions);
+ splitStringLines(ports, (int)ArraySize(ports), tmp);
+ if(port >= 0 && port < (int)ArraySize(ports))
+ strcpy(duePort, ports[port]);
+ else sprintf(duePort, "???");
+ return duePort;
+}
+
+char driverMode[10];
+
+const char* translateTMCDriverMode(int mode) {
+ char* modes[3];
+ char tmp[40];
+ sprintf_P(tmp, P_TMCModeItems);
+ splitStringLines(modes, (int)ArraySize(modes), tmp);
+ if(mode >= 0 && mode < (int)ArraySize(modes))
+ strcpy(driverMode, modes[mode]);
+ else sprintf(driverMode, "???");
+ return driverMode;
+}
+
+void selectPanelDuePort(char* menuTitle) {
+ int val;
+ char tmp[128];
+ sprintf_P(tmp, P_PanelDueOptions);
+ val = smuffConfig.hasPanelDue;
+ if(showInputDialog(menuTitle, P_PanelDuePort, &val, String(tmp), NULL, true))
+ smuffConfig.hasPanelDue = val;
+}
bool selectBaudrate(int port, char* menuTitle) {
unsigned long val;
char tmp[128];
sprintf_P(tmp, P_Baudrates);
- if(port == 1) {
- val = smuffConfig.serial1Baudrate;
- if(showInputDialog(menuTitle, P_Baud, &val, String(tmp)))
- smuffConfig.serial1Baudrate = val;
+ if(port == 0) {
+ val = smuffConfig.serial0Baudrate;
+ if(showInputDialog(menuTitle, P_Baud, &val, String(tmp))) {
+ smuffConfig.serial0Baudrate = val;
+ Serial.end();
+ delay(500);
+ Serial.begin(smuffConfig.serial0Baudrate);
+ }
+ }
+ else if(port == 1) {
+ if(CAN_USE_SERIAL1) {
+ val = smuffConfig.serial1Baudrate;
+ if(showInputDialog(menuTitle, P_Baud, &val, String(tmp))) {
+ smuffConfig.serial1Baudrate = val;
+ Serial1.end();
+ delay(500);
+ Serial1.begin(smuffConfig.serial1Baudrate);
+ }
+ }
+ }
+ else if(port == 2) {
+ if(CAN_USE_SERIAL2) {
+ val = smuffConfig.serial2Baudrate;
+ if(showInputDialog(menuTitle, P_Baud, &val, String(tmp))) {
+ smuffConfig.serial2Baudrate = val;
+ Serial2.end();
+ delay(500);
+ Serial2.begin(smuffConfig.serial2Baudrate);
+ }
+ }
}
else {
- val = smuffConfig.serial2Baudrate;
- if(showInputDialog(menuTitle, P_Baud, &val, String(tmp)))
- smuffConfig.serial2Baudrate = val;
+ if(CAN_USE_SERIAL3) {
+ val = smuffConfig.serial3Baudrate;
+ if(showInputDialog(menuTitle, P_Baud, &val, String(tmp))) {
+ smuffConfig.serial3Baudrate = val;
+ Serial3.end();
+ delay(500);
+ Serial3.begin(smuffConfig.serial3Baudrate);
+ }
+ }
}
return true;
}
@@ -525,20 +580,22 @@ bool selectBacklightColor(int color, char* menuTitle) {
}
void positionServoCallback(int val) {
- setServoPos(1, val);
+ setServoPos(SERVO_LID, val);
}
-void showRevolverMenu(char* menuTitle) {
+void showTMCMenu(char* menuTitle, int axis) {
bool stopMenu = false;
unsigned int startTime = millis();
uint8_t current_selection = 0;
- char* title;
bool bVal;
int iVal;
- char _menu[350];
+ float fVal;
+ char* title;
+ char _menu[450];
+ char tmp[50];
do {
- setupRevolverMenu(_menu);
+ setupTMCMenu(_menu, axis);
//__debug(PSTR("Revolver Menu: %s %d"), _menu, strlen(_menu));
resetAutoClose();
stopMenu = checkStopMenu(startTime);
@@ -553,7 +610,276 @@ void showRevolverMenu(char* menuTitle) {
case 1:
stopMenu = true;
break;
- #if defined(SMUFF_V5)
+
+ case 2: // Mode
+ iVal = smuffConfig.stepperMode[axis];
+ sprintf_P(tmp, P_TMCModeItems);
+ if(showInputDialog(title, P_DriverMode, &iVal, String(tmp), NULL, true))
+ smuffConfig.stepperMode[axis] = iVal;
+ startTime = millis();
+ break;
+
+ case 3: // Power
+ iVal = smuffConfig.stepperPower[axis];
+ if(showInputDialog(title, P_InMilliAmpere, &iVal, 0, 1400, NULL, 10)) {
+ smuffConfig.stepperPower[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->rms_current(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 4: // RSense
+ fVal = smuffConfig.stepperRSense[axis];
+ if(showInputDialog(title, P_InOhm, &fVal, 0, 1, NULL, 0.01)) {
+ smuffConfig.stepperRSense[axis] = fVal;
+ if(setupDriver != NULL)
+ setupDriver->Rsense = fVal;
+ }
+ startTime = millis();
+ break;
+
+ case 5: // Microsteps
+ iVal = smuffConfig.stepperMicrosteps[axis];
+ sprintf_P(tmp, P_MicrostepItems);
+ if(showInputDialog(title, P_Microsteps, &iVal, String(tmp), NULL, false)) {
+ smuffConfig.stepperMicrosteps[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->mstep_reg_select(true);
+ setupDriver->microsteps(iVal);
+ }
+ break;
+
+ case 6: // Stall
+ iVal = smuffConfig.stepperStall[axis];
+ if(showInputDialog(title, P_Threshold, &iVal, 0, 255)) {
+ smuffConfig.stepperStall[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->SGTHRS(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 8: // CoolStep min
+ iVal = smuffConfig.stepperCSmin[axis];
+ if(showInputDialog(title, P_Min, &iVal, 0, 15)) {
+ smuffConfig.stepperCSmin[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->semin(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 7: // CoolStep max
+ iVal = smuffConfig.stepperCSmax[axis];
+ if(showInputDialog(title, P_Max, &iVal, 0, 15)) {
+ smuffConfig.stepperCSmax[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->semax(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 9: // CoolStep down
+ iVal = smuffConfig.stepperCSdown[axis];
+ if(showInputDialog(title, P_Down, &iVal, 0, 15)) {
+ smuffConfig.stepperCSdown[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->sedn(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 10: // Driver Address
+ iVal = smuffConfig.stepperAddr[axis];
+ if(showInputDialog(title, P_Address, &iVal, 0, 3)) {
+ smuffConfig.stepperAddr[axis] = iVal;
+ }
+ startTime = millis();
+ break;
+
+ case 11: // TOff
+ iVal = smuffConfig.stepperToff[axis];
+ if(showInputDialog(title, P_Value, &iVal, 0, 15)) {
+ smuffConfig.stepperToff[axis] = iVal;
+ if(setupDriver != NULL)
+ setupDriver->toff(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 12: // SpreadCycle
+ bVal = smuffConfig.stepperSpread[axis];
+ if(showInputDialog(title, P_YesNo, &bVal)) {
+ smuffConfig.stepperSpread[axis] = bVal;
+ if(setupDriver != NULL)
+ setupDriver->en_spreadCycle(bVal);
+ }
+ startTime = millis();
+ break;
+ }
+ }
+ } while(!stopMenu);
+}
+
+void showRevolverMenu(char* menuTitle) {
+ bool stopMenu = false;
+ unsigned int startTime = millis();
+ uint8_t current_selection = 0;
+ char* title;
+ bool bVal;
+ int iVal;
+ char _menu[350];
+
+ do {
+ setupRevolverMenu(_menu);
+ //__debug(PSTR("Revolver Menu: %s\nLen: %d"), _menu, strlen(_menu));
+ resetAutoClose();
+ stopMenu = checkStopMenu(startTime);
+
+ current_selection = display.userInterfaceSelectionList(menuTitle, current_selection, _menu);
+
+ if(current_selection == 0)
+ return;
+ else {
+ title = extractTitle(_menu, current_selection-1);
+ switch(current_selection) {
+ case 1:
+ stopMenu = true;
+ break;
+
+ case 2: // TMC-Paramters
+ setupDriver = driverY;
+ showTMCMenu(title, REVOLVER);
+ startTime = millis();
+ break;
+
+ case 3: // Invert dir
+ bVal = smuffConfig.invertDir_Y;
+ if(showInputDialog(title, P_YesNo, &bVal)) {
+ smuffConfig.invertDir_Y = bVal;
+ steppers[REVOLVER].setInvertDir(bVal);
+ }
+ startTime = millis();
+ break;
+
+ case 4: // Endstop trigger
+ iVal = smuffConfig.endstopTrigger_Y;
+ if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1)) {
+ smuffConfig.endstopTrigger_Y = iVal;
+ steppers[REVOLVER].setEndstopState(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 5: // Step Delay
+ iVal = smuffConfig.stepDelay_Y;
+ if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100)) {
+ smuffConfig.stepDelay_Y = iVal;
+ }
+ startTime = millis();
+ break;
+
+ case 6: // Max. Speed
+ iVal = smuffConfig.maxSpeed_Y;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
+ smuffConfig.maxSpeed_Y = iVal;
+ steppers[REVOLVER].setMaxSpeed(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 7: // Max. Speed HS
+ iVal = smuffConfig.maxSpeedHS_Y;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
+ smuffConfig.maxSpeedHS_Y = iVal;
+ steppers[REVOLVER].setMaxHSpeed(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 8: // Acceleration
+ iVal = smuffConfig.acceleration_Y;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 60000, NULL, 50)) {
+ smuffConfig.acceleration_Y = iVal;
+ steppers[REVOLVER].setAcceleration(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 9: // Offset
+ changeOffset(REVOLVER);
+ startTime = millis();
+ break;
+
+ case 10: // Steps Per Rev
+ iVal = smuffConfig.stepsPerRevolution_Y;
+ if(showInputDialog(title, P_InSteps, &iVal, 1, 10000)) {
+ smuffConfig.stepsPerRevolution_Y = iVal;
+ steppers[REVOLVER].setMaxStepCount(iVal);
+ steppers[REVOLVER].setStepsPerDegree(iVal/360);
+ }
+ startTime = millis();
+ break;
+
+ case 11: // Home after feed
+ bVal = smuffConfig.homeAfterFeed;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.homeAfterFeed = bVal;
+ startTime = millis();
+ break;
+
+ case 12: // Reset before feed
+ bVal = smuffConfig.resetBeforeFeed_Y;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.resetBeforeFeed_Y = bVal;
+ startTime = millis();
+ break;
+
+ case 13: // Wiggle
+ bVal = smuffConfig.wiggleRevolver;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.wiggleRevolver = bVal;
+ startTime = millis();
+ break;
+
+ case 14: // Use Servo
+ bVal = smuffConfig.revolverIsServo;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.revolverIsServo = bVal;
+ startTime = millis();
+ break;
+ }
+ }
+ } while(!stopMenu);
+}
+
+void showServoMenu(char* menuTitle) {
+ bool stopMenu = false;
+ unsigned int startTime = millis();
+ uint8_t current_selection = 0;
+ char* title;
+ bool bVal;
+ int iVal;
+ char _menu[350];
+
+ do {
+ setupServoMenu(_menu);
+ //__debug(PSTR("Revolver Menu: %s %d"), _menu, strlen(_menu));
+ resetAutoClose();
+ stopMenu = checkStopMenu(startTime);
+
+ current_selection = display.userInterfaceSelectionList(menuTitle, current_selection, _menu);
+
+ if(current_selection == 0)
+ return;
+ else {
+ title = extractTitle(_menu, current_selection-1);
+ switch(current_selection) {
+ case 1:
+ stopMenu = true;
+ break;
+
case 2: // Home after feed
bVal = smuffConfig.homeAfterFeed;
if(showInputDialog(title, P_YesNo, &bVal))
@@ -606,114 +932,6 @@ void showRevolverMenu(char* menuTitle) {
}
startTime = millis();
break;
- #else
- case 2: // Invert dir
- bVal = smuffConfig.invertDir_Y;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.invertDir_Y = bVal;
- startTime = millis();
- break;
-
- case 3: // Endstop trigger
- iVal = smuffConfig.endstopTrigger_Y;
- if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1))
- smuffConfig.endstopTrigger_Y = iVal;
- startTime = millis();
- break;
-
- case 4: // Step Delay
- iVal = smuffConfig.stepDelay_Y;
- if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100))
- smuffConfig.stepDelay_Y = iVal;
- startTime = millis();
- break;
-
- case 5: // Max. Speed
- iVal = smuffConfig.maxSpeed_Y;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
- smuffConfig.maxSpeed_Y = iVal;
- startTime = millis();
- break;
-
- case 6: // Max. Speed HS
- iVal = smuffConfig.maxSpeedHS_Y;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
- smuffConfig.maxSpeedHS_Y = iVal;
- startTime = millis();
- break;
-
- case 7: // Acceleration
- iVal = smuffConfig.acceleration_Y;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 60000))
- smuffConfig.acceleration_Y = iVal;
- startTime = millis();
- break;
-
- case 8: // Steps Per Rev
- iVal = smuffConfig.stepsPerRevolution_Y;
- if(showInputDialog(title, P_InSteps, &iVal, 1, 10000))
- smuffConfig.stepsPerRevolution_Y = iVal;
- startTime = millis();
- break;
-
- case 9: // Home after feed
- bVal = smuffConfig.homeAfterFeed;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.homeAfterFeed = bVal;
- startTime = millis();
- break;
-
- case 10: // Reset before feed
- bVal = smuffConfig.resetBeforeFeed_Y;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.resetBeforeFeed_Y = bVal;
- startTime = millis();
- break;
-
- case 11: // Wiggle
- bVal = smuffConfig.wiggleRevolver;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.wiggleRevolver = bVal;
- startTime = millis();
- break;
-
- case 12: // Use Servo
- bVal = smuffConfig.revolverIsServo;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.revolverIsServo = bVal;
- startTime = millis();
- break;
-
- case 13: // Servo open
- iVal = smuffConfig.revolverOffPos;
- if(showInputDialog(title, P_OpenPos, &iVal, 0, 2400, positionServoCallback))
- smuffConfig.revolverOffPos = iVal;
- startTime = millis();
- break;
-
- case 14: // Servo closed
- iVal = smuffConfig.revolverOnPos;
- if(showInputDialog(title, P_ClosedPos, &iVal, 0, 2400, positionServoCallback))
- smuffConfig.revolverOnPos = iVal;
- startTime = millis();
- break;
-
- case 15: // Servo 1 cycles
- iVal = smuffConfig.servoCycles1;
- if(showInputDialog(title, P_ServoCycles, &iVal, 0, 50))
- smuffConfig.servoCycles1 = iVal;
- servo.setMaxCycles(iVal);
- startTime = millis();
- break;
-
- case 16: // Servo 2 cycles
- iVal = smuffConfig.servoCycles2;
- if(showInputDialog(title, P_ServoCycles, &iVal, 0, 50))
- smuffConfig.servoCycles2 = iVal;
- servoRevolver.setMaxCycles(iVal);
- startTime = millis();
- break;
- #endif
}
}
} while(!stopMenu);
@@ -726,11 +944,11 @@ void showSelectorMenu(char* menuTitle) {
char* title;
bool bVal;
int iVal;
- char _menu[300];
+ char _menu[350];
do {
setupSelectorMenu(_menu);
- //__debug(PSTR("Selector Menu: %s %d"), _menu, strlen(_menu));
+ //__debug(PSTR("Selector Menu: %s\nLen: %d"), _menu, strlen(_menu));
resetAutoClose();
stopMenu = checkStopMenu(startTime);
@@ -745,52 +963,76 @@ void showSelectorMenu(char* menuTitle) {
stopMenu = true;
break;
- case 2: // Invert dir
+ case 2: // TMC-Paramters
+ setupDriver = driverX;
+ showTMCMenu(title, SELECTOR);
+ startTime = millis();
+ break;
+
+ case 3: // Invert dir
bVal = smuffConfig.invertDir_X;
- if(showInputDialog(title, P_YesNo, &bVal))
+ if(showInputDialog(title, P_YesNo, &bVal)) {
smuffConfig.invertDir_X = bVal;
+ steppers[SELECTOR].setInvertDir(bVal);
+ }
startTime = millis();
break;
- case 3: // Endstop trigger
+ case 4: // Endstop trigger
iVal = smuffConfig.endstopTrigger_X;
- if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1))
+ if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1)) {
smuffConfig.endstopTrigger_X = iVal;
+ steppers[SELECTOR].setEndstopState(iVal);
+ }
startTime = millis();
break;
- case 4: // Step Delay
+ case 5: // Step Delay
iVal = smuffConfig.stepDelay_X;
- if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100))
+ if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100)) {
smuffConfig.stepDelay_X = iVal;
+ }
startTime = millis();
break;
- case 5: // Max. Speed
+ case 6: // Max. Speed
iVal = smuffConfig.maxSpeed_X;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
smuffConfig.maxSpeed_X = iVal;
+ steppers[SELECTOR].setMaxSpeed(iVal);
+ }
startTime = millis();
break;
- case 6: // Max. Speed HS
+ case 7: // Max. Speed HS
iVal = smuffConfig.maxSpeedHS_X;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
smuffConfig.maxSpeedHS_X = iVal;
+ steppers[SELECTOR].setMaxHSpeed(iVal);
+ }
startTime = millis();
break;
- case 7: // Acceleration
+ case 8: // Acceleration
iVal = smuffConfig.acceleration_X;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 60000))
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 60000, NULL, 50)) {
smuffConfig.acceleration_X = iVal;
+ steppers[SELECTOR].setAcceleration(iVal);
+ }
startTime = millis();
break;
- case 8: // Steps Per MM
+ case 9: // Offset
+ changeOffset(SELECTOR);
+ startTime = millis();
+ break;
+
+ case 10: // Steps Per MM
iVal = smuffConfig.stepsPerMM_X;
- if(showInputDialog(title, P_InSteps, &iVal, 1, 10000))
+ if(showInputDialog(title, P_InSteps, &iVal, 1, 10000)) {
smuffConfig.stepsPerMM_X = iVal;
+ steppers[SELECTOR].setStepsPerMM(iVal);
+ }
startTime = millis();
break;
}
@@ -806,11 +1048,11 @@ void showFeederMenu(char* menuTitle) {
bool bVal;
int iVal;
float fVal;
- char _menu[300];
+ char _menu[400];
do {
setupFeederMenu(_menu);
- //__debug(PSTR("Feeder Menu: %s %d"), _menu, strlen(_menu));
+ //__debug(PSTR("Feeder Menu: %s\nLen: %d"), _menu, strlen(_menu));
resetAutoClose();
stopMenu = checkStopMenu(startTime);
@@ -825,66 +1067,84 @@ void showFeederMenu(char* menuTitle) {
stopMenu = true;
break;
- case 2: // Invert dir
+ case 2: // TMC-Paramters
+ setupDriver = driverZ;
+ showTMCMenu(title, FEEDER);
+ startTime = millis();
+ break;
+
+ case 3: // Invert dir
bVal = smuffConfig.invertDir_Z;
- if(showInputDialog(title, P_YesNo, &bVal))
+ if(showInputDialog(title, P_YesNo, &bVal)) {
smuffConfig.invertDir_Z = bVal;
- startTime = millis();
- break;
-
- case 3: // Endstop trigger
- iVal = smuffConfig.endstopTrigger_Z;
- if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1))
- smuffConfig.endstopTrigger_Z = iVal;
- startTime = millis();
- break;
-
- case 4: // Step Delay
- iVal = smuffConfig.stepDelay_Z;
- if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100))
- smuffConfig.stepDelay_Z = iVal;
- startTime = millis();
- break;
-
- case 5: // Max. Speed
- iVal = smuffConfig.maxSpeed_Z;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
- smuffConfig.maxSpeed_Z = iVal;
- startTime = millis();
- break;
-
- case 6: // Max. Speed HS
- iVal = smuffConfig.maxSpeedHS_Z;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 50000))
- smuffConfig.maxSpeedHS_Z = iVal;
- startTime = millis();
- break;
-
- case 7: // Acceleration
- iVal = smuffConfig.acceleration_Z;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 60000)) {
- smuffConfig.acceleration_Z = iVal;
- if(smuffConfig.insertSpeed_Z > smuffConfig.acceleration_Z)
- smuffConfig.acceleration_Z = smuffConfig.insertSpeed_Z;
+ steppers[FEEDER].setInvertDir(bVal);
}
startTime = millis();
break;
- case 8: // Steps Per MM
- iVal = smuffConfig.stepsPerMM_Z;
- if(showInputDialog(title, P_InSteps, &iVal, 1, 10000))
- smuffConfig.stepsPerMM_Z = iVal;
+ case 4: // Endstop trigger
+ iVal = smuffConfig.endstopTrigger_Z;
+ if(showInputDialog(title, P_TriggerOn, &iVal, 0, 1)) {
+ smuffConfig.endstopTrigger_Z = iVal;
+ steppers[FEEDER].setEndstopState(iVal);
+ }
startTime = millis();
break;
- case 9: // Enable chunks
+ case 5: // Step Delay
+ iVal = smuffConfig.stepDelay_Z;
+ if(showInputDialog(title, P_InMicroseconds, &iVal, 0, 100)) {
+ smuffConfig.stepDelay_Z = iVal;
+ }
+ startTime = millis();
+ break;
+
+ case 6: // Max. Speed
+ iVal = smuffConfig.maxSpeed_Z;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
+ smuffConfig.maxSpeed_Z = iVal;
+ steppers[FEEDER].setMaxSpeed(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 7: // Max. Speed HS
+ iVal = smuffConfig.maxSpeedHS_Z;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 50000, NULL, 50)) {
+ smuffConfig.maxSpeedHS_Z = iVal;
+ steppers[FEEDER].setMaxHSpeed(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 8: // Acceleration
+ iVal = smuffConfig.acceleration_Z;
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 60000, NULL, 50)) {
+ smuffConfig.acceleration_Z = iVal;
+ if(smuffConfig.insertSpeed_Z > smuffConfig.acceleration_Z)
+ smuffConfig.acceleration_Z = smuffConfig.insertSpeed_Z;
+ steppers[FEEDER].setAcceleration(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 9: // Steps Per MM
+ iVal = smuffConfig.stepsPerMM_Z;
+ if(showInputDialog(title, P_InSteps, &iVal, 1, 10000)) {
+ smuffConfig.stepsPerMM_Z = iVal;
+ steppers[FEEDER].setStepsPerMM(iVal);
+ }
+ startTime = millis();
+ break;
+
+ case 10: // Enable chunks
bVal = smuffConfig.enableChunks;
if(showInputDialog(title, P_YesNo, &bVal))
smuffConfig.enableChunks = bVal;
startTime = millis();
break;
- case 10: // Feed chunks
+ case 11: // Feed chunks
iVal = smuffConfig.feedChunks;
if(showInputDialog(title, P_NoOfChunks, &iVal, 0, 100))
smuffConfig.feedChunks = iVal;
@@ -893,16 +1153,16 @@ void showFeederMenu(char* menuTitle) {
startTime = millis();
break;
- case 11: // Insert length
+ case 12: // Insert length
fVal = smuffConfig.insertLength;
if(showInputDialog(title, P_InMillimeter, &fVal, 1, smuffConfig.selectorDistance))
smuffConfig.insertLength = fVal;
startTime = millis();
break;
- case 12: // Insert Speed
+ case 13: // Insert Speed
iVal = smuffConfig.insertSpeed_Z;
- if(showInputDialog(title, P_InTicks, &iVal, 1, 60000)) {
+ if(showInputDialog(title, P_InTicks, &iVal, 1, 60000, NULL, 50)) {
smuffConfig.insertSpeed_Z = iVal;
if(smuffConfig.insertSpeed_Z > smuffConfig.acceleration_Z)
smuffConfig.acceleration_Z = smuffConfig.insertSpeed_Z;
@@ -910,12 +1170,27 @@ void showFeederMenu(char* menuTitle) {
startTime = millis();
break;
- case 13: // Reinforce length
+ case 14: // Reinforce length
fVal = smuffConfig.reinforceLength;
if(showInputDialog(title, P_InMillimeter, &fVal, 0, 10))
smuffConfig.reinforceLength = fVal;
startTime = millis();
break;
+
+ case 15: // Ext. Feeder Ctl
+ bVal = smuffConfig.externalControl_Z;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.externalControl_Z = bVal;
+ startTime = millis();
+ break;
+
+ case 16: // Shared Stepper
+ bVal = smuffConfig.isSharedStepper;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.isSharedStepper = bVal;
+ startTime = millis();
+ break;
+
}
}
} while(!stopMenu);
@@ -957,7 +1232,10 @@ void showSteppersMenu(char* menuTitle) {
break;
case 4: // Revolver or Servo
- showRevolverMenu(title);
+ if(smuffConfig.revolverIsServo)
+ showServoMenu(title);
+ else
+ showRevolverMenu(title);
current_selection = 1;
startTime = millis();
break;
@@ -1009,6 +1287,13 @@ void showDisplayMenu(char* menuTitle) {
selectBacklightColor(smuffConfig.backlightColor, title);
startTime = millis();
break;
+
+ case 5: // Encoder Ticks
+ bVal = smuffConfig.encoderTickSound;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.encoderTickSound = bVal;
+ startTime = millis();
+ break;
}
}
} while(!stopMenu);
@@ -1028,7 +1313,6 @@ void showSettingsMenu(char* menuTitle) {
do {
setupSettingsMenu(_menu);
- //__debug(PSTR("Settings Menu: %d %d"), strlen(_menu), 0 /*freeMemory()*/);
resetAutoClose();
stopMenu = checkStopMenu(startTime);
@@ -1064,70 +1348,37 @@ void showSettingsMenu(char* menuTitle) {
startTime = millis();
break;
- case 5: // Menu auto close
- iVal = smuffConfig.menuAutoClose;
- if(showInputDialog(title, P_InSeconds, &iVal, 0, 300))
- smuffConfig.menuAutoClose = iVal;
+ case 5: // Separator
+ break;
+
+ case 6: // Options
+ showOptionsMenu(title);
+ current_selection = 1;
startTime = millis();
break;
- case 6: // Fan speed
- iVal = smuffConfig.fanSpeed;
- if(showInputDialog(title, P_InPercent, &iVal, 0, 100)) {
- smuffConfig.fanSpeed = iVal;
- #if defined (__STM32F1__)
- pwmWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 255));
- #elif defined (__ESP32__)
- ledcWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 255));
- #else
- analogWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 255));
- #endif
- }
- startTime = millis();
- break;
-
- case 7: // Prusa Emulation
- bVal = smuffConfig.prusaMMU2;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.prusaMMU2 = bVal;
- startTime = millis();
- break;
-
- case 8: // Send Status Info
- bVal = smuffConfig.sendPeriodicalStats;
- if(showInputDialog(title, P_YesNo, &bVal))
- smuffConfig.sendPeriodicalStats = bVal;
- startTime = millis();
- break;
-
- case 9: // Baudrates
+ case 7: // Baudrates
showBaudratesMenu(title);
current_selection = 1;
startTime = millis();
break;
- case 10: // Offsets
- showOffsetsMenu(title);
- current_selection = 1;
- startTime = millis();
- break;
-
- case 11: // Steppers
+ case 8: // Steppers
showSteppersMenu(title);
current_selection = 1;
startTime = millis();
break;
- case 12: // Display
+ case 9: // Display
showDisplayMenu(title);
current_selection = 1;
startTime = millis();
break;
- case 13: // Separator
+ case 10: // Separator
break;
- case 14: // STORE CONFIG
+ case 11: // STORE CONFIG
if(writeConfig()) {
beep(1);
sprintf_P(msg, P_ConfigWriteSuccess);
@@ -1146,6 +1397,88 @@ void showSettingsMenu(char* menuTitle) {
} while(!stopMenu);
}
+void setLiveFanSpeed(int val) {
+ #if defined (__STM32F1__)
+ fan.setFanSpeed(val);
+ #elif defined (__ESP32__)
+ ledcWrite(FAN_PIN, map(val, 0, 100, 0, 255));
+ #else
+ analogWrite(FAN_PIN, map(val, 0, 100, 0, 255));
+ #endif
+}
+
+void showOptionsMenu(char* menuTitle) {
+ bool stopMenu = false;
+ unsigned int startTime = millis();
+ uint8_t current_selection = 0;
+ float fVal;
+ int iVal;
+ bool bVal;
+ char *title;
+ char msg[128];
+ char _menu[300];
+
+ do {
+ setupOptionsMenu(_menu);
+ resetAutoClose();
+ stopMenu = checkStopMenu(startTime);
+
+ current_selection = display.userInterfaceSelectionList(menuTitle, current_selection, _menu);
+
+ if(current_selection == 0)
+ return;
+ else {
+ title = extractTitle(_menu, current_selection-1);
+ switch(current_selection) {
+ case 1:
+ stopMenu = true;
+ break;
+
+ case 2: // Menu auto close
+ iVal = smuffConfig.menuAutoClose;
+ if(showInputDialog(title, P_InSeconds, &iVal, 0, 300))
+ smuffConfig.menuAutoClose = iVal;
+ startTime = millis();
+ break;
+
+ case 3: // Fan speed
+ iVal = smuffConfig.fanSpeed;
+ if(showInputDialog(title, P_InPercent, &iVal, 0, 100, setLiveFanSpeed)) {
+ smuffConfig.fanSpeed = iVal;
+ }
+ startTime = millis();
+ break;
+
+ case 4: // Prusa Emulation
+ bVal = smuffConfig.prusaMMU2;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.prusaMMU2 = bVal;
+ startTime = millis();
+ break;
+
+ case 5: // Send Status Info
+ bVal = smuffConfig.sendPeriodicalStats;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.sendPeriodicalStats = bVal;
+ startTime = millis();
+ break;
+
+ case 6: // Duet Laser Sensor
+ bVal = smuffConfig.useDuetLaser;
+ if(showInputDialog(title, P_YesNo, &bVal))
+ smuffConfig.useDuetLaser = bVal;
+ startTime = millis();
+ break;
+
+ case 7: // PanelDue
+ selectPanelDuePort(title);
+ startTime = millis();
+ break;
+ }
+ }
+ } while(!stopMenu);
+}
+
void drawSwapTool(int from, int with) {
char tmp[256];
sprintf_P(tmp, P_SwapToolDialog, from, with);
@@ -1215,7 +1548,7 @@ void showBaudratesMenu(char* menuTitle) {
unsigned int startTime = millis();
uint8_t current_selection = 0;
char* title;
- char _menu[128];
+ char _menu[300];
do {
setupBaudrateMenu(_menu);
@@ -1234,29 +1567,41 @@ void showBaudratesMenu(char* menuTitle) {
break;
case 2:
- selectBaudrate(1, title);
+ selectBaudrate(0, title);
current_selection = 1;
startTime = millis();
break;
case 3:
+ selectBaudrate(1, title);
+ current_selection = 1;
+ startTime = millis();
+ break;
+
+ case 4:
selectBaudrate(2, title);
current_selection = 1;
startTime = millis();
break;
+
+ case 5:
+ selectBaudrate(3, title);
+ current_selection = 1;
+ startTime = millis();
+ break;
}
}
} while(!stopMenu);
}
-void showOffsetsMenu(char* menuTitle) {
+void showStatusInfoMenu(char* menuTitle) {
bool stopMenu = false;
unsigned int startTime = millis();
uint8_t current_selection = 0;
char _menu[120];
do {
- setupOffsetMenu(_menu);
+ setupStatusInfoMenu(_menu);
//__debug(PSTR("Offsets Menu: %s %d %d"), _menu, strlen(_menu), 0 /*freeMemory()*/);
resetAutoClose();
stopMenu = checkStopMenu(startTime);
@@ -1272,14 +1617,28 @@ void showOffsetsMenu(char* menuTitle) {
break;
case 2:
- changeOffset(SELECTOR);
- current_selection = 1;
+ if(smuffConfig.useDuetLaser)
+ showDuetLS();
+ else {
+ debounceButton();
+ drawUserMessage(P_DuetLSDisabled);
+ delay(3000);
+ }
startTime = millis();
break;
-
+
case 3:
- changeOffset(REVOLVER);
- current_selection = 1;
+ showTMCStatus(SELECTOR);
+ startTime = millis();
+ break;
+
+ case 4:
+ showTMCStatus(REVOLVER);
+ startTime = millis();
+ break;
+
+ case 5:
+ showTMCStatus(FEEDER);
startTime = millis();
break;
}
@@ -1383,18 +1742,15 @@ void showToolsMenu() {
stopMenu = true;
else {
int tool = toolSelections[current_selection-2];
- if(!smuffConfig.duetDirect) {
+ if(!smuffConfig.sendActionCmds) {
selectTool(tool);
}
else {
- //selectTool(tool);
- // the duetDirect flag is a synonym of "communicate directly with the controller attached"
- if(smuffConfig.duetDirect) {
- sprintf(_tmp, "//action: T%d\n", tool);
- printResponse(_tmp, 0);
- printResponse(_tmp, 1);
- printResponse(_tmp, 2);
- }
+ // send "Tool Change" action to controller
+ sprintf(_tmp, "//action: T%d\n", tool);
+ printResponse(_tmp, 0);
+ printResponse(_tmp, 1);
+ printResponse(_tmp, 2);
// TODO: do tool change using Duet3D
// not yet possible due to Duet3D is being blocked waiting for endstop
/*
diff --git a/src/Periodicals.cpp b/src/Periodicals.cpp
new file mode 100644
index 0000000..c55eb9a
--- /dev/null
+++ b/src/Periodicals.cpp
@@ -0,0 +1,122 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include "SMuFF.h"
+
+volatile bool interval10ms; // set each time when function is called; reset yourself if needed
+volatile bool interval20ms;
+volatile bool interval50ms;
+volatile bool interval100ms;
+volatile bool interval250ms;
+volatile bool interval500ms;
+volatile bool interval1s;
+volatile bool interval2s;
+volatile bool interval5s;
+static volatile uint32_t last10ms;
+static volatile uint32_t last20ms;
+static volatile uint32_t last50ms;
+static volatile uint32_t last100ms;
+static volatile uint32_t last250ms;
+static volatile uint32_t last500ms;
+static volatile uint32_t last1s;
+static volatile uint32_t last2s;
+static volatile uint32_t last5s;
+
+void every10ms() {
+ if(millis()-last10ms < 10)
+ return;
+ last10ms = millis();
+ interval10ms = true;
+ // Add your periodical code here
+}
+
+void every20ms() {
+ if(millis()-last20ms < 20)
+ return;
+ last20ms = millis();
+ interval20ms = true;
+ // Add your periodical code here
+}
+
+void every50ms() {
+ if(millis()-last50ms < 50)
+ return;
+ last50ms = millis();
+ interval50ms = true;
+ // Add your periodical code here
+}
+
+void every100ms() {
+ if(millis()-last100ms < 100)
+ return;
+ last100ms = millis();
+ interval100ms = true;
+ // Add your periodical code here
+}
+
+void every250ms() {
+ if(millis()-last250ms < 250)
+ return;
+ last250ms = millis();
+ interval250ms = true;
+ // Add your periodical code here
+}
+
+void every500ms() {
+ if(millis()-last500ms < 500)
+ return;
+ last500ms = millis();
+ interval500ms = true;
+ // Add your periodical code here
+}
+
+void every1s() {
+ if(millis()-last1s < 1000)
+ return;
+ last1s = millis();
+ interval1s = true;
+ // Add your periodical code here
+}
+
+void every2s() {
+ if(millis()-last2s < 2000)
+ return;
+ last2s = millis();
+ interval2s = true;
+
+ if(parserBusy || sendingResponse) {
+ __debug(PSTR("Parser busy: %s Sending Response: %s"), parserBusy ? P_Yes : P_No, sendingResponse ? P_Yes : P_No);
+ }
+ // send status of endstops and current tool to all listeners, if configured
+ if(!sendingResponse && smuffConfig.sendPeriodicalStats && enablePeriStat && !parserBusy) {
+ printPeriodicalState(0);
+ if(CAN_USE_SERIAL1) printPeriodicalState(1);
+ if(CAN_USE_SERIAL2 && smuffConfig.hasPanelDue != 2) printPeriodicalState(2);
+ if(CAN_USE_SERIAL3 && smuffConfig.hasPanelDue != 3) printPeriodicalState(3);
+ }
+ // Add your periodical code here
+}
+
+void every5s() {
+ if(millis()-last5s < 5000)
+ return;
+ last5s = millis();
+ interval5s = true;
+ // Add your periodical code here
+}
+
diff --git a/src/SMuFF.cpp b/src/SMuFF.cpp
index 37cfee7..b1bcb79 100644
--- a/src/SMuFF.cpp
+++ b/src/SMuFF.cpp
@@ -18,30 +18,29 @@
*/
#include "SMuFF.h"
#include "Config.h"
-#include "ZTimerLib.h"
-#include "ZStepperLib.h"
-#include "ZServo.h"
-#include "ZPortExpander.h"
-#include "DuetLaserSensor.h"
+// Please notice: If you make any changes / additions here, you'll have to add
+// an "external" declaration in SMuFF.h as well
#ifdef __BRD_I3_MINI
U8G2_ST7565_64128N_F_4W_HW_SPI display(U8G2_R2, /* cs=*/ DSP_CS_PIN, /* dc=*/ DSP_DC_PIN, /* reset=*/ DSP_RESET_PIN);
#endif
-#ifdef __BRD_SKR_MINI
+#if defined(__BRD_SKR_MINI) || defined(__BRD_SKR_MINI_E3) || defined(__BRD_SKR_MINI_E3DIP)
#ifdef USE_TWI_DISPLAY
U8G2_SSD1306_128X64_NONAME_F_HW_I2C display(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#elif USE_ANET_DISPLAY
- /*
- Attn.: In order to use this display you have to make some heavy modifications on the wiring
- for the display connector!
- Instructions can be found here: https://www.thingiverse.com/thing:4009810
- */
+ //
+ // Attn.: Instructions to modify the ANET display can be found here: https://www.thingiverse.com/thing:4009810
+ //
+ #pragma error "Before you use this display, you have to make some heavy modifications on the wiring for the display connector! Please check, then comment out this line."
U8G2_ST7920_128X64_F_2ND_HW_SPI display(U8G2_R0, /* cs=*/ DSP_CS_PIN, /* reset=*/ U8X8_PIN_NONE);
// if the hardware SPI doesn't work, you may try software SPI instead
- //U8G2_ST7920_128X64_F_SW_SPI display(U8G2_R0, /* clock=*/ DSP_DC, /* data=*/ DSP_DATA, /* cs=*/ DSP_CS, /* reset=*/ U8X8_PIN_NONE);
+ //U8G2_ST7920_128X64_F_SW_SPI display(U8G2_R0, /* clock=*/ DSP_DC_PIN, /* data=*/ DSP_DATA_PIN, /* cs=*/ DSP_CS_PIN, /* reset=*/ U8X8_PIN_NONE);
#elif USE_MINI12864_PANEL_V21
U8G2_ST7567_JLX12864_F_2ND_4W_HW_SPI display(U8G2_R0, /* cs=*/ DSP_CS_PIN, /* dc=*/ DSP_DC_PIN, /* reset=*/ DSP_RESET_PIN);
+ #elif USE_CREALITY_DISPLAY
+ // works only with software SPI, hence it's remarkably slower than hardware SPI
+ U8G2_ST7920_128X64_F_SW_SPI display(U8G2_R0, /* clock=*/ DSP_DC_PIN, /* data=*/ DSP_DATA_PIN, /* cc=*/ DSP_CS_PIN, /* reset=*/ DSP_RESET_PIN);
#else
// Notice: This constructor is feasible for the MKS-MINI12864 V2.0 RepRap display
U8G2_ST7567_ENH_DG128064_F_2ND_4W_HW_SPI display(U8G2_R2, /* cs=*/ DSP_CS_PIN, /* dc=*/ DSP_DC_PIN, /* reset=*/ DSP_RESET_PIN);
@@ -65,56 +64,71 @@ U8G2_UC1701_MINI12864_F_4W_HW_SPI display(U8G2_R0, /* cs=*/ DSP_CS_PIN, /* dc=*/
#if defined(__ESP32__)
BluetoothSerial SerialBT; // used for debugging or mirroring traffic to PanelDue
#if defined(__DEBUG_BT__)
-Stream* debugSerial = &SerialBT; // decide which serial port to use for debug outputs
+Stream* debugSerial = &SerialBT; // decide which serial port to use for debug outputs
#else
-Stream* debugSerial = &Serial; // decide which serial port to use for debug outputs
+Stream* debugSerial = &Serial; // decide which serial port to use for debug outputs
#endif
+HardwareSerial Serial3(1); // dummy declaration to keep the compiler happy,
+ // won't be used though because of the CAN_USE_SERIAL3 definition
#elif defined(__STM32F1__)
-Stream* debugSerial = &Serial1;
+ #if defined(__BRD_SKR_MINI_E3) || defined(__BRD_SKR_MINI_E3DIP)
+Stream* debugSerial = &Serial2;
+ #else
+Stream* debugSerial = &Serial1;
+ #endif
#else
Stream* debugSerial = &Serial;
#endif
+
ZStepper steppers[NUM_STEPPERS];
ZTimer stepperTimer;
-ZTimer encoderTimer;
+ZTimer gpTimer;
ZServo servo;
ZServo servoRevolver;
+ZFan fan;
+DuetLaserSensor duetLS;
+ClickEncoder encoder(ENCODER1_PIN, ENCODER2_PIN, ENCODER_BUTTON_PIN, 4);
+#if defined(USE_SW_SERIAL)
+SoftwareSerial swSer0(SW_SERIAL_RX_PIN, SW_SERIAL_TX_PIN, false);
+#endif
#if defined(__ESP32__)
ZPortExpander portEx;
#endif
-DuetLaserSensor duetLS;
-ClickEncoder encoder(ENCODER1_PIN, ENCODER2_PIN, ENCODER_BUTTON_PIN, 4);
+#if defined(__STM32F1__)
+USBMassStorage MassStorage;
+USBCompositeSerial CompositeSerial;
+#endif
-volatile byte nextStepperFlag = 0;
-volatile byte remainingSteppersFlag = 0;
-volatile unsigned long lastEncoderButtonTime = 0;
-bool testMode = false;
-int toolSelections[MAX_TOOLS];
-volatile unsigned long pwrSaveTime;
-volatile bool isPwrSave = false;
-volatile bool showMenu = false;
-volatile bool lastZEndstopState = false;
-volatile bool lastZEndstop2State = false;
-unsigned long endstopZ2HitCnt = 0;
-static unsigned long lastDisplayRefresh = 0;
-volatile unsigned long generalCounter = 0;
-volatile int bracketCnt = 0;
-volatile int jsonPtr = 0;
-//char jsonData[MAX_JSON]; // temporary buffer for json data coming from Duet3D (not used yet)
-volatile bool enablePS = false;
-
-String serialBuffer0, serialBuffer2, serialBuffer9;
-String traceSerial2;
-String _hostname = "";
-
-extern int swapTools[MAX_TOOLS];
-extern void setToneTimerChannel(uint8_t ntimer, uint8_t channel); // defined in tone library
+TMC2209Stepper* driverX = NULL;
+TMC2209Stepper* driverY = NULL;
+TMC2209Stepper* driverZ = NULL;
+TMC2209Stepper* driverE = NULL;
-void isrStepperHandler(); // forward declarations ... makes every compiler happy
-void isrEncoderHandler();
-void refreshStatus(bool withLogo);
-
+String wirelessHostname = "";
+volatile byte nextStepperFlag = 0;
+volatile byte remainingSteppersFlag = 0;
+volatile unsigned long lastEncoderButtonTime = 0;
+bool testMode = false;
+int toolSelections[MAX_TOOLS];
+volatile unsigned long pwrSaveTime;
+volatile bool isPwrSave = false;
+volatile bool showMenu = false;
+volatile bool lastZEndstopState = false;
+volatile bool lastZEndstop2State = false;
+unsigned long endstopZ2HitCnt = 0;
+static unsigned long lastDisplayRefresh = 0;
+static volatile unsigned long generalCounter = 0;
+static volatile unsigned long tickCounter = 0;
+volatile int bracketCnt = 0;
+volatile int jsonPtr = 0;
+//char jsonData[MAX_JSON]; // temporary buffer for json data coming from Duet3D (not used yet)
+volatile bool enablePeriStat = false; // enables sending periodical status information to serial ports
+volatile bool processingSerial0; // set when GCode is incoming on a serial port
+volatile bool processingSerial1;
+volatile bool processingSerial2;
+volatile bool processingSerial3;
+String serialBuffer0, serialBuffer1, serialBuffer2, serialBuffer3, serialBuffer9, traceSerial2;
#ifdef __STM32F1__
volatile uint32_t *stepper_reg_X = &((PIN_MAP[X_STEP_PIN].gpio_device)->regs->BSRR);
@@ -123,7 +137,6 @@ volatile uint32_t *stepper_reg_Z = &((PIN_MAP[Z_STEP_PIN].gpio_device)->regs->BS
uint32_t pinMask_X = BIT(PIN_MAP[X_STEP_PIN].gpio_bit);
uint32_t pinMask_Y = BIT(PIN_MAP[Y_STEP_PIN].gpio_bit);
uint32_t pinMask_Z = BIT(PIN_MAP[Z_STEP_PIN].gpio_bit);
-
#endif
void overrideStepX() {
@@ -134,7 +147,8 @@ void overrideStepX() {
*stepper_reg_X = pinMask_X << 16;
#else
STEP_HIGH_X
- // if(smuffConfig.delayBetweenPulses) __asm__ volatile ("nop");
+ if(smuffConfig.stepDelay_X > 0)
+ delayMicroseconds(smuffConfig.stepDelay_X);
STEP_LOW_X
#endif
}
@@ -147,7 +161,8 @@ void overrideStepY() {
*stepper_reg_Y = pinMask_Y << 16;
#else
STEP_HIGH_Y
- // if(smuffConfig.delayBetweenPulses) __asm__ volatile ("nop");
+ if(smuffConfig.stepDelay_Y > 0)
+ delayMicroseconds(smuffConfig.stepDelay_Y);
STEP_LOW_Y
#endif
}
@@ -160,113 +175,53 @@ void overrideStepZ() {
*stepper_reg_Z = pinMask_Z << 16;
#else
STEP_HIGH_Z
- // if(smuffConfig.delayBetweenPulses) __asm__ volatile ("nop");
+ if(smuffConfig.stepDelay_Z > 0)
+ delayMicroseconds(smuffConfig.stepDelay_Z);
STEP_LOW_Z
#endif
}
-void endstopYevent() {
+void endstopEventY() {
+ // add your code here it you want to hook into the endstop event for the Revolver
//__debug(PSTR("Endstop Revolver: %d"), steppers[REVOLVER].getStepPosition());
}
-void endstopZevent() {
+void endstopEventZ() {
+ // add your code here it you want to hook into the 1st endstop event for the Feeder
//__debug(PSTR("Endstop Revolver: %d"), steppers[REVOLVER].getStepPosition());
}
-void endstopZ2event() {
-}
-
-void duetLSHandler() {
- duetLS.service();
-}
-
-volatile boolean interval20ms;
-void every20ms() {
- interval20ms = true;
- // do the servos interrupt routines so we save one timer
- if(!servo.hasTimer())
- servo.setServo();
- if(!servoRevolver.hasTimer())
- servoRevolver.setServo();
-}
-
-volatile boolean interval100ms;
-void every100ms() {
- interval100ms = true;
- // Add your periodical code here
-}
-
-volatile boolean interval250ms;
-void every250ms() {
- interval250ms = true;
- // Add your periodical code here
-}
-
-volatile boolean interval500ms;
-void every500ms() {
- interval500ms = true;
- // Add your periodical code here
-}
-
-volatile unsigned long lastTick;
-volatile unsigned gcInterval;
-volatile boolean interval1s;
-void every1s() {
- interval1s = true;
- unsigned long tmp = millis();
- gcInterval = tmp-lastTick;
- lastTick = tmp;
- // Add your periodical code here
-#if defined(__STM32F1__)
- // __debug("%d ms", gcInterval);
-#endif
-}
-
-void every2s() {
- // send status of endstops and current tool to all listeners, if configured
- if(!sendingResponse && smuffConfig.sendPeriodicalStats && enablePS && !parserBusy) {
- printPeriodicalState(0);
- printPeriodicalState(1);
- printPeriodicalState(2);
- }
-}
-
-volatile boolean interval5s;
-void every5s() {
- interval5s = true;
- // Add your periodical code here
+void endstopEventZ2() {
+ // add your code here it you want to hook into the 2nd endstop event for the Feeder
}
/*
- Handles the timer interrupt for the rotary encoder.
- Also serves as a general purpose timer dispatcher since the
- interrupt occures every millisecond.
+ Used as a callback from ZStepper library to check stall on stepper
+ while moving (if TMC drivers are being used).
+ Returns true if a stall was detected, false otherwise.
*/
-void isrEncoderHandler() {
- encoder.service();
- generalCounter++;
- if(generalCounter % 20 == 0) { // every 20 ms
- every20ms();
+bool stallCheckX() {
+ if(driverX != NULL) {
+ bool stat = driverX->SG_RESULT() < driverX->SGTHRS();
+ return stat;
}
- if(generalCounter % 100 == 0) { // every 100 ms
- every100ms();
+ return false;
+}
+
+bool stallCheckY() {
+ if(driverY != NULL) {
+ bool stat = driverY->SG_RESULT() < driverY->SGTHRS();
+ return stat;
}
- if(generalCounter % 250 == 0) { // every 250 ms
- every250ms();
+ return false;
+}
+
+bool stallCheckZ() {
+ if(driverZ != NULL) {
+ bool stat = driverZ->SG_RESULT() < driverZ->SGTHRS();
+ return stat;
}
- if(generalCounter % 500 == 0) { // every 500 ms
- every500ms();
- }
- if(generalCounter % 1000 == 0) { // every 1000 ms
- every1s();
- }
- if(generalCounter % 2000 == 0) { // every 2000 ms
- every2s();
- }
- if(generalCounter % 5000 == 0) { // every 5000 ms
- every5s();
- }
- //duetLSHandler();
+ return false;
}
bool checkDuetEndstop() {
@@ -276,227 +231,83 @@ bool checkDuetEndstop() {
return false;
}
-void blinkLED() {
-#if defined(LED_PIN)
- if(LED_PIN != -1)
- digitalWrite(LED_PIN, !digitalRead(LED_PIN));
-#endif
-}
-
-void setupDeviceName() {
- String appendix = "";
-#if defined(__ESP32__)
- appendix = WiFi.macAddress().substring(9);
- appendix.replace(":", "");
-#endif
- _hostname = String("SMuFF") + "_" + appendix;
-}
-
/*
- Initialize FastLED library for NeoPixels.
- Primarily used for backlight on some displays (i.e. FYSETC 12864 Mini V2.1)
+ Handles the genaral purpose timer interrupt.
+ Fires every 50uS and thus increments the generalCounter
+ every millisecond.
+ Also serves as a handler dispatcher for servos / encoder.
*/
-void initFastLED() {
- #if NEOPIXEL_PIN != -1
- FastLED.addLeds(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
- FastLED.setBrightness(BRIGHTNESS);
- #endif
+void isrGPTimerHandler() {
+ cli();
+ tickCounter++; // increment tick counter
+ if(tickCounter % 20) { // after one ms
+ generalCounter++; // increment milliseconds counter
+ encoder.service(); // service the rotary encoder
+ if(smuffConfig.useDuetLaser) {
+ duetLS.service(); // service the Duet3D laser Sensor reader
+ }
+ #if defined(__HW_DEBUG__) && defined(DEBUG_PIN)
+ // used for internal hardware debugging only - will produce a 500Hz signal on the output pin
+ if(DEBUG_PIN != -1) digitalWrite(DEBUG_PIN, !digitalRead(DEBUG_PIN));
+ #endif
+ }
+ // call the servos & fan interrupt routines also every 50uS
+ isrServoTimerHandler();
+ isrFanTimerHandler();
+ sei();
}
void setup() {
-#ifdef __STM32F1__
- #ifndef USE_TWI_DISPLAY
- #ifdef STM32_REMAP_SPI
- afio_remap(AFIO_REMAP_SPI1); // remap SPI3 to SPI1 if a "normal" display is being used
- #endif
-
- #warning("**** Don't forget to short Z+ input to GND for programming the device! ****")
- if(DEBUG_OFF_PIN != -1) {
- pinMode(DEBUG_OFF_PIN, INPUT_PULLUP);
- /* ============ WARNING ================
- If debug ports (JTAG) are disabled, you won't
- be able to program the device via STLink anymore!
- Therefore, before programming the device,
- set Z+ input to ground and reset the device
- to reenable debug ports.
- =====================================*/
- if(digitalRead(DEBUG_OFF_PIN)==HIGH)
- disableDebugPorts(); // disable JTAG if Z+ is unconnected
- }
- #endif
-#endif
-
- delay(500);
-
- serialBuffer0.reserve(40);
+ serialBuffer0.reserve(40); // initialize serial comm. buffers
+ serialBuffer1.reserve(40);
serialBuffer2.reserve(40);
+ serialBuffer3.reserve(40);
traceSerial2.reserve(40);
-
- initFastLED();
- testFastLED();
-#if defined(USE_RGB_BACKLIGHT) || defined(USE_FASTLED_BACKLIGHT)
- setBacklightIndex(7); // set backlight color to white by default - gets overwritten after config has been read
-#endif
-
- setupDeviceName();
-
-#ifdef __ESP32__
- // this line must be kept, otherwise BT power down will cause a reset
- SerialBT.begin(_hostname);
- if(BEEPER_PIN != -1) {
- ledcSetup(BEEPER_CHANNEL, 5000, 8);
- ledcAttachPin(BEEPER_PIN, BEEPER_CHANNEL);
- }
-#endif
-
- Serial.begin(115200); // set fixed baudrate until config file was read
-#if defined(__STM32F1__)
- Serial1.begin(115200);
- Serial2.begin(115200);
- Serial3.begin(115200);
-#else
- Serial2.begin(115200);
-#endif
- //__debug(PSTR("[ setup() ]"));
-
- setupDisplay();
- readConfig();
-// turn on the LCD backlight accroding to the configured setting
-#if defined(USE_RGB_BACKLIGHT) || defined(USE_FASTLED_BACKLIGHT)
- setBacklightIndex(smuffConfig.backlightColor);
-#endif
-
-
- // special case:
- // if the baudrate is set to 0, the board is running out of working memory
- if(smuffConfig.serial1Baudrate != 0) {
- if(smuffConfig.serial1Baudrate != 115200) {
- Serial.end();
- Serial.begin(smuffConfig.serial1Baudrate);
- }
- }
- else {
- writeConfig(&Serial);
- longBeep(3);
- showDialog(P_TitleConfigError, P_ConfigFail1, P_ConfigFail4, P_OkButtonOnly);
- }
-
-#ifndef __AVR__
- Serial1.begin(smuffConfig.serial2Baudrate);
- Serial2.begin(smuffConfig.serial2Baudrate);
- #ifndef __ESP32__
- Serial3.begin(smuffConfig.serial2Baudrate);
+ #if defined(__BRD_FYSETC_AIOII) || defined(__BRD_SKR_MINI_E3DIP) || defined(__BRD_SKR_MINI)
+ // Disable JTAG for these boards!
+ // On the FYSETC AIOII it's because of the display DSP_DC_PIN/DOG_A0 signal (PA15 / JTDI).
+ // On the SKR MINI E3-DIP it's because of the buzzer signal (PA15 / JTDI).
+ disableDebugPorts();
#endif
-#else
-#endif
- //__debug(PSTR("DONE init SERIAL"));
+ initUSB(); // init the USB serial so it's being recognized by the Windows-PC
+ delay(500);
+ initFastLED(); // init FastLED if configured
+ testFastLED(); // run a test sequence on FastLEDs
+ initHwDebug(); // init hardware debugging
+
+ // Setup a fixed baudrate until the config file was read.
+ // This baudrate is the default setting on the ESP32 while
+ // booting up, so exceptions thrown can be shown in terminal app
+ Serial.begin(115200);
+ if(CAN_USE_SERIAL1) Serial1.begin(115200);
+ if(CAN_USE_SERIAL2) Serial2.begin(115200);
+ if(CAN_USE_SERIAL3) Serial3.begin(115200);
+ //__debug(PSTR("[ setup() ]"));
+ setupBuzzer(); // setup buzzer before reading config
+ setupDeviceName(); // used for SerialBT on ESP32 only
+ setupSerialBT(); // used for debugging on ESP32 only
+ setupDisplay(); // setup display first in order to show error messages if neccessary
+ readConfig(); // read SMUFF.CFG from SD-Card
+ setupSerial(); // setup all components according to the values in SMUFF.CFG
setupSteppers();
setupTimers();
-
- if(SERVO1_PIN != -1) {
- servo.setMaxCycles(smuffConfig.servoCycles1);
- servo.setPulseWidthMinMax(smuffConfig.servoMinPwm, smuffConfig.servoMaxPwm);
- #if defined(__ESP32__)
- // we'll be using the internal ledcWrite for servo control on ESP32
- servo.attach(SERVO1_PIN, false, 0);
- #elif defined(__STM32F1__)
- servo.attach(SERVO1_PIN, true, 0);
- #else
- servo.attach(SERVO1_PIN, true, 0);
- #endif
- setServoPos(0, 90);
- }
-
- // Replace the Revolver stepper motor with a servo motor
- if(SERVO2_PIN != -1) {
- servoRevolver.setMaxCycles(smuffConfig.servoCycles2);
- servoRevolver.setPulseWidthMinMax(smuffConfig.servoMinPwm, smuffConfig.servoMaxPwm);
- #if defined(__ESP32__)
- // we'll be using the internal ledcWrite for servo control on ESP32
- servoRevolver.attach(SERVO2_PIN, false, 1);
- #elif defined(__STM32F1__)
- servoRevolver.attach(SERVO2_PIN, true, 1);
- #else
- servoRevolver.attach(SERVO2_PIN, true, 1);
- #endif
- setServoPos(1, smuffConfig.revolverOffPos);
- }
- // this call must happen after setupSteppers()
- getStoredData();
+ setupServos();
+ setupRelay();
+ setupTMCDrivers(); // setup TMC drivers if any were used
+ setupSwSerial0(); // used only for testing purposes
+ setupBacklight();
+ setupDuetLaserSensor(); // setup other peripherials
+ setupEncoder();
+ setupHeaterBed();
+ setupFan();
+ setupPortExpander();
+ setupI2C();
+ getStoredData(); // read EEPROM.DAT from SD-Card; this call must happen after setupSteppers()
+ readTune();
- // Duet Laser Sensor is not being used yet because the
- // measurements are somewhat unreliable. Not sure whether it's the
- // sensor itself or just some mechanical issue.
- /*
- if(smuffConfig.useDuetLaser) {
- duetLS.attach(Z_END_PIN);
- }
- */
-
- // Please note: All the PWM pins on the SKR are not working as
- // expected. Maybe it's a common libmaple issue, maybe it's a
- // STM32 timer related thing or maybe it's the
- // hardware design of the board itself.
- // Can't tell for sure, need some more investigation.
- if(HEATER0_PIN != -1) {
- pinMode(HEATER0_PIN, OUTPUT);
- }
-#if defined(__STM32F1__) || defined(__ESP32__)
- if(HEATBED_PIN != -1) {
- #if defined(__STM32F1__)
- pinMode(HEATBED_PIN, PWM);
- #else
- pinMode(HEATBED_PIN, OUTPUT);
- #endif
- }
-#endif
-
- if(FAN_PIN != -1) {
-#ifdef __STM32F1__
- pinMode(FAN_PIN, PWM);
-#elif defined(__ESP32__)
- ledcSetup(FAN_CHANNEL, FAN_FREQ, 8);
- ledcAttachPin(FAN_PIN, FAN_CHANNEL);
- //__debug(PSTR("DONE FAN PIN CONFIG"));
-#else
- pinMode(FAN_PIN, OUTPUT);
-#endif
- if(smuffConfig.fanSpeed >= 0 && smuffConfig.fanSpeed <= 100) {
- #if defined (__ESP32__)
- ledcWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 65535));
- #elif defined(__STM32F1__)
- analogWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 65535));
- #else
- analogWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 255));
- #endif
- }
- //__debug(PSTR("DONE FAN init"));
- #if defined( __ESP32__)
- // init the PCF8574 port expander and set pin modes (0-5 OUTPUT, 6-7 INPUT)
- portEx.begin(PORT_EXPANDER_ADDRESS, false);
- for(int i=0; i< 6; i++) {
- portEx.pinMode(i, OUTPUT);
- portEx.setPin(i);
- }
- portEx.pinMode(6, INPUT_PULLUP);
- portEx.pinMode(7, INPUT_PULLUP);
- portEx.resetPin(0);
- //__debug(PSTR("DONE PortExpander init"));
- #endif
- }
-
-#ifdef __AVR__
- // We can't do Master and Slave on this device.
- // Slave mode is used for the I2C OLE Display on SKR mini
- if(smuffConfig.i2cAddress != 0) {
- Wire.begin(smuffConfig.i2cAddress);
- Wire.onReceive(wireReceiveEvent);
- }
- //__debug(PSTR("DONE I2C init"));
- #endif
if(smuffConfig.homeAfterFeed) {
moveHome(REVOLVER, false, false);
}
@@ -505,116 +316,18 @@ void setup() {
}
//__debug(PSTR("DONE reset Revolver"));
- sendStartResponse(0);
- if(smuffConfig.prusaMMU2) {
-#ifdef __STM32F1__
- sendStartResponse(1);
- sendStartResponse(3);
-#else
+ sendStartResponse(0); // send "start" to USB serial interface
+ if(CAN_USE_SERIAL1)
+ sendStartResponse(1); // send "start" to all serial interfaces allowed to use
+ if(CAN_USE_SERIAL2 && smuffConfig.hasPanelDue != 2)
sendStartResponse(2);
-#endif
- }
-
- pwrSaveTime = millis();
-
- initBeep();
- enablePS = true; // enable periodically sending status, if configured
-}
+ if(CAN_USE_SERIAL3 && smuffConfig.hasPanelDue != 3)
+ sendStartResponse(3);
-void setupSteppers() {
-
- steppers[SELECTOR] = ZStepper(SELECTOR, (char*)"Selector", X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, smuffConfig.acceleration_X, smuffConfig.maxSpeed_X);
- steppers[SELECTOR].setEndstop(X_END_PIN, smuffConfig.endstopTrigger_X, ZStepper::MIN);
- steppers[SELECTOR].stepFunc = overrideStepX;
- steppers[SELECTOR].setMaxStepCount(smuffConfig.maxSteps_X);
- steppers[SELECTOR].setStepsPerMM(smuffConfig.stepsPerMM_X);
- steppers[SELECTOR].setInvertDir(smuffConfig.invertDir_X);
- steppers[SELECTOR].setMaxHSpeed(smuffConfig.maxSpeedHS_X);
- steppers[SELECTOR].setAccelDistance(smuffConfig.accelDistance_X);
-
-#if !defined(SMUFF_V5)
- steppers[REVOLVER] = ZStepper(REVOLVER, (char*)"Revolver", Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, smuffConfig.acceleration_Y, smuffConfig.maxSpeed_Y);
- steppers[REVOLVER].setEndstop(Y_END_PIN, smuffConfig.endstopTrigger_Y, ZStepper::ORBITAL);
- steppers[REVOLVER].stepFunc = overrideStepY;
- steppers[REVOLVER].setMaxStepCount(smuffConfig.stepsPerRevolution_Y);
- steppers[REVOLVER].setStepsPerDegree(smuffConfig.stepsPerRevolution_Y/360);
- steppers[REVOLVER].endstopFunc = endstopYevent;
- steppers[REVOLVER].setInvertDir(smuffConfig.invertDir_Y);
- steppers[REVOLVER].setMaxHSpeed(smuffConfig.maxSpeedHS_Y);
- steppers[REVOLVER].setAccelDistance(smuffConfig.accelDistance_Y);
-#endif
-
- steppers[FEEDER] = ZStepper(FEEDER, (char*)"Feeder", Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, smuffConfig.acceleration_Z, smuffConfig.maxSpeed_Z);
- /*
- if(smuffConfig.useDuetLaser) {
- steppers[FEEDER].setEndstop(-1, smuffConfig.endstopTrigger_Z, ZStepper::MIN);
- steppers[FEEDER].endstopCheck = checkDuetEndstop;
- }
- else
- */
- steppers[FEEDER].setEndstop(Z_END_PIN, smuffConfig.endstopTrigger_Z, ZStepper::MIN);
- if(Z_END2_PIN != -1)
- steppers[FEEDER].setEndstop(Z_END2_PIN, smuffConfig.endstopTrigger_Z, ZStepper::MIN, 2); // optional; used for testing only
- steppers[FEEDER].stepFunc = overrideStepZ;
- steppers[FEEDER].setStepsPerMM(smuffConfig.stepsPerMM_Z);
- steppers[FEEDER].endstopFunc = endstopZevent;
- steppers[FEEDER].endstop2Func = endstopZ2event;
- steppers[FEEDER].setInvertDir(smuffConfig.invertDir_Z);
- steppers[FEEDER].setMaxHSpeed(smuffConfig.maxSpeedHS_Z);
- steppers[FEEDER].setAccelDistance(smuffConfig.accelDistance_Z);
-
- for(int i=0; i < NUM_STEPPERS; i++) {
- steppers[i].runAndWaitFunc = runAndWait;
- steppers[i].runNoWaitFunc = runNoWait;
- steppers[i].setEnabled(true);
- }
- //__debug(PSTR("DONE enabling steppers"));
-
- for(int i=0; i < MAX_TOOLS; i++) {
- swapTools[i] = i;
- }
- //__debug(PSTR("DONE initializing swaps"));
-}
-
-void setupTimers() {
-#if defined(__AVR__)
- // *****
- // Attn: Servo uses TIMER5 if it's setup to create its own timer
- // *****
- stepperTimer.setupTimer(ZTimer::ZTIMER4, ZTimer::PRESCALER1);
- encoderTimer.setupTimer(ZTimer::ZTIMER3, ZTimer::PRESCALER256); // round about 1ms on 16MHz CPU
-#elif defined(__ESP32__)
- // *****
- // Attn: Servo uses TIMER4 if it's setup to create its own timer
- // PortExpander uses TIMER3
- // *****
- stepperTimer.setupTimer(ZTimer::ZTIMER1, 4, 1); // prescaler set to 20MHz, timer will be calculated as needed
- encoderTimer.setupTimer(ZTimer::ZTIMER2, 80, 1000); // 1ms on 80MHz Timer Clock
-#else
- // *****
- // Attn:
- // Servo uses TIMER5 CH1 if it's set up to create its own timer
- // Fan uses TIMER8 CH3
- // Beeper uses TIMER4 CH3
- // PC9 (Heatbed) uses TIMER1 CH1
- // *****
- stepperTimer.setupTimer(ZTimer::ZTIMER2, 3, 1, 1); // prescaler set to 72MHz, timer will be calculated as needed
- encoderTimer.setupTimer(ZTimer::ZTIMER1, 1, 8, 9000); // 1ms on 72MHz CPU
- setToneTimerChannel((uint8_t)ZTimer::ZTIMER4, 3); // force TIMER4 / CH3 on STM32F1x for tone library
-#endif
-
- stepperTimer.setupTimerHook(isrStepperHandler);
- encoderTimer.setupTimerHook(isrEncoderHandler);
- encoder.setDoubleClickEnabled(true);
-
-#if defined(__STM32F1__)
- encoderTimer.setNextInterruptInterval(9000); // run encoder timer (STM32)
-#elif defined(__ESP32__)
- encoderTimer.setNextInterruptInterval(1000); // run encoder timer (ESP32)
-#else
- encoderTimer.setNextInterruptInterval(40); // run encoder timer (AVR)
-#endif
- //__debug(PSTR("DONE setup timers"));
+ removeFirmwareBin(); // deletes the firmware.bin file to prevent re-flashing on each boot
+ enablePeriStat = true; // enable periodically sending status, if configured
+ startupBeep(); // signal startup has finished
+ pwrSaveTime = millis(); // init value for LCD screen timeout
}
void startStepperInterval() {
@@ -656,49 +369,75 @@ void isrStepperHandler() {
}
steppers[i].handleISR();
- if(steppers[i].getMovementDone())
- remainingSteppersFlag &= ~_BV(i);
+ if(steppers[i].getMovementDone()) {
+ remainingSteppersFlag &= ~_BV(i);
+ //__debug(PSTR("ISR(): movement of %d done; Flag %d"), i, remainingSteppersFlag);
+ }
}
//__debug(PSTR("ISR(): %d"), remainingSteppersFlag);
startStepperInterval();
}
-void runNoWait(volatile int index) {
+void runNoWait(int index) {
if(index != -1)
remainingSteppersFlag |= _BV(index);
startStepperInterval();
- //__debug(PSTR("started stepper %d"), index);
+ //__debug(PSTR("Started stepper %d"), index);
}
-void runAndWait(volatile int index) {
+void runAndWait(int index) {
runNoWait(index);
while(remainingSteppersFlag) {
checkSerialPending(); // not a really nice solution but needed to check serials for "Abort" command in PMMU mode
+
#if defined(__STM32F1__) // || defined(__ESP32__)
- if(!showMenu)
- refreshStatus(true);
+ if((remainingSteppersFlag & _BV(FEEDER)) && !showMenu) {
+ refreshStatus(false, true);
+ }
#endif
}
//__debug(PSTR("RunAndWait done"));
//if(index==FEEDER) __debug(PSTR("Fed: %smm"), String(steppers[index].getStepsTakenMM()).c_str());
}
-void refreshStatus(bool withLogo) {
- display.firstPage();
- do {
- if(withLogo)
- drawLogo();
- drawStatus();
- } while(display.nextPage());
+void refreshStatus(bool withLogo, bool feedOnly) {
+ if(feedOnly) {
+ drawFeed();
+ }
+ else {
+ display.firstPage();
+ do {
+ if(withLogo)
+ drawLogo();
+ drawStatus();
+ } while(display.nextPage());
+ }
lastDisplayRefresh = millis();
}
void loop() {
+
+ // Call periodical functions as the timeout has reached.
+ // Add your specific code there, if you need to have something
+ // managed periodically.
+ // The main loop is the better choice for dispatching, since it'll
+ // allow uninterrupted serial I/O.
+ if(generalCounter % 20 == 0) every20ms();
+ if(generalCounter % 50 == 0) every50ms();
+ if(generalCounter % 100 == 0) every100ms();
+ if(generalCounter % 250 == 0) every250ms();
+ if(generalCounter % 500 == 0) every500ms();
+ if(generalCounter % 1000 == 0) every1s();
+ if(generalCounter % 2000 == 0) every2s();
+ if(generalCounter % 5000 == 0) every5s();
+
+ #if defined(USE_COMPOSITE_SERIAL)
+ MassStorage.loop();
+ #endif
- //__debug(PSTR("gcInterval: %ld"), gcInterval);
-#if defined(__STM32F1__) || defined(__ESP32__)
+ #if defined(__STM32F1__) || defined(__ESP32__)
checkSerialPending();
-#endif
+ #endif
if(feederEndstop() != lastZEndstopState) {
lastZEndstopState = feederEndstop();
bool state = feederEndstop();
@@ -716,22 +455,18 @@ void loop() {
//__debug(PSTR("Mem: %d"), freeMemory());
checkUserMessage();
+
if(!displayingUserMessage) {
if(!isPwrSave && !showMenu) {
unsigned long elapsed = millis()-lastDisplayRefresh;
#if defined(__STM32F1__)
- if(elapsed > 250) { // refresh display every 250ms
- refreshStatus(true);
- }
-#elif defined(__ESP32__)
- if(elapsed > 500) { // refresh display every 500ms
- refreshStatus(true);
- }
+ if(elapsed > 250) // refresh display every 250ms
#else
- if(elapsed > 500) { // refresh display every 500ms
- refreshStatus(true);
- }
+ if(elapsed > 500) // refresh display every 500ms
#endif
+ {
+ refreshStatus(true, false);
+ }
}
}
@@ -775,6 +510,21 @@ void loop() {
//__debug(PSTR("Power save mode after %d seconds (%d)"), (millis() - pwrSaveTime)/1000, smuffConfig.powerSaveTimeout);
setPwrSave(1);
}
+
+#if defined(__BRD_SKR_MINI_E3) || defined(__BRD_SKR_MINI_E3DIP)
+ /*
+ if(interval1s) {
+ #if defined(USE_SW_SERIAL)
+ // for testing SoftwareSerial
+ swSer0.write('*');
+ swSer0.write('T');
+ swSer0.write('G');
+ #endif
+ interval1s = false;
+ }
+ */
+#endif
+
#if defined(__ESP32__)
// call this method only if you have serial ports assigned
// to the Port Expander
@@ -818,12 +568,12 @@ bool checkUserMessage() {
#ifndef __AVR__
void serialEventRun() {
if(Serial.available()) serialEvent();
- if(Serial1.available()) serialEvent1();
- if(Serial2.available()) serialEvent2();
-
- #ifdef __STM32F1__
- if(Serial3.available()) serialEvent3();
- #endif
+ if(CAN_USE_SERIAL1)
+ if(Serial1.available()) serialEvent1();
+ if(CAN_USE_SERIAL2)
+ if(Serial2.available()) serialEvent2();
+ if(CAN_USE_SERIAL3)
+ if(Serial3.available()) serialEvent3();
}
#endif
@@ -834,9 +584,9 @@ void checkSerialPending() {
void resetSerialBuffer(int serial) {
switch(serial) {
case 0: serialBuffer0 = ""; break;
- case 1: serialBuffer0 = ""; break;
+ case 1: serialBuffer1 = ""; break;
case 2: serialBuffer2 = ""; break;
- case 3: serialBuffer2 = ""; break;
+ case 3: serialBuffer3 = ""; break;
case 9: serialBuffer9 = ""; break;
}
}
@@ -873,12 +623,11 @@ void filterSerialInput(String& buffer, char in) {
void sendToPanelDue(char in) {
// only if PanelDue is configured...
- if(smuffConfig.hasPanelDue) {
- #if defined(__ESP32__)
- Serial2.write(in);
- #elif defined(__STM32F1__)
- Serial3.write(in);
- #endif
+ switch(smuffConfig.hasPanelDue) {
+ case 0: return;
+ case 1: if(CAN_USE_SERIAL1) Serial1.write(in); break;
+ case 2: if(CAN_USE_SERIAL2) Serial2.write(in); break;
+ case 3: if(CAN_USE_SERIAL3) Serial3.write(in); break;
}
}
@@ -915,7 +664,6 @@ bool isJsonData(char in) {
return false;
}
-volatile bool processingSerial0;
void serialEvent() {
@@ -942,8 +690,6 @@ void serialEvent() {
processingSerial0 = false;
}
-volatile bool processingSerial2;
-
void serialEvent2() {
if(processingSerial2)
@@ -954,8 +700,8 @@ void serialEvent2() {
processingSerial2 = true;
char in = (char)Serial2.read();
// in case of PanelDue connected, route everthing to Duet3D - do not process it any further
- if(smuffConfig.hasPanelDue) {
- Serial.write(in);
+ if(smuffConfig.hasPanelDue == 1) {
+ if(CAN_USE_SERIAL1) Serial1.write(in);
}
else {
if (in == '\n') {
@@ -972,8 +718,6 @@ void serialEvent2() {
processingSerial2 = false;
}
-volatile bool processingSerial1;
-
#ifndef __AVR__
void serialEvent1() {
@@ -988,22 +732,19 @@ void serialEvent1() {
if(isJsonData(in))
continue;
if (in == '\n') {
- //__debug(PSTR("Received-1: %s"), serialBuffer0.c_str());
- parseGcode(serialBuffer0, 1);
+ //__debug(PSTR("Received-1: %s"), serialBuffer1.c_str());
+ parseGcode(serialBuffer1, 1);
isQuote = false;
actionOk = false;
}
else {
- filterSerialInput(serialBuffer0, in);
+ filterSerialInput(serialBuffer1, in);
}
}
processingSerial1 = false;
}
-#ifndef __ESP32__
-volatile bool processingSerial3;
-
void serialEvent3() {
if(processingSerial3)
@@ -1013,24 +754,28 @@ void serialEvent3() {
while(Serial3.available()) {
processingSerial3 = true;
char in = (char)Serial3.read();
- //Serial3.write(in);
- if (in == '\n') {
- //__debug(PSTR("Received-3: %s"), serialBuffer2.c_str());
- parseGcode(serialBuffer2, 3);
- isQuote = false;
- actionOk = false;
+ if(smuffConfig.hasPanelDue == 2) {
+ if(CAN_USE_SERIAL2) Serial2.write(in);
}
else {
- filterSerialInput(serialBuffer2, in);
+ if (in == '\n') {
+ //__debug(PSTR("Received-3: %s"), serialBuffe3.c_str());
+ parseGcode(serialBuffer3, 3);
+ isQuote = false;
+ actionOk = false;
+ }
+ else {
+ filterSerialInput(serialBuffer3, in);
+ }
}
}
processingSerial3 = false;
}
#endif
-#endif
#ifdef __AVR__
+// not really used anymore; Kept only to not break compatibility
void wireReceiveEvent(int numBytes) {
while (Wire.available()) {
char in = (char)Wire.read();
diff --git a/src/SMuFFtools.cpp b/src/SMuFFtools.cpp
index 147fd3f..d0bfbc9 100644
--- a/src/SMuFFtools.cpp
+++ b/src/SMuFFtools.cpp
@@ -25,17 +25,14 @@
#include "SMuFF.h"
#include "SMuFFBitmaps.h"
#include "Config.h"
-#include "ZTimerLib.h"
-#include "ZStepperLib.h"
-#include "ZServo.h"
#ifdef __ESP32__
extern BluetoothSerial SerialBT;
#endif
#ifdef __STM32F1__
-#include "libmaple/libmaple.h"
-SPIClass SPI_3(3);
+//#include "libmaple/libmaple.h"
+//SPIClass SPI_3(3);
#define _tone(pin, freq, duration) playTone(pin, freq, duration)
#define _noTone(pin) muteTone(pin)
#elif defined (__ESP32__)
@@ -65,10 +62,22 @@ int swapTools[MAX_TOOLS];
bool isWarning;
unsigned long feederErrors = 0;
bool ignoreHoming = false;
+String tuneSequence = "F440D120P150.F523D120P80.F196D220P80.F196D120P80.F587D400P120.F349D80P240.F349D80P160.";
+// the "old" tune
+//String tuneSequence = "F1760D90.F1975D90.F2093D90.F1975D90.F1760D200P50.";
+
const char brand[] = VERSION_STRING;
void setupDisplay() {
+ // The next code line (display.setI2CAddress) changes the address for your TWI_DISPLAY if it's
+ // configured differently.
+ // Usually, thoses displays are pre-configured at I2C address 0x78, which equals to 0x3c
+ // from the software side because of the 7-Bit address mode.
+ // If it's configured at 0x7a, you need to change the I2C_DISPLAY_ADDRESS in Config.h to 0x3d.
+ #if I2C_DISPLAY_ADDRESS != 0x3C
+ display.setI2CAddress(I2C_DISPLAY_ADDRESS);
+ #endif
display.begin(/*Select=*/ ENCODER_BUTTON_PIN, /* menu_next_pin= */ U8X8_PIN_NONE, /* menu_prev_pin= */ U8X8_PIN_NONE, /* menu_home_pin= */ U8X8_PIN_NONE);
display.enableUTF8Print();
resetDisplay();
@@ -107,7 +116,9 @@ void drawStatus() {
#ifdef __AVR__
sprintf_P(tmp, PSTR("M:%d | %-4s | %-5s "), freeMemory(), traceSerial2.c_str(), _wait);
#else
- sprintf_P(tmp, PSTR("%-4s| %-4s | %-5s "), String(steppers[FEEDER].getStepsTakenMM()).c_str(), traceSerial2.c_str(), _wait);
+ String pos = String(steppers[FEEDER].getStepsTakenMM());
+ //String pos = String(lastDuetPos);
+ sprintf_P(tmp, PSTR("%-7s| %-4s | %-4s "), pos.c_str(), smuffConfig.externalStepper ? P_External : P_Internal, _wait);
#endif
display.drawStr(1, display.getDisplayHeight(), tmp);
display.setFontMode(0);
@@ -129,8 +140,15 @@ void drawFeed() {
display.setFont(SMALL_FONT);
display.setFontMode(0);
display.setDrawColor(0);
- display.drawBox(0, display.getDisplayHeight()-display.getMaxCharHeight()+2, 40, display.getMaxCharHeight());
- display.drawStr(1, display.getDisplayHeight(), tmp);
+ int x = 0;
+ int y = display.getDisplayHeight()-display.getMaxCharHeight() + 2;
+ int w = 40;
+ int h = display.getMaxCharHeight();
+ display.drawBox(x, y, w, h);
+ display.drawStr(x+1, display.getDisplayHeight(), tmp);
+ display.sendBuffer();
+ //display.updateDisplayArea(x, y, w, h);
+
#else
display.setFont(STATUS_FONT);
display.setFontMode(0);
@@ -141,6 +159,125 @@ void drawFeed() {
#endif
}
+int duetTurn = 0;
+void drawSymbolCallback() {
+ uint16_t symbols[] = { 0x25ef, 0x25d0, 0x25d3, 0x25d1, 0x25d2 };
+
+ if(duetLS.isMoving()) {
+ if(++duetTurn > 4)
+ duetTurn = 1;
+ }
+ else {
+ duetTurn = 0;
+ }
+ display.setFont(SYMBOL_FONT);
+ display.drawGlyph(118, 10, symbols[duetTurn]);
+}
+
+void showDuetLS() {
+ char _msg[128];
+ char _addData[15];
+ char _dir[3];
+
+ bool extStepper = smuffConfig.externalStepper;
+ switchFeederStepper(INTERNAL);
+ debounceButton();
+ encoder.setAccelerationEnabled(true);
+ while(1) {
+ if(encoder.getButton() == ClickEncoder::Clicked)
+ break;
+ // if the encoder knob is being turned, extrude / retract filament by the value defined
+ switch(encoder.getValue()) {
+ case -1: moveFeeder(-0.25); break;
+ case 1: moveFeeder( 0.25); break;
+ case -2: moveFeeder(-0.50); break;
+ case 2: moveFeeder( 0.50); break;
+ case -3: moveFeeder(-1.00); break;
+ case 3: moveFeeder( 1.00); break;
+ case -4: moveFeeder(-2.00); break;
+ case 4: moveFeeder( 2.00); break;
+ case -5: moveFeeder(-5.00); break;
+ case 5: moveFeeder( 5.00); break;
+ default: break;
+ }
+ uint8_t err = duetLS.getSensorError();
+ if(err != 0)
+ sprintf_P(_addData, PSTR("%4s/%04x"), err==E_SENSOR_INIT ? "INIT" : err==E_SENSOR_VCC ? "VCC" : String(err).c_str(), duetLS.getError());
+ else {
+ if(!duetLS.isValid())
+ sprintf_P(_addData, PSTR("-invalid-"));
+ else
+ sprintf_P(_addData, PSTR("none/%04x"), duetLS.getError());
+ }
+ switch(duetLS.getDirection()) {
+ case DIR_NONE: sprintf(_dir," "); break;
+ case DIR_EXTRUDE: sprintf(_dir, "<<"); break;
+ case DIR_RETRACT: sprintf(_dir, ">>"); break;
+ }
+
+ sprintf_P(_msg, P_DuetLSData, _dir, String(duetLS.getPositionMM()).c_str(), duetLS.getQuality(), duetLS.getBrightness(), duetLS.getShutter(), duetLS.getSwitch() ? P_On : P_Off, _addData, duetLS.getVersion());
+ drawUserMessage(_msg, true, false, drawSymbolCallback);
+ delay(100);
+ }
+ if(extStepper)
+ switchFeederStepper(EXTERNAL);
+}
+
+TMC2209Stepper* showDriver = NULL;
+
+void drawStallCallback() {
+ uint16_t symbols[] = { 0x0020, 0x21af, 0x0020, 0x21a0 };
+ if(showDriver == NULL)
+ return;
+ bool stat = showDriver->diag();
+ display.setFont(SYMBOL_FONT);
+ display.drawGlyph(50, 8, symbols[stat]);
+ stat = showDriver->SG_RESULT() > showDriver->SGTHRS();
+ display.drawGlyph(61, 8, symbols[stat+2]);
+}
+
+void showTMCStatus(int axis) {
+ char _msg[256];
+
+ debounceButton();
+ encoder.setAccelerationEnabled(true);
+ switch(axis) {
+ case SELECTOR:
+ showDriver = driverX;
+ break;
+ case REVOLVER:
+ showDriver = driverY;
+ break;
+ case FEEDER:
+ showDriver = driverZ;
+ break;
+ }
+ if(showDriver == NULL) {
+ debounceButton();
+ drawUserMessage(P_StepperNotCfg);
+ delay(3000);
+ return;
+ }
+ steppers[axis].setEnabled(true);
+ displayingUserMessage = true;
+ while(1) {
+ checkSerialPending();
+ if(encoder.getButton() == ClickEncoder::Clicked)
+ break;
+ sprintf_P(_msg, P_TMC_Status,
+ showDriver->stealth() ? P_Stealth : P_Spread,
+ showDriver->rms_current(),
+ showDriver->ola() ? P_Yes : P_No,
+ showDriver->olb() ? P_Yes : P_No,
+ showDriver->s2ga() ? P_Yes : P_No,
+ showDriver->s2gb() ? P_Yes : P_No,
+ showDriver->ot() ? P_Yes : P_No);
+ drawUserMessage(_msg, true, false, drawStallCallback);
+ delay(100);
+ }
+ displayingUserMessage = false;
+}
+
void resetDisplay() {
display.clearDisplay();
display.setFont(BASE_FONT);
@@ -151,6 +288,9 @@ void resetDisplay() {
void drawSelectingMessage(int tool) {
char _sel[128];
char _wait[128];
+
+ if(displayingUserMessage) // don't show if something else is being displayed
+ return;
display.firstPage();
do {
resetDisplay();
@@ -208,10 +348,10 @@ int splitStringLines(char* lines[], int maxLines, const char* message) {
return cnt;
}
-void drawUserMessage(String message) {
+void drawUserMessage(String message, bool smallFont /* = false */, bool center /* = true */, void (*drawCallbackFunc)() /* = null */) {
- char* lines[6];
- int lineCnt = splitStringLines(lines, (int)(sizeof(lines)/sizeof(lines[0])), message.c_str());
+ char* lines[8];
+ int lineCnt = splitStringLines(lines, (int)ArraySize(lines), message.c_str());
if(isPwrSave) {
setPwrSave(0);
@@ -222,12 +362,13 @@ void drawUserMessage(String message) {
display.drawFrame(0, 0, display.getDisplayWidth(), display.getDisplayHeight());
display.firstPage();
do {
- display.setFont(BASE_FONT_BIG);
+ display.setFont(smallFont ? BASE_FONT : BASE_FONT_BIG);
int y = (display.getDisplayHeight()-(lineCnt-1)*display.getMaxCharHeight())/2;
display.firstPage();
do {
for(int i=0; i< lineCnt; i++) {
- display.drawStr((display.getDisplayWidth() - display.getStrWidth(lines[i]))/2, y, lines[i]);
+ int x = center ? (display.getDisplayWidth() - display.getStrWidth(lines[i]))/2 : 0;
+ display.drawStr(x, y, lines[i]);
if(i==0) {
if(lineCnt > 1 && strcmp(lines[1]," ")==0) {
display.drawHLine(0, y+3, display.getDisplayWidth());
@@ -236,6 +377,8 @@ void drawUserMessage(String message) {
y += display.getMaxCharHeight();
}
} while(display.nextPage());
+ if(drawCallbackFunc != NULL)
+ drawCallbackFunc();
display.setFont(BASE_FONT);
} while(display.nextPage());
displayingUserMessage = true;
@@ -300,6 +443,8 @@ uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
else {
if (turn != 0) {
resetAutoClose();
+ if(smuffConfig.encoderTickSound)
+ encoderBeep(1);
switch (turn)
{
case 1:
@@ -569,11 +714,20 @@ bool moveHome(int index, bool showMessage, bool checkFeeder) {
}
}
}
- if(index != FEEDER && smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ if(smuffConfig.revolverIsServo) {
+ //__debug(PSTR("Stepper home SERVO variant"));
+ // don't release the servo when homing the Feeder but
+ // release it when homing something else
+ if(index != FEEDER)
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
+ // Revolver isn't being used on a servo variant
+ if(index != REVOLVER)
+ steppers[index].home();
}
- if(index != REVOLVER && smuffConfig.revolverIsServo) {
- steppers[index].home();
+ else {
+ //__debug(PSTR("Stepper home non SERVO variant"));
+ // not a servo variant, home stepper which ever it is
+ steppers[index].home();
}
//__debug(PSTR("DONE Stepper home"));
@@ -673,19 +827,44 @@ void signalNoTool() {
drawUserMessage(_msg1);
}
+void switchFeederStepper(int stepper) {
+ if(RELAIS_PIN != -1) {
+ if(stepper == EXTERNAL) {
+ steppers[FEEDER].setEnabled(false);
+ digitalWrite(RELAIS_PIN, 0);
+ smuffConfig.externalStepper = true;
+ }
+ else if(stepper == INTERNAL) {
+ digitalWrite(RELAIS_PIN, 1);
+ smuffConfig.externalStepper = false;
+ }
+ // gain the relay some time to debounce
+ delay(50);
+ }
+}
+
+void moveFeeder(float distanceMM) {
+ steppers[FEEDER].setEnabled(true);
+ unsigned int curSpeed = steppers[FEEDER].getMaxSpeed();
+ steppers[FEEDER].setMaxSpeed(smuffConfig.insertSpeed_Z);
+ prepSteppingRelMillimeter(FEEDER, distanceMM, true);
+ runAndWait(FEEDER);
+ steppers[FEEDER].setMaxSpeed(curSpeed);
+}
+
void positionRevolver() {
// disable Feeder temporarily
steppers[FEEDER].setEnabled(false);
if(smuffConfig.resetBeforeFeed_Y && !ignoreHoming) {
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
else
moveHome(REVOLVER, false, false);
}
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOnPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOnPos);
steppers[FEEDER].setEnabled(true);
return;
}
@@ -801,7 +980,7 @@ bool feedToEndstop(bool showMessage) {
repositionSelector(true);
}
if(smuffConfig.revolverIsServo)
- setServoPos(1, smuffConfig.revolverOnPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOnPos);
n = 0;
}
if (retry < 0) {
@@ -810,7 +989,7 @@ bool feedToEndstop(bool showMessage) {
moveHome(REVOLVER, false, false); // home Revolver
M18("M18", "", 0); // turn all motors off
if(smuffConfig.revolverIsServo) { // release servo, if used
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
if(showFeederFailedMessage(1) == true) { // user wants to retry...
steppers[FEEDER].setEnabled(true);
@@ -866,11 +1045,14 @@ bool loadFilament(bool showMessage) {
signalNoTool();
return false;
}
- if(smuffConfig.externalControl_Z) {
+ if(smuffConfig.externalControl_Z && !smuffConfig.isSharedStepper) {
positionRevolver();
signalLoadFilament();
return true;
}
+ if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(INTERNAL);
+ }
parserBusy = true;
unsigned int curSpeed = steppers[FEEDER].getMaxSpeed();
@@ -894,7 +1076,7 @@ bool loadFilament(bool showMessage) {
if(smuffConfig.homeAfterFeed) {
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
else
steppers[REVOLVER].home();
@@ -902,6 +1084,10 @@ bool loadFilament(bool showMessage) {
bool wasAborted = steppers[FEEDER].getAbort();
steppers[FEEDER].setAbort(false);
+ if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(EXTERNAL);
+ }
+
parserBusy = false;
return true; //aborted ? false : true;
}
@@ -916,11 +1102,15 @@ bool loadFilamentPMMU2(bool showMessage) {
signalNoTool();
return false;
}
- if(smuffConfig.externalControl_Z) {
+ if(smuffConfig.externalControl_Z && !smuffConfig.isSharedStepper) {
positionRevolver();
signalLoadFilament();
return true;
}
+ if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(INTERNAL);
+ }
+
parserBusy = true;
unsigned int curSpeed = steppers[FEEDER].getMaxSpeed();
// move filament until it hits the feeder endstop
@@ -948,13 +1138,17 @@ bool loadFilamentPMMU2(bool showMessage) {
if(smuffConfig.homeAfterFeed) {
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
else
steppers[REVOLVER].home();
}
steppers[FEEDER].setAbort(false);
+ if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(EXTERNAL);
+ }
+
parserBusy = false;
return true;
}
@@ -993,11 +1187,14 @@ bool unloadFilament() {
signalNoTool();
return false;
}
- if(smuffConfig.externalControl_Z) {
+ if(smuffConfig.externalControl_Z && !smuffConfig.isSharedStepper) {
positionRevolver();
signalUnloadFilament();
return true;
}
+ else if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(INTERNAL);
+ }
steppers[FEEDER].setStepsTaken(0);
parserBusy = true;
if(!steppers[FEEDER].getEnabled())
@@ -1084,12 +1281,14 @@ bool unloadFilament() {
steppers[FEEDER].setAbort(false);
if(smuffConfig.homeAfterFeed) {
if(smuffConfig.revolverIsServo) {
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
else
steppers[REVOLVER].home();
}
-
+ if(smuffConfig.externalControl_Z && smuffConfig.isSharedStepper) {
+ switchFeederStepper(EXTERNAL);
+ }
parserBusy = false;
return true;
}
@@ -1145,8 +1344,10 @@ bool selectTool(int ndx, bool showMessage) {
}
else if (smuffConfig.externalControl_Z && feederEndstop()) {
beep(4);
- if(smuffConfig.duetDirect) {
- sprintf(_tmp, "//action: WAIT\n");
+ if(smuffConfig.sendActionCmds) {
+ // send action command to indicate a jam has happend and
+ // the controller shall wait
+ sprintf_P(_tmp, PSTR("//action: WAIT\n"));
printResponse(_tmp, 0);
printResponse(_tmp, 1);
printResponse(_tmp, 2);
@@ -1158,15 +1359,16 @@ bool selectTool(int ndx, bool showMessage) {
if(!stat)
return false;
if(smuffConfig.unloadCommand != NULL && strlen(smuffConfig.unloadCommand) > 0) {
- #if !defined(__ESP32__)
- Serial2.print(smuffConfig.unloadCommand);
- Serial2.print("\n");
- //__debug(PSTR("Feeder jammed, sent unload command '%s'\n"), smuffConfig.unloadCommand);
- #endif
+ if(CAN_USE_SERIAL2) {
+ Serial2.print(smuffConfig.unloadCommand);
+ Serial2.print("\n");
+ //__debug(PSTR("Feeder jammed, sent unload command '%s'\n"), smuffConfig.unloadCommand);
+ }
}
}
- if(smuffConfig.duetDirect) {
- sprintf(_tmp, "//action: CONTINUE\n");
+ if(smuffConfig.sendActionCmds) {
+ // send action command to indicate jam cleared, continue printing
+ sprintf_P(_tmp, PSTR("//action: CONTINUE\n"));
printResponse(_tmp, 0);
printResponse(_tmp, 1);
printResponse(_tmp, 2);
@@ -1174,24 +1376,31 @@ bool selectTool(int ndx, bool showMessage) {
}
if(smuffConfig.revolverIsServo) {
// release servo prior moving the selector
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
}
//__debug(PSTR("Selecting tool: %d"), ndx);
parserBusy = true;
drawSelectingMessage(ndx);
+ //__debug(PSTR("Message shown"));
unsigned speed = steppers[SELECTOR].getMaxSpeed();
- // if the distance between two tools is more than 3, use higher speed to move
+ // if the distance between two tools is more than 3 (tools), use higher speed to move
if(abs(toolSelected-ndx) >=3)
steppers[SELECTOR].setMaxSpeed(steppers[SELECTOR].getMaxHSpeed());
prepSteppingAbsMillimeter(SELECTOR, smuffConfig.firstToolOffset + (ndx * smuffConfig.toolSpacing));
remainingSteppersFlag |= _BV(SELECTOR);
+ #if !defined(SMUFF_V5)
if(!smuffConfig.resetBeforeFeed_Y) {
prepSteppingAbs(REVOLVER, smuffConfig.firstRevolverOffset + (ndx *smuffConfig.revolverSpacing), true);
remainingSteppersFlag |= _BV(REVOLVER);
}
runAndWait(-1);
+ #else
+ runAndWait(SELECTOR);
+ #endif
+ //__debug(PSTR("Selector in position: %d"), ndx);
+
steppers[SELECTOR].setMaxSpeed(speed);
toolSelected = ndx;
@@ -1200,20 +1409,26 @@ bool selectTool(int ndx, bool showMessage) {
dataStore.stepperPos[REVOLVER] = steppers[REVOLVER].getStepPosition();
dataStore.stepperPos[FEEDER] = steppers[FEEDER].getStepPosition();
saveStore();
+ //__debug(PSTR("Data stored"));
if (!smuffConfig.externalControl_Z && showMessage) {
showFeederLoadMessage();
}
if(smuffConfig.externalControl_Z) {
+ //__debug(PSTR("Resetting Revolver"));
resetRevolver();
signalSelectorReady();
+ //__debug(PSTR("Revolver reset done"));
}
// Attn: if testMode is set, it'll echo the selected tool to Serial2
- if(testMode) {
+ /*
+ if(testMode && CAN_USE_SERIAL2) {
Serial2.print("T");
Serial2.println(ndx);
}
+ */
parserBusy = false;
+ //__debug(PSTR("Finished selecting tool"));
return true;
}
@@ -1226,7 +1441,7 @@ void resetRevolver() {
}
else {
//__debug(PSTR("Positioning servo to: %d (CLOSED)"), smuffConfig.revolverOnPos);
- setServoPos(1, smuffConfig.revolverOnPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOnPos);
}
}
}
@@ -1237,7 +1452,7 @@ void setStepperSteps(int index, long steps, bool ignoreEndstop) {
if(smuffConfig.revolverIsServo && index == SELECTOR) {
if(servoRevolver.getDegree() != smuffConfig.revolverOffPos) {
//__debug(PSTR("Positioning servo to: %d (OPEN)"), smuffConfig.revolverOffPos);
- setServoPos(1, smuffConfig.revolverOffPos);
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
}
}
if (steps != 0)
@@ -1295,7 +1510,8 @@ void printSpeeds(int serial) {
String(smuffConfig.stepDelay_X).c_str(),
String(steppers[REVOLVER].getMaxSpeed()).c_str(),
String(smuffConfig.stepDelay_Y).c_str(),
- smuffConfig.externalControl_Z ? "external" : String(steppers[FEEDER].getMaxSpeed()).c_str(),
+ String(steppers[FEEDER].getMaxSpeed()).c_str(),
+ smuffConfig.externalControl_Z ? " (E)" : " (I)",
String(smuffConfig.stepDelay_Z).c_str());
printResponse(tmp, serial);
}
@@ -1306,7 +1522,8 @@ void printAcceleration(int serial) {
String(smuffConfig.stepDelay_X).c_str(),
String(steppers[REVOLVER].getAcceleration()).c_str(),
String(smuffConfig.stepDelay_Y).c_str(),
- smuffConfig.externalControl_Z ? "external" : String(steppers[FEEDER].getAcceleration()).c_str(),
+ String(steppers[FEEDER].getMaxSpeed()).c_str(),
+ smuffConfig.externalControl_Z ? " (E)" : " (I)",
String(smuffConfig.stepDelay_Z).c_str());
printResponse(tmp, serial);
}
@@ -1391,15 +1608,55 @@ void userBeep() {
_noTone(BEEPER_PIN);
}
-void initBeep() {
+void encoderBeep(int count) {
+ if(BEEPER_PIN == -1)
+ return;
+ _tone(BEEPER_PIN, 330, 5);
+ delayMicroseconds(5);
+ _noTone(BEEPER_PIN);
+}
+
+/*
+ Plays a sound sequence given in a string.
+ The format is: F{frequency} D{duration} [P{pause}].F{frequency}D{duration}[P{pause}]. ...
+ Example: "F440D120P80." plays an A (440Hz) with a duration of 120mS and pauses 80mS
+ after the tone has played.
+ The '.' at the end of a tone is needed to play that tone and must not be omitted.
+*/
+void playSequence(const char* seq) {
+ int f=0, d=0, p=0;
+ while(*seq) {
+ if(*seq=='"' || *seq==' ')
+ seq++;
+ if(toupper(*seq)=='F') {
+ f = atoi(++seq);
+ }
+ if(toupper(*seq)=='D') {
+ d = atoi(++seq);
+ }
+ if(toupper(*seq)=='P') {
+ p = atoi(++seq);
+ }
+ if(*seq=='.') {
+ if(f && d) {
+ _tone(BEEPER_PIN, f, d);
+ delay(d);
+ }
+ if(p)
+ delay(p);
+ f = d = p = 0;
+ }
+ seq++;
+ }
+ _noTone(BEEPER_PIN);
+}
+
+void startupBeep() {
showLed(4, 1);
if(BEEPER_PIN == -1)
return;
- _tone(BEEPER_PIN, 1760, 90); delay(90); _noTone(BEEPER_PIN);
- _tone(BEEPER_PIN, 1975, 90); delay(90); _noTone(BEEPER_PIN);
- _tone(BEEPER_PIN, 2093, 90); delay(90); _noTone(BEEPER_PIN);
- _tone(BEEPER_PIN, 1975, 90); delay(90); _noTone(BEEPER_PIN);
- _tone(BEEPER_PIN, 1760, 200); delay(250); _noTone(BEEPER_PIN);
+ // the "new" tune
+ playSequence(tuneSequence.c_str());
}
void setServoMinPwm(int servoNum, int pwm) {
@@ -1460,14 +1717,10 @@ void getStoredData() {
void setSignalPort(int port, bool state) {
if(!smuffConfig.prusaMMU2 && !smuffConfig.sendPeriodicalStats) {
sprintf(tmp,"%c%c%s", 0x1b, port, state ? "1" : "0");
-#if defined(__STM32F1__)
- Serial1.write(tmp);
-#elif defined(__ESP32__)
- // nothing here yet, might need adding some port pins settings / resetting
- //__debug(PSTR("setting signal port: %d, %s"), port, state ? "true" : "false");
-#else
- Serial2.write(tmp);
-#endif
+ if(CAN_USE_SERIAL1)
+ Serial1.write(tmp);
+ if(CAN_USE_SERIAL2)
+ Serial2.write(tmp);
}
}
@@ -1555,6 +1808,23 @@ bool getFiles(const char* rootFolder, const char* pattern, int maxFiles, bool cu
return false;
}
+/*
+ Removes file firmware.bin from root directory in order
+ to prevent re-flashing on each reset!
+*/
+void removeFirmwareBin() {
+ SdFat SD;
+
+#if defined(__ESP32__)
+ if (SD.begin(SDCS_PIN, SD_SCK_MHZ(4))) {
+#else
+ if (SD.begin()) {
+#endif
+ SD.remove("firmware.bin");
+ }
+}
+
+
void testRun(String fname) {
char line[80];
char msg[256];
@@ -1707,6 +1977,14 @@ void maintainTool() {
}
}
+void blinkLED() {
+#if defined(LED_PIN)
+ if(LED_PIN != -1)
+ digitalWrite(LED_PIN, !digitalRead(LED_PIN));
+#endif
+}
+
+
extern Stream* debugSerial;
void __debug(const char* fmt, ...) {
diff --git a/src/SetupInit.cpp b/src/SetupInit.cpp
new file mode 100644
index 0000000..02c0fe3
--- /dev/null
+++ b/src/SetupInit.cpp
@@ -0,0 +1,479 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include "SMuFF.h"
+
+#if defined(__STM32F1__)
+#define PRODUCT_ID 0x29 // for CompositeSerial
+#endif
+
+#if defined(USE_COMPOSITE_SERIAL)
+bool writeSDCard(const uint8_t *writebuff, uint32_t startSector, uint16_t numSectors) {
+ return SD.card()->writeSectors(startSector, writebuff, numSectors);
+}
+
+bool readSDCard(uint8_t *readbuff, uint32_t startSector, uint16_t numSectors) {
+ return SD.card()->readSectors(startSector, readbuff, numSectors);
+}
+#endif
+
+void initUSB() {
+#if defined(__STM32F1__)
+ if(USB_CONNECT_PIN != -1) {
+ pinMode(USB_CONNECT_PIN, OUTPUT);
+ digitalWrite(USB_CONNECT_PIN, HIGH); // USB clear connection
+ delay(1000); // give OS time to notice
+ digitalWrite(USB_CONNECT_PIN, LOW); // USB reestablish connection
+ }
+
+ #if defined(USE_COMPOSITE_SERIAL)
+ /* Not tested yet */
+ bool sdStat;
+ if(SDCS_PIN != -1) {
+ sdStat = SD.begin(SDCS_PIN, SD_SCK_MHZ(4));
+ }
+ else {
+ sdStat = SD.begin();
+ }
+ if(sdStat) {
+ USBComposite.setProductId(PRODUCT_ID);
+ MassStorage.setDriveData(0, SD.card()->sectorCount(), readSDCard, writeSDCard);
+ MassStorage.registerComponent();
+ CompositeSerial.registerComponent();
+ USBComposite.begin();
+ delay(2000);
+ }
+ #endif
+#endif
+}
+
+void setupDeviceName() {
+ String appendix = "";
+#if defined(__ESP32__)
+ appendix = WiFi.macAddress().substring(9);
+ appendix.replace(":", "");
+#endif
+ wirelessHostname = String("SMuFF") + "_" + appendix;
+}
+
+void setupBuzzer() {
+ if(BEEPER_PIN != -1) {
+#if defined(__ESP32__)
+ ledcSetup(BEEPER_CHANNEL, 5000, 8);
+ ledcAttachPin(BEEPER_PIN, BEEPER_CHANNEL);
+#else
+#endif
+ }
+}
+
+
+/*
+ Initialize FastLED library for NeoPixels.
+ Primarily used for backlight on some displays (i.e. FYSETC 12864 Mini V2.1)
+*/
+void initFastLED() {
+ #if NEOPIXEL_PIN != -1 && defined(USE_FASTLED_BACKLIGHT)
+ FastLED.addLeds(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
+ FastLED.setBrightness(BRIGHTNESS);
+ #endif
+}
+
+/*
+ Initialize pin for hardware debugging.
+ Primarily used to attach an oscilloscope.
+*/
+void initHwDebug() {
+ #if defined(__HW_DEBUG__)
+ pinMode(DEBUG_PIN, OUTPUT);
+ digitalWrite(DEBUG_PIN, HIGH);
+ #endif
+}
+
+void setupDuetLaserSensor() {
+ // Duet Laser Sensor is being used as the Feeder endstop
+ if(smuffConfig.useDuetLaser) {
+ duetLS.attach(Z_END_DUET_PIN);
+ }
+}
+
+void setupSerialBT() {
+#ifdef __ESP32__
+ // this line must be kept, otherwise BT power down will cause a reset
+ SerialBT.begin(wirelessHostname);
+#endif
+}
+
+void setupSerial() {
+ // special case:
+ // if the baudrate is set to 0, the board is running out of memory
+ if(smuffConfig.serial0Baudrate != 0) {
+ if(smuffConfig.serial0Baudrate != 115200) {
+ Serial.end();
+ Serial.begin(smuffConfig.serial0Baudrate);
+ }
+ }
+ else {
+ writeConfig(&Serial);
+ longBeep(3);
+ showDialog(P_TitleConfigError, P_ConfigFail1, P_ConfigFail4, P_OkButtonOnly);
+ }
+
+ Serial.begin(smuffConfig.serial0Baudrate);
+ if(CAN_USE_SERIAL1) Serial1.begin(smuffConfig.serial1Baudrate);
+ if(CAN_USE_SERIAL2) Serial2.begin(smuffConfig.serial2Baudrate);
+ if(CAN_USE_SERIAL3) Serial3.begin(smuffConfig.serial3Baudrate);
+ //__debug(PSTR("DONE init SERIAL"));
+}
+
+void setupSwSerial0() {
+#if defined(USE_SW_SERIAL)
+ swSer0.begin(TMC_BAUDRATE);
+#endif
+}
+
+void setupRelay() {
+ if(RELAIS_PIN != -1 && smuffConfig.revolverIsServo) {
+ // Relay mode will only work on servo variants
+ pinMode(RELAIS_PIN, OUTPUT);
+ // if there's an external Feeder stepper defined (i.e. the 3D-Printer drives the Feeder),
+ // switch on the external stepper by default. Otherwise, use the interal stepper.
+ if(smuffConfig.externalControl_Z)
+ switchFeederStepper(EXTERNAL);
+ else
+ switchFeederStepper(INTERNAL);
+ }
+}
+
+void setupServos() {
+
+ // setup the Wiper servo
+ if(SERVO1_PIN != -1) {
+ servo.setMaxCycles(smuffConfig.servoCycles1);
+ servo.setPulseWidthMinMax(smuffConfig.servoMinPwm, smuffConfig.servoMaxPwm);
+ #if defined(__ESP32__)
+ // we'll be using the internal ledcWrite for servo control on ESP32
+ servo.attach(SERVO1_PIN, false, 0);
+ #elif defined(__STM32F1__)
+ servo.attach(SERVO1_PIN, true, 0);
+ #else
+ servo.attach(SERVO1_PIN, true, 0);
+ #endif
+ int resetPos = 90, param;
+ // try to find out the default reset position of the wiper servo from
+ // within the wipe sequence
+ if((param = getParam(String(smuffConfig.wipeSequence), (char*)"P")) != -1) {
+ resetPos = param;
+ }
+ setServoPos(SERVO_WIPER, resetPos);
+ }
+
+ // setup the Lid servo (replaces the Revolver stepper motor)
+ if(SERVO2_PIN != -1) {
+ servoRevolver.setMaxCycles(smuffConfig.servoCycles2);
+ servoRevolver.setPulseWidthMinMax(smuffConfig.servoMinPwm, smuffConfig.servoMaxPwm);
+ #if defined(__ESP32__)
+ // we'll be using the internal ledcWrite for servo control on ESP32
+ servoRevolver.attach(SERVO2_PIN, false, 1);
+ #elif defined(__STM32F1__)
+ servoRevolver.attach(SERVO2_PIN, true, 1);
+ #else
+ servoRevolver.attach(SERVO2_PIN, true, 1);
+ #endif
+ setServoPos(SERVO_LID, smuffConfig.revolverOffPos);
+ }
+}
+
+void setupHeaterBed() {
+ // Please note: All the PWM pins on the SKR are not working as
+ // expected. Maybe it's a common libmaple issue, maybe it's a
+ // STM32 timer related thing or maybe it's the
+ // hardware design of the board itself.
+ // Can't tell for sure, need some more investigation.
+ if(HEATER0_PIN != -1) {
+ pinMode(HEATER0_PIN, OUTPUT);
+ }
+#if defined(__STM32F1__) || defined(__ESP32__)
+ if(HEATBED_PIN != -1) {
+ #if defined(__STM32F1__)
+ pinMode(HEATBED_PIN, PWM);
+ #else
+ pinMode(HEATBED_PIN, OUTPUT);
+ #endif
+ }
+#endif
+}
+
+void setupFan() {
+
+ if(FAN_PIN != -1) {
+ #ifdef __STM32F1__
+ fan.attach(FAN_PIN, 0);
+ #elif defined(__ESP32__)
+ ledcSetup(FAN_CHANNEL, FAN_FREQ, 8);
+ ledcAttachPin(FAN_PIN, FAN_CHANNEL);
+ //__debug(PSTR("DONE FAN PIN CONFIG"));
+ #else
+ pinMode(FAN_PIN, OUTPUT);
+ #endif
+ if(smuffConfig.fanSpeed >= 0 && smuffConfig.fanSpeed <= 100) {
+ #if defined (__ESP32__)
+ ledcWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 65535));
+ #elif defined(__STM32F1__)
+ //pwmWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 65535));
+ fan.setFanSpeed(smuffConfig.fanSpeed);
+ #else
+ analogWrite(FAN_PIN, map(smuffConfig.fanSpeed, 0, 100, 0, 255));
+ #endif
+ }
+ }
+ //__debug(PSTR("DONE FAN init"));
+}
+
+void setupPortExpander() {
+ #if defined(__ESP32__)
+ // init the PCF8574 port expander and set pin modes (0-5 OUTPUT, 6-7 INPUT)
+ portEx.begin(PORT_EXPANDER_ADDRESS, false);
+ for(int i=0; i< 6; i++) {
+ portEx.pinMode(i, OUTPUT);
+ portEx.setPin(i);
+ }
+ portEx.pinMode(6, INPUT_PULLUP);
+ portEx.pinMode(7, INPUT_PULLUP);
+ portEx.resetPin(0);
+ //__debug(PSTR("DONE PortExpander init"));
+ #endif
+}
+
+void setupI2C() {
+ #ifdef __AVR__
+ // We can't do Master and Slave on this device.
+ // Slave mode is used for the I2C OLE Display on SKR mini
+ if(smuffConfig.i2cAddress != 0) {
+ Wire.begin(smuffConfig.i2cAddress);
+ Wire.onReceive(wireReceiveEvent);
+ }
+ //__debug(PSTR("DONE I2C init"));
+ #endif
+}
+
+void setupBacklight() {
+ #if defined(USE_RGB_BACKLIGHT) || defined(USE_FASTLED_BACKLIGHT)
+ for(int i=0; i< 8; i++) {
+ setBacklightIndex(i); // flip through all colors
+ delay(250);
+ }
+ setBacklightIndex(smuffConfig.backlightColor); // turn on the LCD backlight according to the configured setting
+ #endif
+}
+
+void setupEncoder() {
+ encoder.setDoubleClickEnabled(true); // enable doubleclick on the rotary encoder
+ encoder.setEnableSound(smuffConfig.encoderTickSound);
+}
+
+void setupSteppers() {
+
+ steppers[SELECTOR] = ZStepper(SELECTOR, (char*)"Selector", X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, smuffConfig.acceleration_X, smuffConfig.maxSpeed_X);
+ steppers[SELECTOR].setEndstop(X_END_PIN, smuffConfig.endstopTrigger_X, ZStepper::MIN);
+ steppers[SELECTOR].stepFunc = overrideStepX;
+ steppers[SELECTOR].setMaxStepCount(smuffConfig.maxSteps_X);
+ steppers[SELECTOR].setStepsPerMM(smuffConfig.stepsPerMM_X);
+ steppers[SELECTOR].setInvertDir(smuffConfig.invertDir_X);
+ steppers[SELECTOR].setMaxHSpeed(smuffConfig.maxSpeedHS_X);
+ steppers[SELECTOR].setAccelDistance(smuffConfig.accelDistance_X);
+ if(smuffConfig.stepperStall[SELECTOR] > 0)
+ steppers[SELECTOR].stallCheck = stallCheckX;
+
+#if !defined(SMUFF_V5)
+ steppers[REVOLVER] = ZStepper(REVOLVER, (char*)"Revolver", Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, smuffConfig.acceleration_Y, smuffConfig.maxSpeed_Y);
+ steppers[REVOLVER].setEndstop(Y_END_PIN, smuffConfig.endstopTrigger_Y, ZStepper::ORBITAL);
+ steppers[REVOLVER].stepFunc = overrideStepY;
+ steppers[REVOLVER].setMaxStepCount(smuffConfig.stepsPerRevolution_Y);
+ steppers[REVOLVER].setStepsPerDegree(smuffConfig.stepsPerRevolution_Y/360);
+ steppers[REVOLVER].endstopFunc = endstopYevent;
+ steppers[REVOLVER].setInvertDir(smuffConfig.invertDir_Y);
+ steppers[REVOLVER].setMaxHSpeed(smuffConfig.maxSpeedHS_Y);
+ steppers[REVOLVER].setAccelDistance(smuffConfig.accelDistance_Y);
+ if(smuffConfig.stepperStall[REVOLVER] > 0)
+ steppers[REVOLVER].stallCheck = stallCheckY;
+#else
+ // we don't use the Revolver stepper but an servo instead, although
+ // create a dummy instance
+ steppers[REVOLVER] = ZStepper(REVOLVER, (char*)"Revolver", -1, -1, Y_ENABLE_PIN, 0, 0);
+#endif
+
+ steppers[FEEDER] = ZStepper(FEEDER, (char*)"Feeder", Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, smuffConfig.acceleration_Z, smuffConfig.maxSpeed_Z);
+ if(smuffConfig.useDuetLaser) {
+ steppers[FEEDER].setEndstop(-1, smuffConfig.endstopTrigger_Z, ZStepper::MIN);
+ steppers[FEEDER].endstopCheck = checkDuetEndstop;
+ }
+ else
+ steppers[FEEDER].setEndstop(Z_END_PIN, smuffConfig.endstopTrigger_Z, ZStepper::MIN);
+ if(Z_END2_PIN != -1)
+ steppers[FEEDER].setEndstop(Z_END2_PIN, smuffConfig.endstopTrigger_Z, ZStepper::MIN, 2); // optional; used for testing only
+ steppers[FEEDER].stepFunc = overrideStepZ;
+ steppers[FEEDER].setStepsPerMM(smuffConfig.stepsPerMM_Z);
+ steppers[FEEDER].endstopFunc = endstopEventZ;
+ steppers[FEEDER].endstop2Func = endstopEventZ2;
+ steppers[FEEDER].setInvertDir(smuffConfig.invertDir_Z);
+ steppers[FEEDER].setMaxHSpeed(smuffConfig.maxSpeedHS_Z);
+ steppers[FEEDER].setAccelDistance(smuffConfig.accelDistance_Z);
+ if(smuffConfig.stepperStall[FEEDER] > 0)
+ steppers[FEEDER].stallCheck = stallCheckZ;
+
+ for(int i=0; i < NUM_STEPPERS; i++) {
+ steppers[i].runAndWaitFunc = runAndWait;
+ steppers[i].runNoWaitFunc = runNoWait;
+ steppers[i].setEnabled(true);
+ }
+
+ __debug(PSTR("DONE init/enabling steppers"));
+ for(int i=0; i < MAX_TOOLS; i++) {
+ swapTools[i] = i;
+ }
+ //__debug(PSTR("DONE initializing swaps"));
+}
+
+
+TMC2209Stepper* initDriver(int axis, int rx_pin, int tx_pin) {
+ int mode = smuffConfig.stepperMode[axis];
+ int stall = smuffConfig.stepperStall[axis];
+ int current = smuffConfig.stepperPower[axis];
+ int msteps = smuffConfig.stepperMicrosteps[axis];
+ int csmin = smuffConfig.stepperCSmin[axis];
+ int csmax = smuffConfig.stepperCSmax[axis];
+ int csdown = smuffConfig.stepperCSdown[axis];
+ float rsense= smuffConfig.stepperRSense[axis];
+ int drvrAdr = smuffConfig.stepperAddr[axis];
+ int toff = stall == 0 ? 4 : 3; // smuffConfig.stepperToff[axis];
+ bool spread = smuffConfig.stepperSpread[axis];
+
+ if(mode == 0) {
+ //__debug(PSTR("Driver for %c-axis skipped"), 'X'+axis);
+ return NULL;
+ }
+
+ TMC2209Stepper* driver = new TMC2209Stepper(rx_pin, tx_pin, rsense, drvrAdr);
+ //__debug(PSTR("Driver for %c-axis initialized"), 'X'+axis);
+
+ steppers[axis].setEnabled(true);
+ driver->beginSerial(TMC_BAUDRATE);
+ delay(50);
+ driver->toff(toff);
+ driver->blank_time(24);
+ driver->internal_Rsense(true);
+ driver->Rsense = rsense;
+ driver->I_scale_analog(true); // set external Vref
+ driver->rms_current(current); // set current in mA
+ driver->mstep_reg_select(1); // set microstepping
+ driver->microsteps(msteps);
+
+ // setup StallGuard only if stepperStall value is between 1 and 255
+ // otherwise put it in SpreadCycle mode
+ if(stall >= 1 && stall <= 255) {
+ #if defined(TMC_TYPE_2130)
+ stall = (int)map(stall, 1, 255, -63, 63); // remap values for TMC2130 (not tested yet!)
+ #endif
+ driver->pwm_autoscale(true);
+ driver->TCOOLTHRS(0xFFFFF);
+ if(csmin >0 && csmax >0) {
+ driver->semin(csmin);
+ driver->semax(csmax);
+ driver->sedn(csdown);
+ }
+ driver->SGTHRS(0);
+ driver->en_spreadCycle(false); // set StealthChop (enable StallGuard)
+ }
+ else {
+ driver->TCOOLTHRS(0);
+ driver->en_spreadCycle(true); // set SpreadCycle (disable StallGuard)
+ }
+ return driver;
+}
+
+void setupTMCDrivers() {
+
+ #if defined(X_SERIAL_TX_PIN)
+ driverX = initDriver(SELECTOR, X_SERIAL_TX_PIN, X_SERIAL_TX_PIN);
+ #endif
+ #if defined(Y_SERIAL_TX_PIN)
+ driverY = initDriver(REVOLVER, Y_SERIAL_TX_PIN, Y_SERIAL_TX_PIN);
+ #endif
+ #if defined(Z_SERIAL_TX_PIN)
+ driverZ = initDriver(FEEDER, Z_SERIAL_TX_PIN, Z_SERIAL_TX_PIN);
+ #endif
+ #if defined(E_SERIAL_TX_PIN)
+ driverE = initDriver(FEEDER, E_SERIAL_TX_PIN, E_SERIAL_TX_PIN);
+ #endif
+ __debug(PSTR("DONE initializing TMC Steppers"));
+}
+
+void setupTimers() {
+#if defined(__AVR__)
+ // *****
+ // Attn:
+ // Servo uses: TIMER5 (if it's setup to create its own timer)
+ // Steppers use: TIMER4
+ // Encoder uses: gpTimer
+ // *****
+ stepperTimer.setupTimer(ZTimer::ZTIMER4, ZTimer::PRESCALER1);
+ gpTimer.setupTimer(ZTimer::ZTIMER3, ZTimer::PRESCALER256); // round about 1ms on 16MHz CPU
+
+#elif defined(__ESP32__)
+ // *****
+ // Attn:
+ // Servo uses: TIMER3 (if it's setup to create its own timer)
+ // PortExpander uses: TIMER3 (via general purpose timer)
+ // Steppers use: TIMER1
+ // Encoder uses: gpTimer
+ // *****
+ stepperTimer.setupTimer(ZTimer::ZTIMER1, 4); // prescaler set to 20MHz, timer will be calculated as needed
+ gp.setupTimer(ZTimer::ZTIMER2, 80); // 1ms on 80MHz timer clock
+#else
+ // *****
+ // Attn:
+ // PA8 (Fan) uses: TIMER1 CH1 (predefined by libmaple for PWM)
+ // Steppers use: TIMER5 CH1 (may corrupt TH0 readings)
+ // GP timer uses: TIMER8 CH1 (general, encoder, servo)
+ // Beeper uses: TIMER4 CH3
+ // SW-Serial uses: TIMER3 CH4 (see SoftwareSerialM library)
+ // PC8 (Heater0) uses: TIMER8 CH3 (predefined by libmaple for PWM)
+ // PC9 (Heatbed) uses: TIMER8 CH4 (predefined by libmaple for PWM)
+ //
+ // Warning: If you need to modify this assignment, be sure you know what you do!
+ // Swapping timers and/or channels may lead to a non functioning device or
+ // communication interrupts/breaks. Read the STM32F1 MCU spec. and check
+ // the libmaple library settings before you do so.
+ // *****
+ stepperTimer.setupTimer(ZTimer::ZTIMER2, ZTimer::CH1, 1, 1); // prescaler set to 72MHz, timer will be calculated as needed
+ gpTimer.setupTimer(ZTimer::ZTIMER8, ZTimer::CH1, 8, 0); // prescaler set to 9MHz, timer will be set to 50uS
+ setToneTimerChannel(ZTimer::ZTIMER4, ZTimer::CH3); // force TIMER4 / CH3 on STM32F1x for tone library
+#endif
+
+ stepperTimer.setupTimerHook(isrStepperHandler); // setup the ISR for the steppers
+ gpTimer.setupTimerHook(isrGPTimerHandler); // setup the ISR for rotary encoder, servo and general timers
+
+#if defined(__STM32F1__)
+ gpTimer.setNextInterruptInterval(450); // run general purpose (gp)timer on 50uS (STM32)
+#elif defined(__ESP32__)
+ gpTimer.setNextInterruptInterval(50); // run general purpose (gp)timer on 50uS (ESP32)
+#else
+ gpTimer.setNextInterruptInterval(3); // run general purpose (gp)timer on 48uS (AVR)
+#endif
+ //__debug(PSTR("DONE setup timers"));
+}
diff --git a/src/SimpleGCodeParser.cpp b/src/SimpleGCodeParser.cpp
index 8b2a213..6b9f728 100644
--- a/src/SimpleGCodeParser.cpp
+++ b/src/SimpleGCodeParser.cpp
@@ -96,12 +96,14 @@ void parseGcode(const String& serialBuffer, int serial) {
if(!steppers[FEEDER].getMovementDone()) {
//__debug(PSTR("Wait after 'T' 500ms"));
delay(500);
+ #if !defined(MARLIN2_ONLY)
if(currentLine > 0)
sprintf_P(ptmp, PSTR("M998 %d\n"), currentLine);
else
sprintf_P(ptmp, PSTR("M998\n"));
printResponseP(ptmp, serial);
//__debug(PSTR("Resend 'T' sent"));
+ #endif
return;
}
}
@@ -203,10 +205,12 @@ bool parse_T(const String& buf, int serial) {
}
else if(tool >= 0 && tool <= smuffConfig.toolCount-1) {
//__debug(PSTR("Tool change requested: T%d"), tool);
- // Prusa expects the MMU to unload filament on its own before tool change
- if(smuffConfig.prusaMMU2 && feederEndstop()) {
- //__debug(PSTR("must unload first!"));
- unloadFilament();
+ if(feederEndstop()) {
+ // Prusa expects the MMU to unload filament on its own before tool change
+ // Same goes if the Feeder stepper is declared shared
+ if(smuffConfig.prusaMMU2 || smuffConfig.isSharedStepper)
+ //__debug(PSTR("must unload first!"));
+ unloadFilament();
}
stat = selectTool(tool, false);
if(stat) {
@@ -219,7 +223,7 @@ bool parse_T(const String& buf, int serial) {
}
}
}
- if(!smuffConfig.prusaMMU2) // Prusa expects not Tx as response
+ if(!smuffConfig.prusaMMU2) // Prusa doesn't expect "Tx" as a response
printResponse(msg, serial);
}
else {
@@ -232,18 +236,24 @@ bool parse_T(const String& buf, int serial) {
bool parse_Action(const String& buf, int serial) {
+ char tmp[256];
+
if(buf.length()==0) {
return false;
}
- actionOk = false;
if(buf.startsWith("T:")) {
+ actionOk = false;
String msg = buf.substring(2);
if(msg == "OK")
actionOk = true;
else {
- drawUserMessage(msg);
+ sprintf_P(tmp, P_ActionMsg, msg.c_str());
+ drawUserMessage(tmp);
}
}
+ else if(buf.startsWith("PING")) {
+ printResponse("//action: PONG", serial);
+ }
return false;
}
@@ -441,6 +451,22 @@ int getParam(String buf, char* token) {
return -1;
}
+float getParamF(String buf, char* token) {
+ int pos = buf.indexOf(token);
+ //__debug(PSTR("getParam: %s\n"),buf.c_str());
+ if(pos != -1) {
+ //__debug(PSTR("getParam:pos: %d"),pos);
+ if(buf.charAt(pos+1)=='-') {
+ int val = buf.substring(pos+2).toInt();
+ //__debug(PSTR("Negative: %d"), 0-val);
+ return 0-val;
+ }
+ return atof(buf.substring(pos+1).c_str());
+ }
+ else
+ return -1;
+}
+
long getParamL(String buf, char* token) {
int pos = buf.indexOf(token);
//__debug(PSTR("getParam: %s\n"),buf.c_str());
@@ -554,11 +580,9 @@ void printResponse(const char* response, int serial) {
sendingResponse = true;
switch(serial) {
case 0: Serial.print(response); break;
- case 1: Serial1.print(response); break;
- case 2: Serial2.print(response); break;
-#ifndef __ESP32__
- case 3: Serial3.print(response); break;
-#endif
+ case 1: if(CAN_USE_SERIAL1) Serial1.print(response); break;
+ case 2: if(CAN_USE_SERIAL2) Serial2.print(response); break;
+ case 3: if(CAN_USE_SERIAL3) Serial3.print(response); break;
}
sendingResponse = false;
}
@@ -567,11 +591,9 @@ void printResponseP(const char* response, int serial) {
sendingResponse = true;
switch(serial) {
case 0: Serial.print((__FlashStringHelper*)response); break;
- case 1: Serial1.print((__FlashStringHelper*)response); break;
- case 2: Serial2.print((__FlashStringHelper*)response); break;
-#ifndef __ESP32__
- case 3: Serial3.print((__FlashStringHelper*)response); break;
-#endif
+ case 1: if(CAN_USE_SERIAL1) Serial1.print((__FlashStringHelper*)response); break;
+ case 2: if(CAN_USE_SERIAL2) Serial2.print((__FlashStringHelper*)response); break;
+ case 3: if(CAN_USE_SERIAL3) Serial3.print((__FlashStringHelper*)response); break;
}
sendingResponse = false;
}
diff --git a/src/ZFan.cpp b/src/ZFan.cpp
new file mode 100644
index 0000000..3cfefa7
--- /dev/null
+++ b/src/ZFan.cpp
@@ -0,0 +1,71 @@
+/**
+ * SMuFF Firmware
+ * Copyright (C) 2019 Technik Gegg
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "ZFan.h"
+
+static ZFan* fanInstances[MAX_FANS];
+
+void ZFan::attach(int pin) {
+ _pin = pin;
+ pinMode(_pin, OUTPUT);
+ digitalWrite(_pin, 0);
+}
+
+void ZFan::detach() {
+ digitalWrite(_pin, 0);
+ fanInstances[_fanIndex] = NULL;
+ _pin = 0;
+}
+
+void ZFan::setIndex(int fanIndex) {
+ if(fanIndex != -1 && fanIndex < MAX_FANS) {
+ _fanIndex = fanIndex;
+ fanInstances[_fanIndex] = this;
+ }
+}
+
+void ZFan::setFanSpeed(int speed) {
+ _speed = speed;
+ _pulseLen = map(speed, 0, 100, _minSpeed, _maxSpeed);
+}
+
+void ZFan::setFan() {
+ _tickCnt += 50;
+ if(_tickCnt <= (uint32_t)_pulseLen)
+ setFanPin(HIGH);
+ else
+ setFanPin(LOW);
+ if(_tickCnt >= (uint32_t)(FAN_DUTY_CYCLE)) {
+ _tickCnt = 0;
+ }
+}
+
+void ZFan::setFanPin(int state) {
+ digitalWrite(_pin, state);
+}
+
+void isrFanTimerHandler() {
+ // call all handlers for all fans periodically if the
+ // internal timer is being used.
+ for(int i=0; i< MAX_FANS; i++) {
+ if(fanInstances[i] != NULL) {
+ fanInstances[i]->setFan();
+ }
+ }
+}
diff --git a/src/ZServo.cpp b/src/ZServo.cpp
index 1ca5d6e..3fbc454 100644
--- a/src/ZServo.cpp
+++ b/src/ZServo.cpp
@@ -21,37 +21,25 @@
static ZServo* servoInstances[MAX_SERVOS];
+/*
+ To use the servo with an timer (interrupt), you have to setup an timer
+ externally, call the attach method with useTimer = true and call the
+ isrServoTimerHandler() method down below from within the timers
+ own interrupt routine.
+ The external timer has to run at 50uS (20kHz) in order to get the correct
+ timing for the servos.
+ Otherwise, as in case of the ESP32, the servos will be handled by
+ PWM on the give pin.
+
+ Had to realize it this way because I was running out of precious timers
+ on the STM32 MCU.
+*/
void ZServo::attach(int pin, bool useTimer, int servoIndex) {
_useTimer = useTimer;
attach(pin);
setIndex(servoIndex);
- // To set up an independent timer, you have to use the attach()-method above
- // with useTimer = true. Otherwise you'll have to call setServo() in a 20 ms
- // period to get the servo running, which is a bit more complex but saves
- // on timers.
- if(!timerSet && _useTimer) {
- timerSet = true;
- #ifdef __STM32F1__
- servoTimer.setupTimer(ZTimer::ZTIMER5, 1800); // equals to 25 us on 72 MHz CPU
- // timers on STM32 are killing me...
- // it's supposed to be 50us but with 50us in the timer each
- // PWM signal it twice as long - therefore 25us.
- // Need to investigate in that some day.
- #elif __ESP32__
- servoTimer.setupTimer(ZTimer::ZTIMER3, 80, 50); // equals to 50 us
- #else
- servoTimer.setupTimer(ZTimer::ZTIMER5, ZTimer::PRESCALER1024);
- #endif
- servoTimer.setupTimerHook(isrServoTimerHandler);
- #if defined(__ESP32__)
- servoTimer.setNextInterruptInterval(50);
- #else
- servoTimer.setNextInterruptInterval(1);
- #endif
- //__debug(PSTR("Servo with timer initialized"));
- }
- else {
+ if(!_useTimer) {
#if defined(__ESP32__)
ledcSetup(SERVO_CHANNEL+_servoIndex, SERVO_FREQ, 16);
ledcAttachPin(pin, SERVO_CHANNEL+_servoIndex);
@@ -63,7 +51,7 @@ void ZServo::attach(int pin, bool useTimer, int servoIndex) {
void ZServo::attach(int pin) {
_pin = pin;
-#if defined(__STM32F1__) && defined(SMUFF_V5)
+#if defined(SMUFF_V5) && defined(__BRD_SKR_MINI)
pinMode(_pin, OUTPUT_OPEN_DRAIN); // set tp Open Drain for the +5V pullup resistor
#else
pinMode(_pin, OUTPUT);
@@ -152,17 +140,17 @@ void ZServo::setServo() {
ledcWrite(SERVO_CHANNEL+_servoIndex, _pulseLen);
#else
digitalWrite(_pin, HIGH);
- delay_us(_pulseLen);
+ delayMicroseconds(_pulseLen);
digitalWrite(_pin, LOW);
#endif
_lastDegree = _degree;
}
}
else {
- // this method increments every 50 us and when the _pulseLen is reached
- // it sets the output to low.
- // Using this method will prevent blocking the whole CPU while the delay
- // is being active, as it's in the method above.
+ // this method increments with every call by 50 (uS) and when the _pulseLen is reached it'll
+ // sets the output to low.
+ // This way, blocking the whole CPU while the delay is being active as it's in the method above
+ // isn't happening.
_tickCnt += 50;
if(_tickCnt <= (uint32_t)_pulseLen)
@@ -173,7 +161,6 @@ void ZServo::setServo() {
if(_maxCycles == 0 || (++_dutyCnt < _maxCycles)) // but no more cycles than defined to avoid jitter on the servo
_tickCnt = 0;
}
-
}
}
@@ -181,15 +168,19 @@ void ZServo::setServoPin(int state) {
digitalWrite(_pin, state);
}
-bool state;
void isrServoTimerHandler() {
+
+ #if defined(__HW_DEBUG__) && defined(DEBUG_PIN)
+ // used for internal hardware debugging only
+ //if(DEBUG_PIN != -1) digitalWrite(DEBUG_PIN, !digitalRead(DEBUG_PIN));
+ #endif
+
// call all handlers for all servos periodically if the
// internal timer is being used.
- //digitalWrite(SERVO2_PIN, state = !state);
-
for(int i=0; i< MAX_SERVOS; i++) {
- if(servoInstances[i] != NULL)
- servoInstances[i]->setServo();
+ if(servoInstances[i] != NULL) {
+ if(!servoInstances[i]->isTimerStopped())
+ servoInstances[i]->setServo();
+ }
}
-
}
diff --git a/src/ZStepperLib.cpp b/src/ZStepperLib.cpp
index 2d5ed94..1a6e8dd 100644
--- a/src/ZStepperLib.cpp
+++ b/src/ZStepperLib.cpp
@@ -37,9 +37,12 @@ ZStepper::ZStepper(int number, char* descriptor, int stepPin, int dirPin, int en
_enablePin = enablePin;
_acceleration = acceleration;
_minStepInterval = minStepInterval;
- pinMode(_stepPin, OUTPUT);
- pinMode(_dirPin, OUTPUT);
- pinMode(_enablePin, OUTPUT);
+ if(_stepPin != -1)
+ pinMode(_stepPin, OUTPUT);
+ if(_dirPin != -1)
+ pinMode(_dirPin, OUTPUT);
+ if(_enablePin != -1)
+ pinMode(_enablePin, OUTPUT);
}
void ZStepper::defaultStepFunc(void) {
@@ -58,7 +61,7 @@ void ZStepper::resetStepper() {
_endstopHit = false;
}
-void ZStepper::prepareMovement(long steps, boolean ignoreEndstop /*= false */) {
+void ZStepper::prepareMovement(long steps, bool ignoreEndstop /*= false */) {
setDirection(steps < 0 ? CCW : CW);
_totalSteps = abs(steps);
_accelDistSteps = _endstopType == ORBITAL ? _stepsPerDegree * _accelDistance : _stepsPerMM * _accelDistance;
@@ -75,7 +78,7 @@ void ZStepper::setEndstop(int pin, int triggerState, EndstopType type, int index
_endstopType = type;
if(pin != -1) {
pinMode(_endstopPin, ((triggerState == 0) ? INPUT_PULLUP : INPUT));
- _endstopHit = digitalRead(_endstopPin) == _endstopState;
+ _endstopHit = (int)digitalRead(_endstopPin) == (int)_endstopState;
}
}
else if(index == 2) {
@@ -84,7 +87,7 @@ void ZStepper::setEndstop(int pin, int triggerState, EndstopType type, int index
_endstopType2 = type;
if(pin != -1) {
pinMode(_endstopPin2, ((triggerState == 0) ? INPUT_PULLUP : INPUT));
- _endstopHit2 = digitalRead(_endstopPin2) == _endstopState2;
+ _endstopHit2 = (int)digitalRead(_endstopPin2) == (int)_endstopState2;
}
}
}
@@ -96,7 +99,7 @@ void ZStepper::setDirection(ZStepper::MoveDirection direction) {
}
}
-void ZStepper::setEnabled(boolean state) {
+void ZStepper::setEnabled(bool state) {
if(_enablePin != -1) {
digitalWrite(_enablePin, state ? LOW : HIGH);
_enabled = state;
@@ -124,6 +127,11 @@ void ZStepper::updateAcceleration() {
void ZStepper::handleISR() {
+ // just in case nothing has been defined
+ if(_stepPin == -1) {
+ setMovementDone(true);
+ return;
+ }
bool hit = false;
if((_endstopType == MIN && _dir == CCW) ||
(_endstopType == MAX && _dir == CW) ||
@@ -134,6 +142,8 @@ void ZStepper::handleISR() {
else {
if(endstopCheck != NULL)
hit = endstopCheck();
+ //if(stallCheck != NULL)
+ //hit = stallCheck();
}
setEndstopHit(hit);
}
diff --git a/src/ZTimerLib.cpp b/src/ZTimerLib.cpp
index 5f54441..5bd7754 100644
--- a/src/ZTimerLib.cpp
+++ b/src/ZTimerLib.cpp
@@ -23,7 +23,7 @@
#include "ZTimerLib.h"
#if defined(__STM32F1__)
-#include
+//#include
#elif defined(__ESP32__)
#include "esp32-hal.h"
#endif
@@ -237,15 +237,25 @@ void ZTimer::setupTimer(IsrTimer timer, int channel, unsigned int prescaler, uns
hwTimer5.attachInterrupt(channel, ISR5);
break;
case ZTIMER6:
+ /*
hwTimer6.setMode(channel, TIMER_OUTPUT_COMPARE);
hwTimer6.setPrescaleFactor(prescaler);
hwTimer6.setCompare(channel, compare);
+ */
+ // since this timer doesn't have a compare mode, we're using
+ // the compare value as a period (in uS)
+ hwTimer6.setPeriod(compare);
hwTimer6.attachInterrupt(channel, ISR6);
break;
case ZTIMER7:
+ /*
hwTimer7.setMode(channel, TIMER_OUTPUT_COMPARE);
hwTimer7.setPrescaleFactor(prescaler);
hwTimer7.setCompare(channel, compare);
+ */
+ // since this timer doesn't have a compare mode, we're using
+ // the compare value as a period (in uS)
+ hwTimer7.setPeriod(compare);
hwTimer7.attachInterrupt(channel, ISR7);
break;
case ZTIMER8: