2020年10月3日土曜日

CENTER 304のシリアルプロトコル

デジタル温度計のシリアルケーブル電源ケーブルを作成したので納品前に動作確認をしてみた。電源ケーブルの方はACアダプタじゃなくてUSB給電ケーブルにしたのにシリアルのGNDとレベルが違うということで急遽絶縁DC-DCコンバータを挟んで対策した。前にオーディオ用で購入していたAliexpressで100円ぐらいだったやつの余りが合ったので助かったー。

借りてきたのはCENTER 304ってやつだったんだけど、TC0304ってやつの説明書を見るとシリアルのプロトコルも載っていたのでついでにPythonで動作確認してみた。
Baudrateは9600でアスキーで"A"を改行コードなしで送ってやるとデータが返ってくる模様。
改行コードがあると何も帰って来なかった。
他にTC0301(CENTER 301)のコマンドも認識してくれるっぽい。シリアル通信経由でボタンが押せる。さらには"E"を送るとRECランプが付くのでこれはおそらくCENTER 309とかのロギング対応モデル用コマンドかも。"P"でログを読み出せそうだけど、空っぽのデータが返ってくる。
import serial
import struct

serial = serial.Serial('COM4', 9600)  # デバイス名とボーレートを設定しポートをオープン

while 1:
    serial.write("A".encode("utf-8"))
    data = bytearray()
    tmp = serial.read(1)
    if tmp == b'\x02':
        data = serial.read(44)
    temp = []
    for num in range(16):
        #print(struct.unpack('>H', data[6:8])[0]/10)
        temp.append(struct.unpack('>H', data[6+(num*2):8+(num*2)])[0]/10)
    print("Current:",end='\t')
    print(temp[0:4])
    print("Delta Set:",end='\t')
    print(temp[4:8])
    print("Min Temp:",end='\t')
    print(temp[8:12])
    print("Max Temp:",end='\t')
    print(temp[12:16])
serial.close()
とりあえず簡単にPythonで温度を読み出すプログラムを作ってみた。

MAXとMINはMAX MINボタンを押してMAX MINモードにしてる間しか変動しなさそう。DeltaはRELキーを押した瞬間の温度を記録してるっぽい。1秒間に2,3回読み出せるけど温度変化は緩やかなので内部のサンプリングに依存してそう。

ついでにArduino環境のESP32でも試してみた。
リクエストめっちゃ送ると温度計側がフリーズしてしまうのでやり過ぎ注意。300msとかでも反応してくるんだけど結局サンプリング周期が3秒に1回ぐらいっぽいので同じデータが淡々と送られてくる。
#define UART1_RX 25
#define UART1_TX 21

uint16_t temp[16];

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1, UART1_RX, UART1_TX);
}

void loop() {
  static unsigned long updPrev;
  if (millis() > 1000 + updPrev )
  {
    updPrev = millis();
    Serial1.print("A");
    if (Serial1.available() > 0 ) {
      uint8_t header = Serial1.read();
      if (header == 0x02) {
        uint8_t rcvData[44];
        uint8_t bytesRead = Serial1.readBytes(rcvData, 44);
        if (bytesRead == 44 && rcvData[43] == 0x03) {
          for (uint8_t i = 0 ; i < 16; i++) {
            temp[i] = rcvData[6 + (i * 2)] << 8 | rcvData[7 + (i * 2)];
          }
          Serial.println(temp[0]);
        }
      }
    }
  }
}
シリアルコンソールに流してるだけだけどESP32ならWiFi経由でインターネットに飛ばしたり色々できそう。
CENTER304 ESP32
ESP32は3.3VなのでI2C用の双方向レベルコンバータを挟んでいる。温度計側は5Vだし。
双方向である必要はないんだけど、このFETを使ったレベル変換って便利だよなぁ。

とりあえずお遊びはこのぐらいにして納品しに行こ…


0 件のコメント:

コメントを投稿