デジタルノギスの計測値をArduino Pro micro を使ってPCに送る方法

#Tips for transmitting data measured by cheap digital caliper to PC with using Arduino Pro Micro HID function.


最近安く買えるようになったデジタルノギスを改造して、ノギスで計測した値をパソコンに送るツールを作りました。
ほとんど参考元としている情報のコピーに近いですが、ノギスから読みとった値をパソコンへキーボード入力として渡している点はオリジナル（？）です。

This page written for  tips for  tool that transmitting measurement data of digital caliper to PC through modifying cheap digital caliper.
Almost written informations are just like copy from reference, but combination transmitting information through HID of Arduino is original (maybe). 

##完成品　　　over view

![スクリーンショット 2022-01-23 0.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515222/6bf3b79a-ea5d-94b5-8d62-9522bb1346a1.png)


テキスト送信先としてFusion360などのCADソフトにしておくことで、キーボードによる数値入力の手間を省くことができます。
下記の実際の動作動画もご確認ください。

It can avoid key input operation by keyboard ,if you set software like a fusion 360 as text input receiver.
Please see demo movie as below.

https://youtu.be/salRcvhnMjc




##構成図 　　configuration


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515222/41e9b6c1-3e09-9cae-63d3-04c689b3faca.png)


##回路図 　　　circuit schematic

デジタルノギスは約1.5V、Arduinoは3.3V(?)と電圧が異なるため、トランジスタを使い電圧違いを吸収してあげる必要があります。
回路図としては出てきませんが、コード上でArduinoのPULLUP抵抗を有効（INPUT_PULLUP)としていますので、トランジスタがOFFの時（ベース電圧が０の時）はArduinoの入力としてはHIとなります。


Digital caliper has communication interface voltage with 1.5V and Arduino has 3.3V(maybe), so it is needed transistor as voltage converter.
Arduino input will HI (means transistor goes off) when BASE of Transistor voltage is ZERO by  Pull-up resistor in Arduino is enabled by code "INPUT_PULLUP".



![スクリーンショット 2022-01-25 0.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515222/067a5000-9bc3-2aed-08b9-c64f6e0214e0.png)





##Arduino のスケッチ 　　　Sketch for Arduino


```c++
#include "Keyboard.h"
#include <Arduino.h>

int clockPin = 4;  // クロック入力ピン番号（Trで反転）　clock input from caliper (reversed by Tr.)
int dataPin = 5;   // データ入力ピン番号（Trで反転）　Data input from caliper (reversed by Tr.)
int switchpin = 2; // テキスト送信用スイッチ入力　Switch input for torigger to transmission to PC
int data;
float key_data = 0;
bool pushed = false;

int ReadCaliper()
{ // ノギスからデータ読んで値返す関数  Function for reading measurement data of digital caliper
  boolean dataStarted = false;
  unsigned long t0, bitOpr, oprResult;
  int n, outData;

  bitOpr = 0x00000001; // ビット操作オペレータ  Bit operator
  oprResult = 0x00000000;

  //   データ転送開始まで待つ
  while (dataStarted == false)
  {
    t0 = micros(); // タイミングを記録  Memory current time
    while (digitalRead(clockPin) == LOW)
    { // クロックピンがLOWの期間を検出 Detect period of low signal of clock
    }
    if (micros() >= t0 + 1000)
    {                     // LOWが1mS以上続いていたらデータ開始とみなす Its assumed data starting if LOW continue more than 1ms
      dataStarted = true; // 但し、micros は70分でゼロに戻るのでその時は取りこぼす、ゴメン!
    }
  } // クロックがHIGHになりデータ転送が始まる

  //   データのビット列を読み込み  Reading data bit stream

  for (n = 1; n <= 24; n++)
  { // 24ビット読み出しループ
    while (digitalRead(clockPin) == HIGH)
    { // クロックピンがLOWになるまで待つ waiting for low of clock
    }
    if (digitalRead(dataPin) == LOW)
    {
      oprResult = oprResult | bitOpr; // 1(負論理なのでLOW)だったらビットを立てる
    }
    if (n != 24)
    {                       // 最後のビットでなければ
      bitOpr = bitOpr << 1; // ビット操作オペレータを左にシフト
      while (digitalRead(clockPin) == LOW)
      { // クロックがHIGHになるまで待つ
      }
    }
  }

  //  データを取り出しint型に整形  Pick data and change type to "int"
  outData = oprResult; // データを16ビットint変数に代入
  if ((oprResult & 0x00100000) != 0)
  {                           // 負の値のフラグ(21ビット目)が立っていたら
    outData = (~outData) + 1; // 2の補数形式の負の値に変換
  }
  return outData; // 値を返して関数終了
}

void setup()
{
  Keyboard.begin();
  pinMode(17, OUTPUT);

  pinMode(clockPin, INPUT_PULLUP);
  pinMode(dataPin, INPUT_PULLUP);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, HIGH);

  pinMode(switchpin, INPUT_PULLUP);
  Serial.begin(11520);
}

void loop()
{

  data = ReadCaliper();     // ノギスからデータを読む  Reading data from caliper
  Serial.println(key_data); // シリアルに書き出し Output serial communication to debug

// 最初に押された時だけ送信する Transmitting data when switch is  pushed at first time only
  if (digitalRead(switchpin) == LOW && pushed == false)  
  {

    key_data = (float)data / 100;
    Keyboard.print(key_data);
    pushed = true;
    digitalWrite(17, LOW);
    delay(200);
  }
  else if (digitalRead(switchpin) == LOW && pushed == true)
  {
  }
  else if (digitalRead(switchpin) == HIGH)
  {

    pushed = false;

    digitalWrite(17, LOW);
  }
}
```


##参考元　　　Reference 

以下のページを多いに参考にさせてもらいました。
ありがとうございました！

Thanks for reference!


◆デジタルノギスのデーターをArduinoで読んでみた
http://radiopench.blog96.fc2.com/blog-entry-324.html

◆Arduino Leonardo(Pro Micro)のHID（キーボード）機能を使う（ショートカットキー実行，コマンド実行）
https://qiita.com/MergeCells/items/17bdc1c1fb35949195b5