读取串行输入,直到控制字符指示消息结束
Read serial input until control char indicates end of message
我正在使用 knewter/erlang-serial 和 Elixir 并尝试读取 JSON-String(例如 {"temperature":20.40,"humidity":30.10}
在接收到控制信号后通过串行输入从 Arduino 传入:
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
出现然后连接这些?
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
我正在使用 knewter/erlang-serial 和 Elixir 并尝试读取 JSON-String(例如 {"temperature":20.40,"humidity":30.10}
在接收到控制信号后通过串行输入从 Arduino 传入:
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
出现然后连接这些?
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