注意 :未验证
参考链接
https://qiita.com/84mota/items/c94e2387d1fc35b22e73
http://radiopench.blog96.fc2.com/blog-entry-324.html
https://blog-imgs-45-origin.fc2.com/r/a/d/radiopench/20120708SlideCaliper.txt
在网上看到有趣的硬件破解记录下来
电路因为游标卡尺的工作电压在1.5V需要做电平转换
顶部是时钟,底部是数据,这样的波形出现在大约 230 mS 的周期内。数据间隔约150μS,。 根据前人分析的数据,数据格式如下:・ 从头开始的20位是数据,第一边是LSB ,第21位是代码,1表示负值。
不确定第 22 位到第 24 位 (在有的地方文章看到说是单位 那天买个便宜的游标卡尺读一下看看)
程序
#include <LiquidCrystal.h>
/*
デジタルノギスのデータ読み込み(関数のデモ)
Pin 6: Clock (Trで反転)
Pin 7; Data(Trで反転)
2012/07/08 by Radiopench
http://radiopench.blog96.fc2.com/
*/
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // LCD シールドのピンアサイン
int clockPin = 6; // クロック入力ピン番号(Trで反転)
int dataPin = 7; // データ入力ピン番号(Trで反転)
int data;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2); //LCDのサイズ設定
pinMode(clockPin, INPUT);
pinMode(dataPin, INPUT);
digitalWrite(clockPin, HIGH);
digitalWrite( dataPin, HIGH);
pinMode(13, OUTPUT);
}
void loop() {
data = ReadCaliper(); // ノギスからデータを読む
lcddisp(data); // 液晶に書いて
Serial.println(data); // シリアルに書き出し
}
int ReadCaliper() { // ノギスからデータ読んで値をinで返す関数
boolean dataStarted = false;
unsigned long t0, bitOpr, oprResult;
int n, outData;
bitOpr = 0x00000001; // ビット操作オペレータ
oprResult = 0x00000000;
// データ転送開始まで待つ
while(dataStarted == false) {
t0 = micros(); // タイミングを記録
while(digitalRead(clockPin) == LOW){ // クロックピンがLOWの期間を検出
}
if(micros() >= t0 + 1000) { // LOWが1mS以上続いていたらデータ開始とみなす
dataStarted = true; // 但し、micros は70分でゼロに戻るのでその時は取りこぼす、ゴメン!
}
} // クロックがHIGHになりデータ転送が始まる
// データのビット列を読み込み
digitalWrite(13, HIGH);
for(n = 1; n <= 24; n++){ // 24ビット読み出しループ
while(digitalRead(clockPin) == HIGH){ // クロックピンがLOWになるまで待つ
}
if(digitalRead(dataPin) == LOW){
oprResult = oprResult | bitOpr; // 1(負論理なのでLOW)だったらビットを立てる
}
if( n != 24 ){ // 最後のビットでなければ
bitOpr = bitOpr << 1; // ビット操作オペレータを左にシフト
while(digitalRead(clockPin) == LOW){ // クロックがHIGHになるまで待つ
}
}
}
// データを取り出しint型に整形
outData = oprResult; // データを16ビットint変数に代入
if( (oprResult & 0x00100000) != 0 ){ // 負の値のフラグ(21ビット目)が立っていたら
outData = ( ~ outData ) + 1; // 2の補数形式の負の値に変換
}
digitalWrite(13, LOW);
return outData; // 値を返して関数終了
}
void lcddisp(int x) { // デジタルノギス測定結果のLCD表示
int lcdout;
lcd.setCursor(0, 0);
if(x < 0) {
lcd.print("-");
} // マイナス表示
else {
lcd.print(" ");
}
lcdout = abs(x/100);
if(lcdout >= 100) {
lcd.print(lcdout);
}
else if(lcdout >= 10 ) {
lcd.print(" "); // ゼロサプレスひとつ
lcd.print(lcdout);
}
else if(lcdout >= 1 ) {
lcd.print(" "); // ゼロサプレス二つ
lcd.print(lcdout);
}
else {
lcd.print(" 0"); // 最下位がゼロの場合は0を表示
}
lcd.print("."); // 小数点表示
lcdout = abs(x % 100);
if(lcdout >= 10) { // 小数点以下1位がゼロでなければそのまま表示
lcd.print(lcdout);
}
else {
lcd.print("0"); // ゼロだったら0を表示
lcd.print(lcdout);
}
lcd.print("mm");
}
另外一份代码
#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);
}
}
发表回复