Skip to content

Instantly share code, notes, and snippets.

@sejr
Created December 22, 2016 16:45
Show Gist options
  • Select an option

  • Save sejr/fcc9e6388c2fa28105595a1e2cdea985 to your computer and use it in GitHub Desktop.

Select an option

Save sejr/fcc9e6388c2fa28105595a1e2cdea985 to your computer and use it in GitHub Desktop.
/*
* JTS_MICROMETER
* Last revised 21 December 2016
*
* This sketch reads the input from the Mitutoyo digital
* micrometer and formats it appropriately for later use.
*
* The output of this sketch is an array of integers with
* the name "reading" - it contains 13 hexadecimal numbers
* which represent the 52-bit output of the micrometer.
* The format of this output is elaborated upon below.
*
* +---+
* +---------+++++---------+
* | 1 3 5 7 9 |
* | 2 4 6 8 10 |
* +-----------------------+
* MICROMETER PINOUT
*/
#define FALSE 0
#define TRUE 1
#define REQ 2 // Request signal from micrometer (Pin 5)
#define CLK 3 // Clock signal from micrometer (Pin 3)
#define DAT 4 // Data signal from micrometer (Pin 2)
#define BTN 5 // Button to request measurement
// TODO: ^ Modify defines so they match the micrometer docs?
int i = 0; // Index counter
int j = 0; // Internal counter
int k = 0; // Placeholder for micrometer datum
int READ_METER; // Flag; meter can be read.
int buttonPressed = 1; // Orange "DATA" button flag.
int buttonState = HIGH; // For storing button state.
int lastButtonState = HIGH; // For storing prev button state.
byte micrometerOutput[13]; // Storing micrometer data.
float reading; // Numeric micrometer reading.
unsigned long lastDebounceTime = 0;
unsigned long previousMillis = 0;
unsigned long debounceDelay = 100;
char buffer [7];
uint8_t keyboard_buffer[7];
char out_buffer [7];
void setup() {
Serial.begin(9600);
pinMode(REQ, OUTPUT);
pinMode(CLK, INPUT_PULLUP);
pinMode(DAT, INPUT_PULLUP);
pinMode(BTN, INPUT_PULLUP);
digitalWrite(REQ,LOW);
}
void loop() {
/*
* Setup for a single micrometer reading.
*
* NOTE (!): If you attempt to read from the micrometer
* too fast, then you will get an inaccurate
* result.
*/
buttonPressed = digitalRead(BTN);
if ((millis() - lastDebounceTime) > debounceDelay) {
if (buttonPressed != lastButtonState)
{
if (buttonPressed == LOW)
{
digitalWrite(REQ, HIGH);
READ_METER = TRUE;
lastDebounceTime = millis();
}
}
lastButtonState = buttonPressed;
}
if (READ_METER == TRUE)
{
delay(debounceDelay);
previousMillis = millis();
for(i = 0; i < 13; i++ ) {
k = 0;
for (j = 0; j < 4; j++) {
while( digitalRead(CLK) == LOW) {
// WAIT FOR CLOCK TOGGLE
}
while( digitalRead(CLK) == HIGH) {
// WAIT FOR CLOCK TOGGLE
}
// Write data bits, reverse order.
bitWrite(k, j, (digitalRead(DAT) & 0x1));
}
// Fetch micrometer data.
micrometerOutput[i] = k;
}
/*
* OUTPUT FORMAT
*
* The remainder of this sketch takes the micrometerOutput array and
* parses it to get a human-readable output. The micrometer output
* is organized into thirteen bytes; they are described below.
*
* [d01] Always F
* [d02] Always F
* [d03] Always F
* [d04] Always F
* [d05] 0 (POS) or 8 (NEG)
* [d06] Measurement (MSD)
* [d07] Measurement
* [d08] Measurement
* [d09] Measurement
* [d10] Measurement
* [d11] Measurement (LSD)
* [d12] # Digits AFTER Decimal Point
* [d13] 0 (MM) or 1 (IN)
*
* To get the human readable output, we store the measurements into
* a separate buffer, then convert that with atol and apply the decimal
* point where appropriate.
*/
for(int i = 0; i < 6; i++)
{
// Fet
buffer[i] = micrometerOutput[i + 5] + '0';
}
buffer[6] = 0;
reading = atol(buffer); // Measurement without decimal place.
/*
* DECIMAL POSITION
* micrometerOutput[11]
*
* Value: 5 4 3 2 1
* Output: 0 . 0 . 0 . 0 . 0 . 0
*/
unsigned long divisor;
switch(micrometerOutput[11])
{
case 1:
divisor = 10;
break;
case 2:
divisor = 100;
break;
case 3:
divisor = 1000;
break;
case 4:
divisor = 10000;
break;
case 5:
divisor = 100000;
break;
default:
divisor = 1;
break;
}
// FOR DEBUGGING:
// Serial.println(micrometerOutput[11], BIN);
float result = reading / divisor;
sprintf(out_buffer, "%f", result);
if (
// If measuring in in, don't go outside 1-2in range (approx)
(micrometerOutput[12] && (result > 0.9 && result < 2.1)) ||
// If measuring in mm, don't go outside 23-53mm range (approx)
(!micrometerOutput[12] && (result > 22.86 && result < 53.34))
)
{
Serial.print(result, 5);
/*
* UNIT
* micrometerOutput[12]
*
* Value: 0 / 1
* Output: millimeters / inches
*/
// FOR DEBUGGING:
// Serial.println(micrometerOutput[12], BIN);
//Serial.write((const uint8_t *)out_buffer, 7);
//releaseKey();
if (micrometerOutput[12])
{
Serial.println("in");
} else
{
Serial.println("mm");
}
} // end if result IN RANGE
} // end if READ_METER == true
READ_METER = FALSE; // Reset for next reading.
} // end LOOP
void releaseKey()
{
Serial.write((const uint8_t *)out_buffer, 7);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment