【问题标题】:3D Printer Serial Communication3D 打印机串行通信
【发布时间】:2019-05-27 04:32:38
【问题描述】:

我正在开发一个可以与 Golang 中的 3D 打印机通信的工具。我遇到的问题困扰着我,似乎我可以启动与打印机的连接。 LCD 屏幕发生变化,代码开始运行,但每当我尝试从端口读取数据时,我都没有得到任何返回。具体来说,他们应该返回“ok”消息,所以我知道继续下一条消息。此外,当我发送 Gcode 字符串时,它似乎永远无法理解它们,据我所知,它们只是被丢弃了。这是我正在使用的示例代码:

package printer

import (
    "errors"
    "fmt"
    "log"
    "strings"
    "time"
    "io/ioutil"
    "path/filepath"

    "github.com/tarm/serial"
)

//Printer is a connection to a reprap or similar printer
type Printer struct {
    s *serial.Port
}

//Connect creates the printer struct and returns it after initing it
func Connect(port string, speed int64) Printer {
    devices, err := getSerialDevices()
    if err != nil {
        log.Println(err)
    }
    for _, value := range devices {
      log.Println("Found device: ", value)
    }
    c := &serial.Config{Name: devices[0], Baud: 115200, ReadTimeout: time.Second * 5}
    s, err := serial.OpenPort(c)
    if err != nil {
        log.Println("Failed to open communication")
        log.Fatal(err)
    }

    p := Printer{}

    p.s = s

    p.readPump()
    p.readPump()

    return p
}

func (p *Printer) readPump() string {
    output := ""
    oldLength := -1
    for {
        buf := make([]byte, 128)
        /*
         This appears to be where part of the problem is,
         I never get anything back from the printer.  Per the
         tarm documentation since I'm in non-blocking mode
         I don't capture the error because it's an EOF
         */
        n, _:= p.s.Read(buf)

        /*if err != nil {
            log.Println("Failed to readPump")
            log.Fatal(err)
        }*/
        output += fmt.Sprintf("%s", buf[:n])
        if len(output) == oldLength {
            return output
        }

        oldLength = len(output)

    }
}

//SendCommand sends a single GCODE command to the printer
func (p *Printer) SendCommand(g string) error {
    g = g + "\n"
    _, err := p.s.Write([]byte(g))
    if err != nil {
        log.Println("Failed to write: ", g)
        log.Fatal(err)
    }
    if !strings.HasSuffix(p.readPump(), "ok\n") {
        log.Println(errors.New("command did not complete successfully"))
    }

    return nil
}

//Retrieve the absolute path for serial devices
func getSerialDevices() ([]string, error) {
    log.Println("getting serial devices")
    devices, err := ioutil.ReadDir("/dev/serial/by-id")
    if err != nil {
        log.Println(err)
        return nil, err
    }
    deviceList := make([]string, len(devices))
    for index, deviceLink := range devices {
        //log.Println("Found device: ", deviceLink.Name())
        abs, err := filepath.EvalSymlinks("/dev/serial/by-id/" + deviceLink.Name())
        //log.Print("Absolute Device: ")
        //log.Println(abs)
        deviceList[index] = abs
        if err != nil {
            log.Println(err)
            return nil, err
        }
    }
    return deviceList, nil
}

这是我用来调用打印机的代码:

package main

import (
    "fmt"
    "log"

    "github.com/david-fry/go-3dprinter"
)

func main() {
    fmt.Println("Connecting to Printer...")
    p := printer.Connect("COM3", 115200)

    fmt.Println("Moving Extruder...")
    err := p.SendCommand("G28")
    err = p.SendCommand("G1 Z20")
    err = p.SendCommand("G1 Y100")
    err = p.SendCommand("G1 X100")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Heating Extruder...")
    err = p.SendCommand("M109 S100")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Cooling Extruder...")
    err = p.SendCommand("M109 S100")

    if err != nil {
        log.Fatal(err)
    }

}

编辑:这是一个 Wanhao Duplicator 6。我可以让它与 Cura 和 Octoprint 一起工作,所以我很确定串行通信工作正常,我只是错过了一些东西。

EDIT2:更令人费解的是,如果我连接 Arduino IDE 并将串行波特率设置为 250000,它会向控制台吐出垃圾。如果我关闭它并打开 Cura,让它检测打印机,然后关闭 Cura 并重新打开控制台,它似乎工作正常。

【问题讨论】:

  • 您应该在问题中包含打印机型号或您使用的控制器。
  • 在底部更新。我知道可以与打印机进行通信,因为我已经让它与 Cura 和 Octoprint 一起工作得很好。
  • 许多 3d 打印机都是基于 Arduino 的。在典型的 PC 操作系统配置中,打开串行端口将触发对引导加载程序的重置,然后需要一两秒来超时并运行主程序(“草图”)。您的代码尝试立即对话。试着在你说话之前延迟几秒钟。
  • 所以,我认为部分问题是我也无法将端口设置为 250000 波特。我一直在寻找一种在 Go 中设置波特率的方法,但我空手而归。例如,系统调用包不允许特定的波特率。

标签: go serial-port 3d-printing


【解决方案1】:

如果有人在将 golang 连接到 3D 打印机时遇到问题,我终于找到了解决方案。事实证明,go 标准库中系统调用的当前实现不支持非规范波特率。大多数 3D 打印机以 250K 波特率运行,并且不支持此速率,因此它将失败。使用实现 termios2 规范的包允许异常比特率并解决问题。这是我正在使用并且运行良好的当前实现。

https://github.com/distributed/sers

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多