读取串行输入,直到控制字符指示消息结束



我正在使用带有Elixir的knewter/elang串行,并尝试读取JSON字符串(例如,在Arduino接收到控制信号后,通过串行输入从其输入的{"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}rn"
[debug] received :data "{"temperature":19.60,"humidity":41"
[debug] received :data ".00}rn"
[debug] received :data "{"temperature":19.50,"humidity":40.90}rn"
[debug] received :data "{"temperature":19.50,"humi"
[debug] received :data "dity":40.90}rn"
[debug] received :data "{"temperat"
[debug] received :data "ure":19.50,"humidity":41.30}rn"

有没有办法告诉接收块等待,直到rn出现在字符串末尾,或者等待固定数量的字符或类似的东西?如果不是,在wait_for_new_values之外保持状态直到rn出现,然后连接这些状态的最佳方法是什么?

receive块是一个相当低级别的函数,因此它将无法完成如此专业化的工作。

Elixir中的State是显式的,可以通过可选参数累加器(在本例中为acc)来实现。稍后,您可以将累积值向下传递给递归调用,并仅在其以"rn"结束时打印它。

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, "rn"
Logger.debug "received :data #{inspect acc}"
acc = ""
end
wait_for_new_values serial_pid, acc
end

最新更新