Daten über serielle Schnittstelle an 3D Drucker senden

  • .NET (FX) 4.0
  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    Daten über serielle Schnittstelle an 3D Drucker senden

    Hallo,
    ich bin stark sehbehindert und habe einen Creality CR-10S 3D Drucker. Mit meinem Sehrest kann ich die Beschriftung auf dem Display zwar nicht lesen, kann aber die Position der Markierten Zeile sehen. Mit einer sehenden Person habe ich die ganze Menüstruktur in eine Textdatei geschrieben, um den Drucker über den Drehknopf am Display bedienen zu können. Nun möchte ich den Nachfolger, da mich der CR-10S überzeugt hat. Der Nachfolger, CR-10S Pro, besitzt allerdings ein Touchdisplay, welches ich gar nicht bedienen kann. Daher habe ich ein Programm für Windows geschrieben, über welches ich dann den Drucker steuern kann. Bevor jetzt jemand mit dem Satz kommt, welches ein erneutes Erfinden eines Rades beinhaltet, möchte ich es erklären. Ich weiß, das man dieses Problem auch mit Octoprint umgehen kann. Ich habe sogar einen Raspberry mit octoprint, allerdings erreiche ich das Programm über eine Weboberfläche. Erstens kann ein Screenreader (Sprachausgabe) besser mit reinen Programmen, als mit Weboberflächen umgehen und zweitens befinden sich auf der Oberfläche von Octoprint einige Schaltflächen, die Pfeile oder andere Symbole beinhalten und ich daher nicht weiß, was diese Schaltfläche bewirkt. Außerdem kann ich mein Programm individuell auf meine, bzw. auf die Wünsche von denen anpassen, die es einsetzen. So habe ich z.B. eine Funktion eingefügt, die auf Wunsch beim Aufheizen, in bestimmten Gradintervallen Pieptöne ausgiebt. Auch kann ich festlegen, wieviele Punkte der Druckkopf beim Kalibrieren anspringen soll.

    Nun zu meinem eigentlichen Problem:

    Das Programm funktioniert soweit ganz gut, bis auf die Funktion "Datei drucken". Hier werden die Druckerfunktionen teilweise, falsch oder gar nicht ausgeführt. Wenn ich allerdings vor dem Senden eines Befehls auf das "ok" des letzten warte, funktioniert es. Nur wird dann jedem Befehl eine Pause eingefügt, weil das Programm ja auf das "ok" wartet. Wenn ich Haltepunkte einfüge und die entsprechende Schleife Schritt für Schritt ausführe, funktioniert es auch. Hier gibt es natürlich auch die ungewünschten Pausen. Vielleicht habe ich auch eine falsche Vorstellung von der Kommunikation über einen seriellen Anschluss. Ich dachte bisher, das es wie folgt funktioniert:

    1. Port mit nötigen Parametern versehen
    2. Port öffnen
    3. Daten senden
    3.1. Warten, bis der Sendepuffer leer ist
    3.2. Neue Textzeile aus der zu druckenden Datei senden
    3.3. Daten werden in den Puffer kopiert
    4. Wenn Drucker wieder bereit ist, werden Daten aus dem Ausgangspuffer nachgeladen
    5. Geöffnete Datei schließen

    Ich habe es auch leider erfolglos versucht, den ganzen Dateiinhalt erst einmal in eine Variablen zu schreiben und diese dann als Ganzes an den Drucker zu senden.

    Hier die Hauptfunktion:

    VB.NET-Quellcode

    1. Private Sub DateiSendenBefehl_Click(sender As Object, e As EventArgs) Handles DateiSendenBefehl.Click
    2. If Verbunden Then
    3. DateiDialog.FileName = ""
    4. DateiDialog.Filter = "Alle Dateien (*.*)|*.*"
    5. DateiDialog.Title = "Datei auswählen"
    6. If DateiDialog.ShowDialog = DialogResult.OK Then
    7. Try
    8. 'Die ausgewählte Datei wird geöffnet und zeilenweise an den
    9. 'Drucker gesendet. Dabei wird darauf geachtet, dass
    10. 'der Ausgangspuffer leer ist.
    11. Dateiinhalt = New StreamReader(DateiDialog.FileName)
    12. Do Until Dateiinhalt.EndOfStream Or Not Anschluss.IsOpen
    13. Inhalt = Dateiinhalt.ReadLine
    14. X = 1
    15. Do Until Mid(Inhalt, X, 1) = ";" Or X > Len(Inhalt) Or Mid(Inhalt, X, 1) = vbNewLine
    16. X += 1
    17. Loop
    18. If X <> 1 Then
    19. Do Until Anschluss.BytesToWrite = 0
    20. Application.DoEvents()
    21. Loop
    22. Anschluss.WriteLine(Mid(Inhalt, 1, X - 1))
    23. End If
    24. Application.DoEvents()
    25. Loop
    26. Dateiinhalt.Close()
    27. Catch Fehler As Exception
    28. Using InfoFenster As New InfoFormular
    29. InfoFenster.Text = "Fehler"
    30. InfoFenster.InfoLabel.Text = "Die Datei konnte nicht an den Drucker gesendet werden"
    31. InfoFenster.ShowDialog(Me)
    32. End Using
    33. End Try
    34. End If
    35. Else
    36. Using InfoFenster As New InfoFormular
    37. InfoFenster.Text = "Hinweis"
    38. InfoFenster.InfoLabel.Text = "Es besteht keine Verbindung zum Drucker. Vergewissern sie sich, dass der Drucker eingeschaltet und die Schnittstelle verfügbar ist"
    39. InfoFenster.ShowDialog(Me)
    40. End Using
    41. End If
    42. End Sub



    Ich würde mich sehr über eine hilfreiche Antwort freuen und Danke schon mal im Voraus für eure Mühe.

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Ich habe gestern eine Idee gehabt. Wahrscheinlich ist nicht der Puffer das Problem, sondern der interne freie Speicher des Druckers. Ich habe im Netz gelesen, dass der Befehl "M100" den freien Speicherplatz zurückgeben soll. Leider bekomme ich beim Absenden dieses Befehles eine leere Antwort. An einer anderen Stelle habe ich auch gelesen, dass die Befehle "M100" bis "M199" zur freien Verfügung sehen sollen.

    Weiß jemand von euch, wie ich das bei einem Creality CR-10S abfragen kann?
    Ich habe gehört, dass der Drucker die benötigten Daten aus dem Schreibpuffer der seriellen Schnittstelle herausnimmt. Also habe ich folgende Funktion gebastelt, die vor dem Senden eines Befehls zuerst prüft, ob der Schreibpuffer genügend platz hat. Davor wird der zu sendende Befehl auf das nötigste gekürzt. Leider funktioniert es aber immer noch nicht. Wenn das Programm bei einem Haltepunkt stoppt, frage ich die noch zu schreibende Datengröße ab und bekomme immer "0" heraus. Hat jemand eine Idee, wie ich die korrekte Größe des freien Speichers auslesen kann?

    VB.NET-Quellcode

    1. AnschlussSerialPort.DiscardInBuffer()
    2. AnschlussSerialPort.DiscardOutBuffer()
    3. RueckmeldungText.Text = ""
    4. DateiDialog.FileName = ""
    5. DateiDialog.Filter = "Alle Dateien (*.*)|*.*"
    6. DateiDialog.Title = "Datei auswählen"
    7. If DateiDialog.ShowDialog = DialogResult.OK Then
    8. 'Die ausgewählte Datei wird geöffnet und zeilenweise an den
    9. 'Drucker gesendet. Dabei wird darauf geachtet, dass
    10. 'Im Sendepuffer immer genug Platz für den nächsten Befehl ist.
    11. Dateiinhalt = New StreamReader(DateiDialog.FileName)
    12. Do Until Dateiinhalt.EndOfStream Or Not AnschlussSerialPort.IsOpen
    13. Inhalt = Dateiinhalt.ReadLine
    14. X = Inhalt.IndexOf(";") - 1
    15. If X < 0 Then
    16. X = Inhalt.Length - 1
    17. End If
    18. Do Until X < 0
    19. If Inhalt.Substring(X, 1) <> " " Then
    20. Inhalt = Inhalt.Substring(0, X + 1)
    21. Exit Do
    22. Else
    23. X -= 1
    24. End If
    25. Loop
    26. If X > 0 Then
    27. Do Until AnschlussSerialPort.WriteBufferSize - AnschlussSerialPort.BytesToWrite > Inhalt.Length
    28. Application.DoEvents()
    29. Loop
    30. BefehlSenden(Inhalt)
    31. End If
    32. Application.DoEvents()
    33. Loop
    34. Dateiinhalt.Close()
    35. End If


    Der Drucker Heitzt als erstes die Düse und das Bett auf die gewünschte Temperatur auf und führt zum 0-Punkt. Dann stoppt er und macht nichts mehr. Wenn ich jeden einzelnen Befehl einzeln anstoße, funktioniert es.
    Hast du dir mal die Repos zu Octoprint oder Cura angesehen?
    Beide bieten ja die Möglichkeit direkt über USB zu drucken. (Prusa Slicer bestimmt auch)
    Da könnte man dann vielleicht erfahren was dein Board (Marlin?) erwartet.

    Und auch wenn du sagt du möchtest selber was schreiben, warum nicht die Funktion vom Slicer nutzen?
    Oder Octoprint an den Drucker hängen und dann in deinem Programm die API zum Drucken nutzen?
    docs.octoprint.org/en/master/api/job.html
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.
    Ich habe mir mal den Source Code von Octoprint heruntergeladen und nach den entsprechenden Funktionen, leider erfolglos gesucht. Ich möchte ein eigenes Programm nutzen, weil Octoprint nicht barrierefrei ist. Ich bin Blind und auf einen Screenreader angewiesen. Octoprint hat aber einige Buttons, die nur mit einem Symbol und nicht mit Text beschriftet sind. Bei Cura ist es leider ähnlich. Ich benutze zum Slicen immernoch Cura 1.14, weil diese Version die Letzte ist, die ich einigermaßen bedienen kann. Bis auf die Sache mit der Speichergröße funktioniert mein Programm. Ich kann damit den Druckkopf bewegen, die Temperaturen einstellen, den Drucker kalibrieren und auch eine Datei von der SDKarte drucken. Mir ist letztens der Karteneinschub auf der Platine kaputtgegangen, daher habe ich mich nochmal mit dem Thema beschäftigt, eine Datei direkt an den Drucker zu schicken. Nun habe ich eine neue Platine gekauft und eingebaut. Jetzt funktioniert der Karteneinschub wieder, aber das Problem juckt mich immernoch unter den Nägeln.