とりあえず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 件のコメント:
コメントを投稿