Prusa i3 Mk3s+ 串行 gcode 读写不一致 - C#

问题描述 投票:0回答:1

我正在做一个延长的周末项目,我想看看我是否可以通过串行端口和 C# 从我的 Windows PC 发送和打印 GCODE 文件。

我正在连接打印机,但在尝试写入串行流时我没有得到一致的结果。我什至不确定我的串行端口设置是否正确,例如,我找不到任何关于 OctoPrint 如何连接到我的打印机的好例子。我认为我的问题是我一次发送了太多数据,但我也在努力从串行连接中读取并等待“确定”,因为它们似乎出现故障。

我可以连接并发送单线,没问题。一旦我给它一个包含许多行的整个文件,打印机就会到达文件的各个部分并挂起。

如何通过串行端口将大文件传输到 3D 打印机而不会使打印机内部缓冲区过载?

我使用的代码:

private static async Task Main(string[] args)
{
    var ports = SerialPort.GetPortNames();

    if (!ports.Any())
    {
        Console.WriteLine("No ports found");
        Console.WriteLine("Press any key to continue...");
        Console.WriteLine();
        Console.ReadKey();
    }
    else
    {
        using (SerialPort mySerialPort = new SerialPort(ports.First()))
        {
            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;

            mySerialPort.Open();

            mySerialPort.DataReceived += DataRecieved;

            using (var fileToPrint = File.OpenRead({Path to GCODE file})
            using (var lineReader = new StreamReader(fileToPrint))
            {
                while (!lineReader.EndOfStream && lineReader is not null)
                {
                    var line = await lineReader.ReadLineAsync() ?? string.Empty;

                    if (!line.StartsWith(";"))
                    {
                        var cleanLine = line. Split(";").First().Trim();

                        mySerialPort.WriteLine(cleanLine);
                    }
                }
            }

            Console.WriteLine("Press any key to continue...");
            Console.WriteLine();
            Console.ReadKey();

            mySerialPort.Close();
        }
    }
}

private static void DataRecieved(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;

    var line = sp.ReadLine();

    Console.WriteLine("Data from printer: {0}", line);
}
c# serial-port 3d-printing
1个回答
0
投票

为我解决这个问题的代码:

具体来说:

  • 以更好的方式阅读回复,据我所知,我没有阅读完整的行,也没有一直听到“ok”的回复。
  • 使用事件等待处理程序 (AutoReset) 告诉作者何时可以向打印机发送更多数据

需要改进的地方:

  • 我仍然不确定我是否正确连接到打印机。我读取接收到的数据的方式感觉不对。
  • 捕获打印机的忙碌响应并将下一条消息延迟几毫秒,以免向串行连接发送垃圾邮件。
internal class Program
{
    private static AutoResetEvent okWaiter = new AutoResetEvent(false);

    private static async Task Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
            .CreateLogger();

        // Starting application
        Log.Information("Application starting...");

        try
        {
            var ports = SerialPort.GetPortNames();

            if (!ports.Any())
            {
                Log.Error("No ports found");
                Log.Information("Press any key to continue...");
                Console.ReadKey();
            }
            else
            {
                using (SerialPort printer = new SerialPort(ports.First()))
                {
                    printer.BaudRate = 115200;
                    printer.Parity = Parity.None;
                    printer.StopBits = StopBits.One;
                    printer.DataBits = 8;
                    printer.Handshake = Handshake.None;

                    printer.Open();

                    printer.DataReceived += DataReceived;

                    var sender = Task.Factory.StartNew(() =>
                    {
                        okWaiter.Set();
                        using (var fileToPrint = File.OpenRead({Path to GCODE}))
                        using (var lineReader = new StreamReader(fileToPrint))
                        {
                            while (!lineReader.EndOfStream && lineReader is not null)
                            {
                                var line = lineReader.ReadLine() ?? string.Empty;

                                if (!line.StartsWith(";"))
                                {
                                    var cleanLine = line.Split(";").First().Trim();

                                    okWaiter.WaitOne();
                                    Log.Information("Sending: {gcode}", cleanLine);
                                    printer.WriteLine(cleanLine);

                                }
                            }
                        }

                        Log.Information("Print complete");
                    });

                    Log.Information("Press any key to continue...");
                    Console.ReadKey();

                    printer.Close();
                }
            }
        }
        catch (Exception e)
        {
            Log.Error(e, "Application error");
        }
        finally
        {
            // Closing application
            Log.Information("Application closing...");
            await Log.CloseAndFlushAsync();
        }
    }

    private static void DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;

        using (var textReader = new StreamReader(sp.BaseStream))
        {
            while (!textReader.EndOfStream)
            {
                var line = textReader.ReadLine() ?? "";

                Log.Information("Response: {response}", line);

                if (line.StartsWith("T:"))
                {
                    var pattern = @"\d+\.\d{1,2}";
                    var temps = line.Split(" ");

                    var nozzleTemp = Regex.Match(temps.First(), pattern);
                    var bedTemp = Regex.Match(temps.Last(), pattern);

                    Console.Title = $"Extruder {nozzleTemp} Bed {bedTemp}";
                }

                if (line == "ok")
                {
                    okWaiter.Set();
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.