前回の記事では、PLR-7 AFR ANALYZERをPCとLAN接続しようと試みましたが、IPアドレスのセグメント不一致により通信ができず、一旦断念しました。
今回は気を取り直して、PLR-7とPCをUSB経由で接続し、C#でWindowsフォームアプリを作成してA/F(空燃比)値の取得に成功したところまでの流れをご紹介します。
■ USB接続でPLR-7をPCに認識させる
PLR-7はUSB経由でPCに接続すると、「USB Serial Port(COMポート)」として認識されます。
ドライバが正しくインストールされていれば、Windowsのデバイスマネージャーに以下のように表示されます。
ポート(COMとLPT)
└ USB Serial Port (COM9)
このCOMポート番号は、後ほどC#アプリで通信ポートとして指定するため、必ずメモしておきます。私の場合は「COM9」でした。
■ PLR-7との通信仕様を確認
USB経由の通信は、実際にはシリアル通信(RS-232C)と同様のプロトコルで動作します。
PLR-7のマニュアルによると、通信仕様は以下のとおりです。
| 項目 | 設定値 |
|---|---|
| ボーレート | 115200 bps |
| データビット | 8ビット |
| パリティ | なし |
| ストップビット | 1ビット |
また、PLR-7は「RMD\r\n」というコマンドを送ることで、現在の測定値を返してくれる仕様です。
このレスポンスは次のような形式になります。
RMD,2,3,0,2, 120.43
この最後の数値(120.43)が、現在のA/F値となります。
■ C#でWindowsフォームアプリを作成
Visual StudioでWindowsフォームアプリケーションのプロジェクトを作成し、以下のような構成でアプリを作りました。
UI要素
TextBox(名前:textBox_AF_Value)
→ 取得したA/F値をリアルタイムに表示する領域
実装の流れ(概要)
- 起動時にPLR-7をリモートモードに切り替える(
SRM,01\r\n) - 続いて測定モードに切り替える(
AOP,01\r\n) - 一定間隔(0.1秒)で
RMD\r\nを送信 - PLR-7から返ってきたレスポンス(例:
RMD,2,3,0,2, 120.41)の最後の値を抽出 - TextBoxに表示
■ 実際のC#コード
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AF計の値出力アプリ
{
public partial class Form1 : Form
{
private SerialPort serialPort;
private Timer requestTimer;
private StringBuilder receiveBuffer = new StringBuilder();
public Form1()
{
InitializeComponent();
serialPort = new SerialPort("COM9", 115200, Parity.None, 8, StopBits.One);
serialPort.DataReceived += SerialPort_DataReceived;
try
{
serialPort.Open();
Debug.WriteLine("シリアルポートを開きました。");
InitializeRemoteAndMeasurementModeAsync();
}
catch (Exception ex)
{
MessageBox.Show("シリアルポート接続エラー: " + ex.Message);
}
}
private async void InitializeRemoteAndMeasurementModeAsync()
{
try
{
serialPort.Write("SRM,01\r\n"); // リモートモード
await Task.Delay(500);
serialPort.Write("AOP,01\r\n"); // 測定モード
await Task.Delay(5000); // 測定モード有効まで待機
requestTimer = new Timer();
requestTimer.Interval = 100; // 0.1秒ごとに送信
requestTimer.Tick += RequestTimer_Tick;
requestTimer.Start();
}
catch (Exception ex)
{
Debug.WriteLine("初期化エラー: " + ex.Message);
}
}
private void RequestTimer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
try
{
serialPort.Write("RMD\r\n");
}
catch (Exception ex)
{
Debug.WriteLine("送信エラー: " + ex.Message);
}
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string incoming = serialPort.ReadExisting();
receiveBuffer.Append(incoming);
while (receiveBuffer.ToString().Contains("\r\n"))
{
string buffer = receiveBuffer.ToString();
int endIndex = buffer.IndexOf("\r\n");
string oneLine = buffer.Substring(0, endIndex);
receiveBuffer.Remove(0, endIndex + 2);
Match match = Regex.Match(oneLine, @"RMD,\d+,\d+,\d+,\d+,\s*(-?\d+\.\d+)");
if (match.Success)
{
string afValue = match.Groups[1].Value;
Invoke(new Action(() =>
{
textBox_AF_Value.Text = afValue;
}));
}
}
}
catch (Exception ex)
{
Debug.WriteLine("受信エラー: " + ex.Message);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort != null && serialPort.IsOpen)
{
serialPort.Close();
}
}
private void textBox_AF_Value_TextChanged(object sender, EventArgs e)
{
}
}
}
■ 値の受信と表示に成功
PLR-7からの応答は分割されて届くことがあるため、SerialPort.DataReceived イベントで受信したデータを一時的にバッファにためて、改行(\r\n)で1行ずつ分割して処理しました。
正規表現を使って、レスポンスから数値部分のみを抽出し、TextBoxに表示することで、リアルタイムにA/F値が画面に表示されるアプリが完成しました。
■ 今後の展開
次回は、このアプリにロガー機能(CSV形式での保存)を追加し、A/F値の記録とファイル保存ができるようにしていきます。
また、取得したデータをグラフ化することも検討しています。
■ まとめ
- USB接続では、PLR-7は「USB Serial Port(COMポート)」として扱える
- C#でのシリアル通信は
SerialPortクラスを使用すれば比較的簡単 - 正確な応答を得るためには、リモートモード・測定モードへの切り替えが必要
- A/F値の取得と画面表示までは成功
次回の記事では、ログ機能の追加とCSV保存の仕組みを紹介します。
同じようにPLR-7をPCで活用したい方の参考になれば幸いです。
ここまで読んでいただきありがとうございました。
技術書の購入コストを抑えてスキルアップするなら

ここまで読んでいただきありがとうございます。最後に宣伝をさせてください。
プログラミングの技術書や参考書は、1冊3,000円〜5,000円するものも多く、出費がかさみがちです。Kindle Unlimitedであれば、月額980円で500万冊以上の書籍が読み放題となります。
気になる言語の入門書から、アルゴリズム、基本設計の専門書まで、手元のスマホやPCですぐに参照可能です。現在は「30日間の無料体験」や、対象者限定の「3か月499円プラン」なども実施されています。まずはご自身のアカウントでどのようなオファーが表示されるか確認してみてください。
