2016/04/25 7M4MON
中華製の安デジタルノギスを
AMAZON で買いました。(2016/3/2)
販売元はヴァップスというところで、価格は1342円でした。(4580285660107)
先人たちの解析によると、内部の端子から独自フォーマットでデータが出力されていて
マイコンを使って取り込むことが出来るようです。
買う前にいろいろ調べていると、このページに PIC12C509A を使用した作例があり、
509Aは部品箱に眠っていたので、これで行ってみることにしました。
が、ノギスが届いて調べてみると…
・電池のマイナス側が筐体に接続されていた。(作例では+側)
・内部コネクタ用ランドのピッチが1.6mmくらいだった。(作例では2mm)
(ZHコネクタの足を曲げてハンダ付け、筐体をニッパで少し加工した。)
・データ形式のお休み時間が+側だった(作例では−側)
・24ビットのデータは180ms毎に、1度だけ送られてくる(作例ではABSとRELが続けて送られてくる)
・電池電圧は約1.2Vでも動く(1.4Vを切ると動かなかったらしい)
(NPN Tr/エミッタフォロワで1.5Vを生成し、ノギスに電源を供給できるようにしておいた)
(この場合はノギスの電池を抜くこと!)
・加工屑で激しくジャリジャリ言ってたので分解したついでに清掃した
と、13年(作例は2002年11月)の月日が流れたためにいろいろ変わってしまっているようです。
ということで、そのままでは動きませんでした。
追加で調べてみると、どうやらここのページ(2012年)のデータ形式に似ています。
ハードウェアを作りなおすのは面倒なので、
上記サイトのコードを PIC12F683 + CCS-C に移植しました。
/* | |
中華製 安デジタルノギスのデータを読み取ってUARTで送る。 | |
2016/04/19 7M4MON | |
24bitのデータで始めの20bitがValue。ただしはじめの16ビットしか使わなくていい(LSB first) | |
21ビット目が±、24ビット目がmm/インチ | |
Memory usage: ROM=57% なのでPIC12F629/675では力不足(RAM=21% - 41%) | |
↓をベースに色んなサイトのコードが混じっている | |
http://nut-bolt.nl/2012/reading-digital-calipers-with-an-arduino/ | |
割り込み時間はMSP430の作例でも32msだった。 | |
at caliper out | |
24bit unit : low =mm, high =in | |
clock L->H = latch | |
21bit pol : plus =L, minus =H | |
トランジスタで反転している。 | |
*/ | |
#include <12f683.h> //ヘッダファイルインクルード | |
//コンフィギュレーション設定 | |
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,NOMCLR | |
#use delay(CLOCK = 8000000) //8MHz | |
#use rs232(baud=9600,parity=N,xmit=PIN_A5,rcv=PIN_A1) | |
#define DATA_LENGTH 24 | |
/* | |
0 caliper clk | |
1 uart rx | |
2 caliper data | |
3 config | |
4 config -> LEDになった | |
5 uart tx | |
*/ | |
#define DATA_PIN PIN_A2 | |
#define CLK_PIN PIN_A0 | |
#define LED_PIN PIN_A4 | |
#define TIMER_INTERVAL 0 //適当(32ms) | |
//変数の宣言 | |
int i; | |
short unit; | |
signed long gauge_data; | |
float gauge_float; | |
#INT_RTCC //ハングアップ対策 | |
void rtcc_isr() { //タイマ0割込み処理関数 | |
i = 0; | |
gauge_data = 0; | |
} | |
//main | |
void main() { | |
setup_adc_ports(NO_ANALOGS); | |
i = 0; | |
gauge_data = 0; | |
port_a_pullups(0b00000111); | |
set_tris_a(0b00001111); | |
#use fast_io(a) | |
output_low(LED_PIN); | |
/*タイマ割り込みの許可*/ | |
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); //分周比最大 | |
set_timer0(TIMER_INTERVAL); // 適当 | |
enable_interrupts(INT_RTCC); //タイマ0割込み許可 | |
enable_interrupts(GLOBAL); | |
while(true) //main loop | |
{ | |
gauge_data = 0; | |
for(i=0;i<DATA_LENGTH;i++) | |
{ | |
output_low(LED_PIN); | |
set_timer0(TIMER_INTERVAL); | |
while(!input(CLK_PIN)){} //クロックの立ち上がり待ち | |
//割り込みのリセット | |
set_timer0(TIMER_INTERVAL); | |
while(input(CLK_PIN)){} //クロックの立ち下がり待ち Trで反転しているので、立ち下がり時にラッチ | |
//割り込みのリセット | |
set_timer0(TIMER_INTERVAL); | |
if(i<16){ | |
gauge_data = gauge_data >> 1; //LSB First | |
if(!input(DATA_PIN)){ | |
gauge_data |= 0x8000; | |
} | |
output_high(LED_PIN); | |
}else if(i==20){ //21bitは± | |
if(!input(DATA_PIN)){ | |
gauge_data = (~gauge_data) + 1; //反転する | |
} | |
output_low(LED_PIN); | |
}else if(i==23){ //24ビット目は単位 | |
unit = input(DATA_PIN); // true=mm, false = inch | |
output_high(LED_PIN); | |
} | |
} | |
//割り込みを一旦停止 | |
disable_interrupts(INT_RTCC); | |
disable_interrupts(GLOBAL); | |
if(unit){ | |
gauge_float = (float)gauge_data / 100; //mm | |
printf("%6.2f mm\r\n", gauge_float); | |
}else{ | |
gauge_float = (float)gauge_data / 2000; //inch | |
printf("%6.3f in\r\n", gauge_float); | |
} | |
output_low(LED_PIN); | |
//割り込みを再開 | |
set_timer0(TIMER_INTERVAL); // 適当 | |
enable_interrupts(INT_RTCC); | |
enable_interrupts(GLOBAL); | |
} | |
} |