このページでは、AVModbus をアプリケーションに追加し、Modbus RTU で値を読み書きします。 用語が初めての場合は Modbus の基礎 を先に読むと理解しやすくなります。
実機での最短手順を探している場合は、すでに設定済みの XIAO ESP32-C5 チュートリアル を利用してください。
1. 準備する
- Erlang / OTP と Elixir(このリポジトリの
.tool-versionsを参照) - AtomVM
release-0.7に対応したファームウェア - UART を利用できる基板と、電圧が適合する RS485 トランシーバー
- 通信先の Modbus RTU Server(または Server に設定した 2 台目の基板)
配線を変更するときは電源を切ってください。トランシーバーの電源電圧と信号電圧も確認します。
2. ライブラリを追加する
利用側の mix.exs に次の依存関係を追加します。
defp deps do
[
{:avmodbus, "~> 0.1.0"},
{:exatomvm, github: "atomvm/exatomvm", runtime: false},
{:atomvm, "~> 0.7.0-beta.0", runtime: false}
]
endmix deps.get で依存関係を取得します。exatomvm は AtomVM へのビルドに使う開発用依存関係です。
ホスト上で AVModbus を使うだけなら、AtomVM 向けの追加依存関係は不要です。
リポジトリの開発版を使う場合は、上記の :avmodbus を
{:avmodbus, git: "https://github.com/piyopiyoex/avmodbus.git", branch: "main"} に置き換えてください。
付属サンプルは開発用として引き続き path: 参照を使います。
3. UART を設定する
XIAO ESP32-C5 での設定例です。UART1、D4 / GPIO23、D5 / GPIO24 を使います。
import Config
config :avmodbus,
uart_peripheral: "UART1",
uart_speed: 9_600,
uart_tx_pin: 23,
uart_rx_pin: 24,
uart_data_bits: 8,
uart_parity: :none,
uart_stop_bits: 1この例は通信速度 9,600 baud、8N1(データ 8 bit、パリティなし、ストップ 1 bit)の設定です。 基板によってピン番号は異なります。AtomVM のコンソールと同じ UART は使わないでください。
4. Client から読み取る
{:ok, client} = AVModbus.Client.start_link(transport: :rtu, timeout: 1_000)
case AVModbus.Client.read_holding_registers(client, 1, 0, 2) do
{:ok, values} -> IO.inspect(values, label: "Holding Registers")
{:error, reason} -> IO.inspect(reason, label: "Modbus error")
end1 は通信先の Unit ID、0 は読み始めるアドレス、2 は読み取る個数です。
成功すると、たとえば Holding Registers: [123, 456] と表示されます。
Client は必要な UART を開き、通信が切れた場合の再接続も管理します。
複数の UART を使いたい場合は start_link/1 の serial: オプションで個別に設定できます。
5. 値を書き込む
Unit ID 1 の Holding Register のアドレス 10 に、42 を書き込みます。
:ok = AVModbus.Client.write_single_register(client, 1, 10, 42)書き込みが実行済みか不明な状態で自動再送すると、同じ操作が繰り返されるおそれがあります。 AVModbus の自動リトライは、明示された読み取り処理に限っています。
終了時は AVModbus.Client.stop(client) を呼びます。
6. Modbus TCP を使う場合
TCP では UART 設定は不要です。接続先の IP アドレスとポート番号を指定します。
{:ok, client} =
AVModbus.Client.start_link(
transport: :tcp,
host: "192.168.1.20",
port: 502,
timeout: 1_000
)
AVModbus.Client.read_holding_registers(client, 1, 0, 2)注意: Modbus TCP の通信は暗号化されません。信頼できるネットワーク内で使ってください。
通信できないとき
| 症状 | 確認すること |
|---|---|
{:error, :uart_pins_not_configured} | TX / RX ピンを設定し、アプリケーションを再ビルドして .avm を書き込んだか |
{:error, :timeout} | Server の起動、Unit ID、アドレス、通信速度・パリティが一致しているか |
| CRC エラー | GND の共通接続、配線、通信速度、パリティを確認する |
| コンソールが読めない | UART0 など、コンソールと Modbus の UART が重なっていないか |
| RS485 で応答がない | A / B の端子表記と配線、トランシーバーの電圧が正しいか |
アドレスは AVModbus では 0 から始まります。機器の説明書が 40001 のような表記を使う場合は、
Modbus の基礎も確認してください。
RS485 の A / B の表記は製品によって異なります。電源を切り、機器の資料を確認してから配線を変更してください。