Crystal-lang 访问串口

Crystal-lang Accessing Serial port

我想使用 Crystal lang 访问串口。

我在 python 中有以下代码。我想为宠物项目编写等效的 Crystal-lang 代码。

import serial

def readSerData():

    s = ser.readline()
    if s:
        print(s)
        result = something(s) #do other stuff
        return result

if __name__ == '__main__':

    ser = serial.Serial("/dev/ttyUSB0", 9600)
    while True:
        data = readSerData()
        #do something with data

我找不到任何用于访问串行端口的库。

在crystal-lang中访问串口的正确方法是什么?

提前致谢。

分多个部分回答这个问题更容易真正涵盖所有内容:

问:如何访问 linux/bsd 上的串口?

A:将其作为文件打开。 在 linux/bsd 上,插入设备时会建立串行连接,然后在 [= 下的某处列出11=](如今,通常为 /dev/ttyUSB0)。为了访问此连接,您只需像打开普通文件一样打开它。有时这实际上足以开始与设备通信,因为现代硬件通常适用于所有波特率和默认标志。

问:如何在 linux/bsd 上配置 serial/tty 设备?

A:如果可用就设置termios flags on the file. If you do need to configure your connection to set things like baud rate, IXON/IXOFF etc, you can do it before even running your program using stty。例如。要设置波特率,您可以 运行: stty -F /dev/ttyUSB0 9600。设置完成后,您可以将其作为文件打开并开始使用。

如果您想要一种简单的方法从您的应用程序配置设备,您可以使用 Process.run 从 crystal 生成 stty。我可能会在下一个解决方案中推荐这种方法..

问:如何在不使用 stty 的情况下从 crystal 设置 termios 标志?

答:直接使用termios posix函数 Crystal 实际上已经为 FileDescriptor 句柄提供了一些常见的 termios 设置,例如 cooked, which means it has minimal termios bindings。我们可以从现有的代码中获取灵感:

require "termios" # See above link for contents

#Open the file
serial_file = File.open("/dev/ttyACM0")
raise "Oh no, not a TTY" unless serial_file.tty?

# Fetch the unix FD. It's just a number.
fd = serial_file.fd

# Fetch the file's existing TTY flags
raise "Can't access TTY?" unless LibC.tcgetattr(fd, out mode) == 0

# `mode` now contains a termios struct. Let's enable, umm.. ISTRIP and IXON
mode.c_iflag |= (Termios::InputMode::ISTRIP | Termios::InputMode::IXON).value
# Let's turn off IXOFF too.
mode.c_iflag &= ~Termios::InputMode::IXOFF.value

# Unfun discovery: Termios doesn't have cfset[io]speed available
# Let's add them so changing baud isn't so difficult.
lib LibC
  fun cfsetispeed(termios_p : Termios*, speed : SpeedT) : Int
  fun cfsetospeed(termios_p : Termios*, speed : SpeedT) : Int
end

# Use the above funcs to set the ispeed and ospeed to your nominated baud rate.
LibC.cfsetispeed(pointerof(mode), Termios::BaudRate::B9600)
LibC.cfsetospeed(pointerof(mode), Termios::BaudRate::B9600)
# Write your changes to the FD.
LibC.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))

# Done! Your serial_file handle is ready to use.

要设置任何其他标志,请参考我刚找到的termios manual, or this nice serial guide

问:有没有图书馆可以帮我做这一切?

A: 没有 :( . 不是我能看到的,但如果有人做了它会很棒。如果有人做了一个,可能并不需要太多工作既得利益:)