概要
TunerStudioを、究める。
一から、iniファイルを作ってみる。
一から、iniファイルを作ってみる手順
burnCommand
queryCommand
pageReadCommand
ochGetCommand
dataReadCommand
これらはすべて、TunerStudioの設定ファイル(配置定義ファイルである mainController.ini など)の[ParameterConfigs] や [Constants] セクション周辺、または通信プロトコル定義で使われるECUとPC間の通信コマンド定義用キーワードです。
TunerStudioがECUとシリアル通信(RS232C、USB、Bluetoothなど)を行う際、どのバイナリデータ(またはアスキー文字)を送信すれば、特定の動作をさせられるかを定義します。
それぞれのコマンドが持つ意味と役割は以下の通りです。
burnCommand (データの永続保存)
- 役割: ECUのRAM(一時メモリ)にある現在のセッティングデータを、フラッシュメモリ(不揮発性メモリ)に書き込み・保存させるコマンド。
- 動作: これを実行しないと、車のキーをOFFにしたときに変更したマップがすべて消えてしまいます。
- 例: burnCommand = "B%2i" (ページ番号を2バイトで指定してBurn命令を送る例)
queryCommand (ECUの識別・確認)
- 役割: TunerStudioが接続されたECUに対して「お前は誰(どのファームウェア)だ?」と身元を問い合わせるためのコマンド。
- 動作: 起動時や接続確立時に最初に送られます。
ECUはこれに対してファームウェアのシグネチャ文字列(例: MS3 Format 0562.03 など)を返します。
これによりTunerStudioは正しい配置定義(.ini)を読み込めます。 - 例: queryCommand = "Q" または "S"
pageReadCommand (設定ページの読み込み)
- 役割: ECU内にある特定の「設定ページ(チューニングマップや定数の塊)」のデータ全体を一括で読み出すためのコマンド。
- 動作: TunerStudioで特定のウインドウを開いたときや、接続時に現在のECUの設定データをPC側に同期する際に使用されます。
- 例: pageReadCommand = "R%2i%2o%2len" (ページ番号、オフセット、長さを指定して読み出す定義)
ochGetCommand (リアルタイムデータの取得)
- 役割: Output Channels(リアルタイムのセンサー情報など)を取得するためのコマンド。
- 動作: エンジン回転数(RPM)、水温、吸気温、空燃比など、ダッシュボードのメーターやロギングに必要なデータを「超高速で繰り返し」ECUから取得するために使われます。
TunerStudioの通信バーストの主軸となる最重要コマンドです。 - 例: ochGetCommand = "A" (旧Megasquirtの例) や "r%2i%2o%2len"
dataReadCommand (特定アドレスデータの読み出し)
- 役割: ページ単位ではなく、より限定された特定のアドレスや範囲のデータを読み出すためのコマンド。
- 動作: プロトコルのバージョン(シリアルプロトコルv3など)によっては、pageReadCommand と統合されていたり、特定の変数(定数)を
ピンポイントで確認・検証したりする際に内部的に呼び出されます。
これらは独自のカスタムECU(ArduinoベースのSpeeduinoやRusEfi、DIYの汎用フルコンなど)を開発し、TunerStudioをそのECUのインターフェースとして対応させる(.iniを自作する)際に必ず設定する必要があります。
サンプルコード
shrikeで、
queryCommand = 'F'
pageReadCommand = 'C'
ochGetCommand = 'O'
に、対応した、pythonプログラム。
import time
import sys
import math
import struct
def get_simulated_rpm():
t = time.ticks_ms()
rpm = 3000 + int(math.sin(t * 0.63) * 2000)
return max(0, rpm)
signature = 'MShift v0.01'
while True:
input_one = sys.stdin.read(1)
if input_one == 'F':
print(signature, end='')
if input_one == 'C':
print(signature, end='')
if input_one == 'O':
current_rpm = get_simulated_rpm()
data_block = struct.pack('<I', current_rpm)
sys.stdout.buffer.write(data_block)
以上。