1 | /*
|
2 | Reading data from digital calipers with 6 digit BCD protocol
|
3 |
|
4 | Data format as it appears on the serial line.
|
5 | The first nibble holds 1/100mmm, the next 1/10mm, then 1mm and so on.
|
6 | If the unit is inches, it starts with 1/1000 inch.
|
7 | Nibble_1 Nibble_2 Nibble_3 Nibble_4 Nibble_5 Nibble_6 Nibble_7
|
8 | -------- -------- -------- -------- -------- -------- --------
|
9 | xxxx.xN xxxx.Nx xxxN.xx xxxNx.xx xNxx.xx Nxxx.xx bitvalues # mm
|
10 | xxx.xxN xxx.xNx xxx.Nxx xxxN.xxx xNx.xxx Nxx.xxx bitvalues # inches
|
11 |
|
12 | Nibble 1-6 : BCD (binary coded decimal)
|
13 | Timing:
|
14 | 1 bit ca. 12 µsec
|
15 | 1 nibble with sync ca. 100 µsec
|
16 | example 1, first nibble : 1010 = 5
|
17 | _____ _ _ _ ______
|
18 | ____| |_| |_| |_| |_| clock (falling edge = data valid , rising edge = data change)
|
19 |
|
20 | 1 2 4 8 bit value
|
21 | _______ ___
|
22 | ____| |___| |___N data; N = set to value of first bit in NEXT nibble
|
23 |
|
24 | example 2, first nibble : 0010 = 4
|
25 | _____ _ _ _ ______
|
26 | ____| |_| |_| |_| |_| clock (falling edge = data valid , rising edge = data change)
|
27 |
|
28 | 1 2 4 8 bit value
|
29 | ___
|
30 | ________________| |___N data; N = set to value of first bit in NEXT nibble
|
31 |
|
32 | Nibble 7 : Bit 0: sign; 0=plus,1=minus
|
33 | Bit 1: 5/10000-inch (if unit is inch), 0=off, 1=on
|
34 | Bit 2: unit, 0=inch, 1=mm
|
35 | Bit 3: (?, always 1)
|
36 |
|
37 | whole packet ca. 750 µsec, pause between packets ca. 300 ms
|
38 |
|
39 | references:
|
40 | http://www.mikrocontroller.net/articles/Me%C3%9Fschieber_auslesen
|
41 | http://www.mikrocontroller.net/topic/30219
|
42 | http://www.roboternetz.de/community/threads/45869-digitale-schieblehre-auslesen
|
43 | http://www.pcbheaven.com/exppages/Digital_Caliper_Protocol/
|
44 | http://code.google.com/p/digitalwritefast/
|
45 |
|
46 | BL, 2015-aug-14
|
47 | */
|
48 |
|
49 |
|
50 | #include <LiquidCrystal.h>
|
51 | // ------------- LCD pin declarations
|
52 | // initialize the library with the interface pin numbers
|
53 | // RS EN D4 D5 D6 D7
|
54 | LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
|
55 |
|
56 | // library from http://code.google.com/p/digitalwritefast/
|
57 | #include <digitalWriteFast.h>
|
58 |
|
59 | #define BITS 28 // data bits in one burst
|
60 | #define STARTUP BITS+2 // value which is not reached during sync'ed transfer. used to identify startup
|
61 | #define DATAIN 3 // data in pin number
|
62 |
|
63 | // ------------- global variables
|
64 | int clockIn = 2; // clockIn pin number
|
65 | volatile int bitVal[30]; // bit read buffer
|
66 | volatile int bitCount = STARTUP;
|
67 | unsigned int timer; // used to detect pause between data bursts
|
68 |
|
69 | // ------------- setup
|
70 | void setup() {
|
71 | pinMode (DATAIN, INPUT);
|
72 | pinMode(clockIn, INPUT);
|
73 | attachInterrupt (0, getBit, FALLING);
|
74 | // Serial.begin(115200);
|
75 | }
|
76 |
|
77 | // ------------- interupt service routine
|
78 | void getBit(){
|
79 | if ( bitCount <= BITS ){
|
80 | /*
|
81 | * read data bit
|
82 | * needs 'fast' variant, 'digitalRead' too slow
|
83 | */
|
84 | bitVal[bitCount] = digitalReadFast2(DATAIN);
|
85 | bitCount++;
|
86 | }
|
87 | }
|
88 |
|
89 | // ------------- loop
|
90 | void loop(){
|
91 | int bc; // bit counter
|
92 | int sc; // shift counter
|
93 | int dc; // digit counter
|
94 | int nibble; // 4 bit buffer
|
95 | int bcdDigit[7]; // BCD + bitmask in [6]
|
96 | // display data
|
97 | char sign;
|
98 | int ftt; // 5/10000 inch
|
99 | char* units; // mm or inch
|
100 | char* displayText = "1234567890123456"; // display buffer
|
101 |
|
102 | // ------------- sync with pause between data bursts
|
103 |
|
104 | if ( bitCount > BITS ){
|
105 | if ( bitCount < STARTUP){ // startup done, now synced
|
106 | // process data bits
|
107 | // Serial.println(bitCount);
|
108 |
|
109 | // bit decoding to BCD
|
110 | sc = 0;
|
111 | dc = 0;
|
112 | nibble=0;
|
113 | for ( bc = 0; bc < BITS; bc++ ){
|
114 | nibble |= bitVal[bc] << sc;
|
115 | // Serial.print(bitVal[bc]);
|
116 | if ( bc %4 == 3 ){
|
117 | // Serial.print("(");
|
118 | // Serial.print(nibble,HEX);
|
119 | // Serial.print(") ");
|
120 |
|
121 | bcdDigit[dc] = nibble;
|
122 | nibble = 0;
|
123 | sc = 0;
|
124 | dc++;
|
125 | }else{
|
126 | sc++;
|
127 | }
|
128 | }
|
129 |
|
130 | // ------------- format output
|
131 | // check sign bit
|
132 | if ( bcdDigit[6] & 0x1 ){
|
133 | sign = '-';
|
134 | }else{
|
135 | sign = '+';
|
136 | }
|
137 | // check 5/10000 bit
|
138 | if ( bcdDigit[6] & 0x2 ){
|
139 | ftt = 5;
|
140 | }else{
|
141 | ftt = 0;
|
142 | }
|
143 | // check units bit
|
144 | if ( bcdDigit[6] & 0x4 ){
|
145 | units = "mm";
|
146 | sprintf(displayText, "%c%d%d%d.%d%d %s",
|
147 | sign,
|
148 | bcdDigit[4], bcdDigit[3], bcdDigit[2], bcdDigit[1], bcdDigit[0],
|
149 | units);
|
150 | // Serial.println(" ");
|
151 | // Serial.print(displayText);
|
152 | // Serial.println(" ");
|
153 | }else{
|
154 | units = "inch";
|
155 | sprintf(displayText, "%c %d%d.%d%d%d%d %s",
|
156 | sign,
|
157 | bcdDigit[4], bcdDigit[3], bcdDigit[2], bcdDigit[1], bcdDigit[0],ftt,
|
158 | units);
|
159 | // Serial.println(" ");
|
160 | // Serial.print(displayText);
|
161 | // Serial.println(" ");
|
162 | }
|
163 | }
|
164 |
|
165 | // display caliper value on LCD
|
166 | lcd.clear();
|
167 | // col,row
|
168 | lcd.setCursor(0,0);
|
169 | lcd.print(displayText);
|
170 |
|
171 | // display done, now sync with next data burst
|
172 |
|
173 | // Serial.println("syncing");
|
174 | // wait for clock becoming low
|
175 | while ( digitalRead(clockIn) == 1 ){}
|
176 | // record time of falling edge
|
177 | timer = millis();
|
178 | // wait for clock becoming high
|
179 | while ( digitalRead(clockIn) == 0 ){}
|
180 | // verify time of rising edge
|
181 | if ( millis() - timer > 200 ){
|
182 | // enable bit capture in ISR getBit
|
183 | bitCount = 0;
|
184 | }
|
185 | }
|
186 | delay(20);
|
187 | }
|
188 |
|
189 | /*
|
190 | serial debug output:
|
191 | syncing
|
192 | 0100(2) 1001(9) 1010(5) 1110(7) 0000(0) 0000(0) 0011(C)
|
193 | +075.92 mm
|
194 | syncing
|
195 | 0100(2) 1001(9) 1010(5) 1110(7) 0000(0) 0000(0) 0011(C)
|
196 | +075.92 mm
|
197 | */
|