C# Skript Beispiel »
3D Drucker
Beschreibung:
Mit diesem Skript ist es möglich, eine Kombination aus Kolben und einem Schweißgerät als 3D-Drucker zu verwenden.
Basierend auf einer einfachen Einrichtung kannst Du Druck-Sequenzen erstellen, indem Du den Programmierbaren Block mit definierten Argumenten ausführen.
Gültige Namen der Kolben:
- X
- x1
- KolbenX1
Du musst mindestens ein x, y oder z (je nach Achse) im Kolbennamen haben
Ein Argument wird folgendermaßen gebildet:
<Achsenname><Richtung[+/-]><Schritt>[,<Nächstes Argument für Sequenzen>,...]
Gültige Argumente sind zum Beispiel:x+1
=> bewegt den Drucker um 1 Schritt vorwärts auf der x-Achsey-1
=> bewegt den Drucker um 1 Schritt auf der y-Achse zurück
oder Sequenzen:x+1,y+1,z+1,action|on,x+4,action|off,reset[,...]
Das Argument "reset
" setzt alle Kolben auf Null zurück.
Optional kann ein LCD mit dem Namen "LCD Log
" zur Protokollierung von Informationen verwendet werden
Argument "clearlog
" löscht den Log-Bildschirm.
Im Skript kannst Du noch folgende Einstellungen vornehmen:
// Gib den Namen des Druckerkopf an, wird benötigt wenn Du das Argument "action" verwenden willst (kann ein Bohrer, Schweißer etc. sein)
string PrinterHeadBlockName = "";
// Standardwert zum Verringern/Erhöhen der Kolben, wird bei Argumenten der Form x+, x-, y+,y-, z+ und z- verwendet
float Schritt = 1.0F;
// Aus-/Einfahrgeschwindigkeit der Kolben
float Geschwindigkeit = 0.5F;
Am besten legst Du dir die verschiedenen Aktionen auf Knöpfe der Schaltkonsole. Dazu im Bedienfeld die Aktion der Knöpfe konfigurieren:
Programmierbarer Block > Ausführen > Gewünschtes Argument eingeben
Benötigt:
min 1 Kolben in jede Achsenrichtung (beliebig viele sind möglich)
Druckkopf (Bohrer, Schweißer o.ä.)
1x Programmierbarer Block
Schaltkonsole
Steam Workshop
Das Skript gibt es auch im Workshop: https://steamcommunity.com/sharedfiles/filedetails/?id=2376883341
Screenshots
Exemplarischer Aufbau - Drucker, Schaltkonsole und Log LCD
Schaltkonsole mit allen Befehlen für den Drucker
Aufbau des Druckers: Es sollten Kolben für alle Achsenrichtungen vorhanden sein. Die Anzahl ist nicht begrenzt.
Source Code
- 3DPrinter.cs
C# Code Datei für Visual Basic
/*
#################################################################
# 3D Printer Script #
# by Dav1dson Visit us on www.spaceengineering.de #
#################################################################Valid names of pistons:
- X
- x1
- PistonX1
At least, they must have an x, y or z (depending on the axis) in its names
----------------------------------------------------------------------------------------------------------------------
An argument is build by:
<axis-name><direction[+/-]><step>[,<next argument for sequences>,...]Valid arguments are fo example:
- x+1
=> will move printer 1 step forward on x-axis
- y-1
=> will move printer 1 step back on y-axis
- or sequences:
x+1,y+1,z+1,action|on,x+4,action|off,reset[,...]
----------------------------------------------------------------------------------------------------------------------
Argument "reset" turns all pistons back to zero
----------------------------------------------------------------------------------------------------------------------
Optional an LCD with name ""LCD Log" can be used for Logging informations
----------------------------------------------------------------------------------------------------------------------
Argument "clearlog" clears log
----------------------------------------------------------------------------------------------------------------------
*/// Set the name for the Printer block if u want to use the "action" argument (drill,welder etc)
string PrinterHeadBlockName = "";
// -----------------------------------------------------------------
// default de-/increase value of pistons
float Step = 1.0F;
// -----------------------------------------------------------------
// default de-/increase speed of pistons
float Speed = 0.5F;
// -----------------------------------------------------------------IMyTerminalBlock printerHeadBlock = null;
public List<IMyTerminalBlock> PistonsX;
public List<IMyTerminalBlock> PistonsY;
public List<IMyTerminalBlock> PistonsZ;
public IMyTextPanel panel;public List<string> Queue;
public IMyPistonBase lastPiston = null;
public bool isRunning = false;
public Program()
{
try
{
Runtime.UpdateFrequency = UpdateFrequency.Update100;
this.PistonsX = new List<IMyTerminalBlock>();
this.PistonsY = new List<IMyTerminalBlock>();
this.PistonsZ = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyPistonBase>(PistonsX, x => x.CustomName.Contains("X") || x.CustomName.Contains("x"));
GridTerminalSystem.GetBlocksOfType<IMyPistonBase>(PistonsY, x => x.CustomName.Contains("Y") || x.CustomName.Contains("y"));
GridTerminalSystem.GetBlocksOfType<IMyPistonBase>(PistonsZ, x => x.CustomName.Contains("Z") || x.CustomName.Contains("z"));
panel = GridTerminalSystem.GetBlockWithName("LCD Log") as IMyTextPanel;
if (PrinterHeadBlockName != "")
{
printerHeadBlock = GridTerminalSystem.GetBlockWithName(PrinterHeadBlockName) as IMyTerminalBlock;
}
Queue = new List<string>();
}
catch (Exception e)
{
Echo(e.Message);
}
}public void Main(string argument, UpdateType updateType)
{
try
{
if (updateType == UpdateType.Update100)
{
if (Queue.Count > 0)
{if (!isRunning &&
(lastPiston == null ||
(lastPiston.Status != PistonStatus.Extending
&& lastPiston.Status != PistonStatus.Retracting))
)
{
isRunning = true;
Log("Process " + Queue[0] + "...");
ProcessCommand(Queue[0]);
isRunning = false;
Queue.RemoveAt(0);
Runtime.UpdateFrequency = UpdateFrequency.Update100;
}
}
else
{
Runtime.UpdateFrequency = UpdateFrequency.None;
isRunning = false;
}
}if (!isRunning && updateType == UpdateType.Trigger)
{
if (argument == "reset")
{
isRunning = true;
this.Reset();
isRunning = false;
}
else if (argument == "clearlog")
{
isRunning = true;
if (panel != null)
{
panel.WriteText("", false);
}
isRunning = false;
}
else
{string[] args = argument.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string arg in args)
{
Queue.Add(arg);
}
Runtime.UpdateFrequency = UpdateFrequency.Update100;
}
}
}
catch (Exception e)
{
Echo(e.Message);
}
}private bool ProcessCommand(string arg)
{
//Log("Argument: " + arg);
// action for "printer head"
if (arg.Length >= 7 && arg.Substring(0, 7) == "action|")
{
if (printerHeadBlock != null)
{
string[] parts = arg.Split('|');
if (parts[1].ToLower() == "on")
{
printerHeadBlock.ApplyAction("OnOff_On");
Log("Block " + PrinterHeadBlockName + " turned on...");
}
else if (parts[1].ToLower() == "off")
{
printerHeadBlock.ApplyAction("OnOff_Off");
Log("Block " + PrinterHeadBlockName + " turned off...");
}
else
{
Log("Command " + parts[1] + " is unknown, possible values are: on, off");
}
}
else
{
Log("Block " + PrinterHeadBlockName + " not found!");
}
return true;
}
// action reset all pistons
else if (arg == "reset")
{
this.Reset();
return true;
}
// move printer
else
{
Log("Move: " + arg);
int Direction = 1;
string dir = "+";
string axis;
if (arg.Length == 2)
{
axis = arg.Substring(0, 1).ToLower(); // x, y or z
dir = arg.Substring(1, 1); // - or +
}
else if (arg.Length >= 3)
{
axis = arg.Substring(0, 1).ToLower(); // x, y or z
dir = arg.Substring(1, 1); // - or +
Step = float.Parse(arg.Substring(2)); // 1, 14 or 12.4
}
else
{
throw new Exception("Invalid argument: " + arg);
}
if (dir == "-")
{
Direction = -1;
}
else
{
Direction = 1;
}
return this.SetNewPistonPosition(axis, Step, Direction);
}
}private bool SetNewPistonPosition(string axis, float step, int Direction)
{
float stepPerPiston;
string dir = "forward";
if (Direction == -1)
{
dir = "backward";
}
this.Log("Set " + axis + "-Axis " + step + " Step(s) " + dir);
switch (axis)
{
case "x":
stepPerPiston = step / PistonsX.Count;
this.Log("Step per Piston: " + stepPerPiston);
lastPiston = (IMyPistonBase)PistonsX[0];
foreach (IMyPistonBase piston in this.PistonsX)
{
float oldStepLower = piston.MinLimit;
float oldStepUpper = piston.MaxLimit;
float newStep = oldStepLower + (stepPerPiston * Direction);
if ((Direction == -1 && newStep >= piston.LowestPosition)
|| (Direction == 1 && newStep <= piston.HighestPosition)
)
{
piston.MinLimit = newStep;
piston.MaxLimit = newStep;
piston.Velocity = (Speed * Direction);
}
lastPiston = piston;
}
break;
case "y":
stepPerPiston = step / PistonsY.Count;
this.Log("Step per Piston: " + stepPerPiston);
lastPiston = (IMyPistonBase)PistonsY[0];
foreach (IMyPistonBase piston in this.PistonsY)
{
float oldStepLower = piston.MinLimit;
float oldStepUpper = piston.MaxLimit;
float newStep = oldStepLower + (stepPerPiston * Direction);
if ((Direction == -1 && newStep >= piston.LowestPosition)
|| (Direction == 1 && newStep <= piston.HighestPosition)
)
{
piston.MinLimit = newStep;
piston.MaxLimit = newStep;
piston.Velocity = (Speed * Direction);
}
lastPiston = piston;
}
break;
case "z":
stepPerPiston = step / PistonsZ.Count;
this.Log("Step per Piston: " + stepPerPiston);
lastPiston = (IMyPistonBase)PistonsZ[0];
foreach (IMyPistonBase piston in this.PistonsZ)
{
float oldStepLower = piston.MinLimit;
float oldStepUpper = piston.MaxLimit;
float newStep = oldStepLower + (stepPerPiston * Direction);
if ((Direction == -1 && newStep >= piston.LowestPosition)
|| (Direction == 1 && newStep <= piston.HighestPosition)
)
{
piston.MinLimit = newStep;
piston.MaxLimit = newStep;
piston.Velocity = (Speed * Direction);
}
lastPiston = piston;
}
break;
}
Log($"{lastPiston.CustomName}: {lastPiston.Status}");
return true;
}private void Log(string message)
{
if (panel != null)
{
panel.WriteText(message + Environment.NewLine, true);
}
}private void Reset()
{
Log("Reset all Pistons");
foreach (IMyPistonBase piston in this.PistonsX)
{
piston.MinLimit = 0;
piston.MaxLimit = 0;
piston.Velocity = (Speed * -1);
}
foreach (IMyPistonBase piston in this.PistonsY)
{
piston.MinLimit = 0;
piston.MaxLimit = 0;
piston.Velocity = (Speed * -1);
}
foreach (IMyPistonBase piston in this.PistonsZ)
{
piston.MinLimit = 0;
piston.MaxLimit = 0;
piston.Velocity = (Speed * -1);
}
}