读取串口输入,直到控制字符表示消息结束。

3

我正在使用knewter/erlang-serial和Elixir,并尝试读取通过串行输入从Arduino接收控制信号后传入的JSON字符串(例如{"temperature":20.40,"humidity":30.10})。

defmodule MyApp.SerialInput do
  require Logger


  def start_link do
    serial_pid = :serial.start [{:open, "/dev/cu.usbmodem1431"}, {:speed, 115200}]

    control_signal = "1"
    :timer.send_interval 5000, serial_pid, {:send, control_signal}

    wait_for_new_values serial_pid
  end


  defp wait_for_new_values(serial_pid) do
    receive do
      {:data, jsonString} when is_binary(jsonString) ->
        Logger.debug "received :data #{inspect jsonString}"

    wait_for_new_values serial_pid
  end
end

我现在的问题是,我获得串行输入数据后,它会被分割成这样(有时候一次性通过):

[debug] received :data "{\"t"
[debug] received :data "emperature\":19.00,\"humidity\":42.00}\r\n"

[debug] received :data "{\"temperature\":19.60,\"humidity\":41"
[debug] received :data ".00}\r\n"

[debug] received :data "{\"temperature\":19.50,\"humidity\":40.90}\r\n"

[debug] received :data "{\"temperature\":19.50,\"humi"
[debug] received :data "dity\":40.90}\r\n"

[debug] received :data "{\"temperat"
[debug] received :data "ure\":19.50,\"humidity\":41.30}\r\n"

有没有一种方法可以告诉接收块等待直到字符串末尾出现\r\n或固定数量的字符或类似的东西? 如果没有,最好的方法是什么,在wait_for_new_values之外保持状态直到\r\n出现,然后连接这些内容?

1个回答

5
< p > receive 块是一种非常低级的函数,因此它不能执行这样的专门任务。

Elixir中的状态是显式的,并且可以通过可选参数累加器(在此处为acc)实现。您可以稍后将累积值传递给递归调用,并仅在以 "\r\n" 结尾时打印它。

defp wait_for_new_values(serial_pid, acc \\ "") do
  receive do
    {:data, chunk} when is_binary(chunk) ->
      acc = acc + chunk
  end

  if String.ends_with? acc, "\r\n"
    Logger.debug "received :data #{inspect acc}"
    acc = ""
  end

  wait_for_new_values serial_pid, acc
end

仅供参考:使用此算法,您可以获得多个温度湿度对。如果您想要精确地接收一条记录,则必须从缓冲区的开头扫描“\r\n”。 - Miroslav Prymek
好的观点,但似乎控制信号只触发一次读取。这可能是一个问题,也可能不是,这取决于实现方式。 - Patrick Oscity
到目前为止似乎没有问题,我的小树莓派自昨天以来一直运行顺畅,并且每30秒收集测量数据非常完美。@MiroslavPrymek 当Arduino从我的Elixir进程首先接收到控制信号(:timer.send_interval 5000, serial_pid, {:send, control_signal})后,它只会发送一对值,因此不应该同时有多个值。 - optikfluffel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接