草庐IT

go - 3D 打印机串行通信

coder 2023-07-01 原文

我正在努力构建一个可以与 Golang 中的 3D 打印机通信的工具。我遇到的问题困扰着我,似乎我可以启动与打印机的连接。 LCD 屏幕发生变化,代码开始运行,但每当我尝试从端口读取时,我都没有得到任何回复。具体来说,他们应该返回“确定”消息,以便我知道继续下一条消息。此外,当我发送 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 并重新打开控制台,它似乎工作正常。

最佳答案

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

https://github.com/distributed/sers

关于go - 3D 打印机串行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53973951/

有关go - 3D 打印机串行通信的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  3. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  4. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  5. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  6. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  7. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  8. ruby - 如何打印 ruby​​ 对象的实例变量 - 2

    classPacketdefinitialize(name,age,number,array)@name=name@age=age@number=number@neighbors=arrayendendp1=Packet.new("n1",5,2,[1,2,3,4])putsp1.name我有上面的代码,但是每当我执行puts语句时,我都会收到nameisnotamethod的错误。我不知道任何其他方式来打印p1的名称。如何打印姓名? 最佳答案 这里的问题是,虽然您拥有实例变量,但您并未使它们可访问。attr_reader:vari

  9. ruby - 如何打印出 Mechanized 存储的 cookie? - 2

    我正在使用mechanize登录网站,然后检索页面。我遇到了一些问题,我怀疑这是由于cookie中的某些值造成的。当Mechanize登录网站时,我假设它存储了cookie。如何通过Mechanize打印出存储在cookie中的所有数据? 最佳答案 代理有一个cookie方法。agent=Mechanize.newpage=agent.get("http://www.google.com/")agent.cookiesagent.cookies.to_scookie返回一个Mechanize::Cookiesobject

  10. ruby - 如何以表格格式快速打印 Ruby 哈希值? - 2

    有没有办法快速将表格格式的ruby​​哈希打印到文件中?如:keyAkeyBkeyC...1232343451253474456...其中散列的值是不同大小的数组。还是使用双循环是唯一的方法?谢谢 最佳答案 试试我写的这个gem(在表中打印散列、ruby对象、ActiveRecord对象):http://github.com/arches/table_print 关于ruby-如何以表格格式快速打印Ruby哈希值?,我们在StackOverflow上找到一个类似的问题:

随机推荐