とりあえずLogWorks3で認識してくれるようなレベルなSSI-4互換機的なものを作ってみた。
応用すればPLX SM-AFRのiMFDプロトコルをMTSプロトコルに変換したりとかできるかも?
一応プロトコルの仕様書とかSDKは公開されているのでそいつらを参考にした。
実機はRS-232CでコネクタはMicro-Fit 3.0もしくは2.5mmジャック。
白がRX、赤がTX、黒はGNDで青をGNDに落とすと接続検知になってる。
Baudrate 19200bpsで81.92ms間隔でのデータストリームになっているっぽい。
とりあえずSSI-4として振る舞い、Aux1~4にADCのデータを突っ込むサンプル。
MAX31855を使って熱電対の情報を入れたり、BMP388を使って圧力ログったりできるかも。
volatile unsigned long ofc = 0;
volatile boolean ovf = false;
volatile int res = 0;
volatile unsigned int aux[4]={0,0,0,0};
//Timer2 overflow interrupt vector handler
ISR(TIMER2_OVF_vect) {
ofc++;
//256(8bit)x1024(Prescaler)/16000000(Clock)*5 = 81.92ms
if(!ovf && ofc >= 5){
ofc = 0;
ovf = true;
mts_send();
ovf = false;
}
};
void mts_send(){
switch (res){
case 0:
//Header Word
//1011 0010 1000 0100
//0xB2 0x84
Serial.write(0xB2);
Serial.write(0x84);
//Aux Channels
//0000 D10D9D8D7 0D6D5D4 D3D2D1D0
for (int i = 0; i <= 3; ++i){
byte auxword[2];
auxword[1] = lowByte(aux[i]) & 0x7F;
auxword[0] = ((highByte(aux[i]) & 0x07) << 1) | ((lowByte(aux[i]) & 0x80) >> 7);
Serial.write(auxword,2);
}
break;
case 1://0xCE
//Header Word
//1010 0010 1000 0101
//0xA2 0x85
Serial.write(0xA2);
Serial.write(0x85);
//0xCE
//0000 0001 0100 1110
//0x01 0x4E
Serial.write(0x01);
Serial.write(0x4E);
//Device Name
Serial.write(0x53);//S
Serial.write(0x53);//S
Serial.write(0x49);//I
Serial.write(0x34);//4
Serial.write(0x00);
Serial.write(0x00);
Serial.write(0x00);
Serial.write(0x00);
res = 0;
digitalWrite(LED_BUILTIN, LOW);//debug
break;
case 2://0xF3
//Header Word
//1010 0010 1000 0101
//0xA2 0x85
Serial.write(0xA2);
Serial.write(0x85);
//0xF3
//0000 0001 0111 0011
//0x01 0x73
Serial.write(0x01);
Serial.write(0x73);
//Firmware Version
Serial.write(0x12);
Serial.write(0x3A);
//Identifier
Serial.write(0x53);
Serial.write(0x53);
Serial.write(0x49);
Serial.write(0x34);
//CPU
Serial.write(0x01);
//Channnel/Flags
Serial.write(0x04);
res = 0;
digitalWrite(LED_BUILTIN, LOW);//debug
break;
}
}
void setup() {
//Timer2 Settings: Timer Prescaler /1024, WGM mode 0
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 = 1<<TOIE2;
//reset timer
TCNT2 = 0;
Serial.begin(19200);
pinMode(LED_BUILTIN, OUTPUT);//debug
}
void loop() {
aux[0] = analogRead(A0);
aux[1] = analogRead(A1);
aux[2] = analogRead(A2);
aux[3] = analogRead(A3);
}
void serialEvent() {
while (Serial.available()) {
switch (Serial.read()) {
digitalWrite(LED_BUILTIN, HIGH);//debug
case 0xCE:
res = 1;//obtain device names
break;
case 0xF3:
res = 2;//obtain device types
break;
case 'H':
TCNT2 = 0;
break;
}
}
}
こんなもんでLogWorks3で認識されてる。

今回は81.92ms間隔でデータを送信するのに8bitタイマーを5回オーバーフローさせて使ってるけど(本家は16bitタイマーっぽい表記があるけど)そこらへんの精度の問題とかもよくわからん…
あとADのデータを割り込み内で取り込むべきかどうかとかとかも悩む。
こいつを応用すればArduino 1台で複数のMTS対応デバイスをエミュレートできるかも。
Arduino一つでSSI-4を2台分とか。
0 件のコメント:
コメントを投稿