工場改善 IoT Arduino開発

現場の悩みに解決手段を

【Seeeduino XIAO】RS232cから受信した信号をUSBHIDで送信してみる。2

先日RS232cをHID出力に入力する機器を作ったんですが、1件づつ間隔を開けて送信する場合はいい感じでした。

しかし...

連続で40~60件分をまとめて送信すると、PCで開いたメモ帳やExcelに入力して描画する
スピードが合わないからか文字が70行目くらいでぐちゃぐちゃになりました。orz
バッファ溢れかな??


今回は最大100件だったので、
試しに最大60文字を100件送るプログラムを作って調査してみたんですが、
送信間隔350ms以上で正常に入力されるようになりました。
Excelだと500ms以上であれば描画が追いついてないですが最後まで正常に入力されてました。
描画がボトルネックなのかな??

そこで前回のHID仕様を改良してみました。
変更点はマイコンにバッファをもたせて、送信間隔を900ms程度に遅延させてみました。
色々調整しながら試してみましたが以下でうまくいきました。


100件分のRS232c信号をUSB HIDでPCに送れるようにしています。

/*
Seeedino XINO
UART(HardwareSerial)
UART1(RX:GPIO7 TX:GPIO6)※受信(RX)のみ使用
ボーレート:9600
ビット長:8ビット、パリティ:なし、ストップビット:なし(SERIAL_8N1)
接続
送信側→本機
3.3V-3.3V
GND -GND
TX -GPIO7(RX)

/

#include <Keyboard.h>

#define BPS0 9600                 // bps UART0(USB)
#define BPS1 9600                 // bps UART1
#define BAFFSIZE 300              // 連続で受信する場合の文字列のバッファ数
#define DATASIZE 70               // 一度に送る文字列のバイト数

char baffArr[BAFFSIZE][DATASIZE]; // バッファ
int ReadX = 0;
int ReadY = 0;
int WriteX = 0;
int WriteY = 0;

#define INTERVAL 900   // 最小送信間隔ms(アプリの入力速度に合わせて変更する)
int count = 0;
String strDATA = "";   // 送信する文字列

/***************************************************************
   初期化
 **************************************************************/
void setup() {
  strDATA.reserve(DATASIZE); // strDATAの文字列の格納領域をbyte数確保
  Keyboard.begin();          // USB HID接続開始
  Serial.begin(BPS0);        // UART0
  Serial1.begin(BPS1);       // UART1
  delay(1000);
  //Keyboard.println("USB HID Start!!");
}

/***************************************************************
  1バイトづつSerialで読み込み、baffArrに一旦格納する。strDATAに結合してUSB HIDで送信
   *************************************************************/
void loop() {
  //読み込み
  while (Serial1.available() > 0) {     // 受信したデータバッファが1バイト以上存在する場合
    char inChar = (char)Serial1.read(); // Serial1からデータ読み込み
    if (inChar == '\n') {               // 改行コード(LF)がある場合の処理
      baffArr[ReadX][ReadY] = '\0';
      ReadX += 1;
      ReadX = ReadX % BAFFSIZE;
      ReadY = 0;
    } else if (inChar != '\r') {        // CRの改行コードの場合は結合しない
      baffArr[ReadX][ReadY] = inChar;   // 読み込んだデータを結合
      ReadY += 1;
    }
  }

  //書き出し
  if (INTERVAL <= count) {
    if (ReadX != WriteX) {             //データが保存されている場合に実行
      for (WriteY = 0; WriteY < DATASIZE; WriteY++) {
        if (baffArr[WriteX][WriteY] != '\0') {
          strDATA += baffArr[WriteX][WriteY];
          baffArr[WriteX][WriteY] = '\0';
        } else {
          break;
        }
      }
      if (strDATA.length() > 1) {
        Keyboard.println(strDATA);     // データ送信
      }
      strDATA = "";                    // データ初期化
      WriteX += 1;
      WriteX = WriteX % BAFFSIZE;
    }
  }
  
  count = count % INTERVAL;
  count += 1;
  delay(1);
}