Created
December 22, 2016 16:45
-
-
Save sejr/fcc9e6388c2fa28105595a1e2cdea985 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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