python - Crystal-lang 访问串口
问题描述
我想使用 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
我找不到任何用于访问串行端口的库。
在水晶语言中访问串口的正确方法是什么?
提前致谢。
解决方案
要真正涵盖所有内容,更容易分多个部分回答这个问题:
问:如何在 linux/bsd 上访问串口?
答:将其作为文件打开。在 linux/bsd 上,在插入设备的那一刻建立串行连接,然后在下面的某个地方列出/dev/
(这些天,通常为 /dev/ttyUSB0)。为了访问此连接,您只需像打开常规文件一样打开它。有时这实际上足以开始与设备通信,因为现代硬件通常适用于所有波特率和默认标志。
问:如何在 linux/bsd 上配置串口/tty 设备?
A:在文件上设置termios标志。如果您确实需要配置连接以设置波特率、IXON/IXOFF 等内容,您甚至可以在使用stty(如果可用)运行程序之前执行此操作。例如。设置您可以运行的波特率:stty -F /dev/ttyUSB0 9600
. 设置完成后,您可以将其作为文件打开并开始使用。
如果您想要一种从应用程序配置设备的简单方法,您可以stty
使用水晶生成。Process.run
我可能会在下一个解决方案中推荐这种方法..
问:如何在不使用 stty 的情况下从水晶设置 termios 标志?
A: 直接使用 termios posix 函数。
Crystal 实际上为 FileDescriptor 句柄提供了一些常见的 termios 设置,例如cooked
,这意味着它已经具有最少的termios 绑定。我们可以从使用现有代码开始:
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 手册或我刚刚找到的这个不错的串行指南。
问:有图书馆可以为我做这一切吗?
A:不 :( 。不是我能看到的,但如果有人做到了那就太好了。如果他们有既得利益,那么做一个人可能没什么工作:)
推荐阅读
- javascript - 如何保留非排序数组(Javascript)
- angular - 当 Ionic 4 中不存在事件时如何运行该函数
- python - Python melt dataframe based on values of comma-separated character vector column
- microsoft-graph-api - 如果仅更改 is_read 字段,则消息增量 API 无法返回字段
- haskell - 如何在 Haskell 中找到坐标元组列表的平均值?
- oracle-adf - 以编程方式更新 adf 表单
- sql - 即使重复值不同,也将数据分组到不同的分区
- c - Math equation user input validation
- javascript - 文本到语音音频在浏览器中无法同步工作
- spring - 我们应该在 Hibernate 和 Springboot 中使用什么。SessionFactory 或 EntityManager