-
1Step 1
Level translators and Caliper Connector
The output from the caliper is digital but only swings from 0 to 1.5 Volts. We need to bump that up in order to interface with the Trinket Pro. The circuit uses open-drain config which will allow interface to a 3V or 5V Trinket.
I wanted to be able to not have to modify the caliper in any way, so, I chose to use a spring-loaded connector.
I also did not want to have to make (or had time to) a PCB. I was able to 're-purpose' an Adafruit SMT breakout board for mounting the FETs and the connector.
(all the parts are available at Digikey)
-
2Step 2
Putting It All Together
All the fit snugly in place. There is no real need to glue or fixture the board or the switches( Panasonic EVO-PRG07K).
Please note the diode from D5 to the USB pull-up. This is a 1N4148 but any switch/rect diode should work.
The enclosure is a Listerine breath strips case. All the 'machining' on the enclosure was done with a craft knife.
-
3Step 3
V-USB Library and Config changes to usbconfig.h
Download the library from here....
https://code.google.com/p/vusb-for-arduino/
and import library into Arduino IDE.
A few changes were required to the usbconfig.h file.
/* Name: usbconfig.h //#define USB_CFG_DMINUS_BIT 4 #define USB_CFG_DMINUS_BIT 7 #define F_CPU 16000000L #define USB_CFG_CLOCK_KHZ (F_CPU/1000) /* ----------------------- Optional Hardware Config ------------------------ */ #define USB_CFG_PULLUP_IOPORTNAME D /* If you connect the 1.5k pullup resistor from D- to a port pin instead of * V+, you can connect and disconnect the device from firmware by calling * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). * This constant defines the port on which the pullup resistor is connected. */ #define USB_CFG_PULLUP_BIT 5 /* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined * above) where the 1.5k pullup resistor is connected. See description * above for details. */ //#define USB_CFG_INTERFACE_PROTOCOL 0 #define USB_CFG_INTERFACE_PROTOCOL 1 // keyboard
-
4Step 4
Bare Bones Code
Read caliper data and can output to USB.
Missing switch debouncing, units, output formatting, and bug clean-up.
-
5Step 5
//--------------------------------------------------------------------- // USB Caliper HID // // version 0.1 - incomplete, only caliper read and output to USB // structure in place. Enough to read from Caliper // and output it. //--------------------------------------------------------------------- #include "UsbKeyboard.h" #define KEY_COMMA 54 #define KEY_SLASH 56 #define LED 13 #define F1_BUTTON_PIN 10 #define F2_BUTTON_PIN 11 #define F3_BUTTON_PIN 12 #define Caliper_nCLK A5 #define Caliper_nDATA A4 #define USB_PU_PIN 5 // If the timer isr is corrected // to not take so long change this to 0. #define BYPASS_TIMER_ISR 1 enum state {WAIT_IDLE, WAIT_CLK_LOW, WAIT_CLK_HIGH}; state Caliper_Read_State = WAIT_IDLE; boolean Caliper_Connected=0; // set to true whenever(the 1st) full 24 bit frame is received // TODO ====> (add pull-downs to gates of lvl conv FETs) boolean Calliper_Reading_Valid = 0 ; // indicates that Caliper_Reading contains a valid reading int Caliper_nDATA_bit; // data bit on the rising edge of Caliper_nCLK int Caliper_Reading; // raw caliper reading int Caliper_ReadingTMP; // raw caliper reading volatile String Caliper_ReadingSTR; // converted caliper int to string for output byte Caliper_bit= 0; // indicates that last bit read from the caliper's 24 bit frame // -1 = no valid idle detected ( high CLK line for longer than 40 ms) // 0 = valid idle detected // 1..24 = int num_of_loops_idle=0; // num of loops with clk line idle #define LOOPS_FOR_IDLE 800 // 20ms div 25 microsecs void setup() { pinMode(F1_BUTTON_PIN, INPUT); // F1 button with pull-up digitalWrite(F1_BUTTON_PIN, HIGH); pinMode(F2_BUTTON_PIN, INPUT); // F2 button with pull-up digitalWrite(F2_BUTTON_PIN, HIGH); pinMode(F3_BUTTON_PIN, INPUT); // F3 button with pull-up digitalWrite(F3_BUTTON_PIN, HIGH); pinMode(Caliper_nCLK, INPUT); // Caliper CLK (inverted) with pull-up digitalWrite(Caliper_nCLK, HIGH); pinMode(Caliper_nDATA, INPUT); // Caliper DATA (inverted) with pull-up digitalWrite(Caliper_nDATA, HIGH); pinMode(LED, OUTPUT); #if BYPASS_TIMER_ISR // disable timer 0 overflow interrupt (used for millis) TIMSK0&=!(1<<TOIE0); // ++ #endif // BRUTE force USB re-enumeration -- will need clean-up cli(); usbDeviceDisconnect(); pinMode(USB_PU_PIN, OUTPUT); digitalWrite(USB_PU_PIN, LOW); delayMs(250); digitalWrite(USB_PU_PIN, HIGH); pinMode(USB_PU_PIN, INPUT); usbDeviceConnect(); sei(); } #if BYPASS_TIMER_ISR void delayMs(unsigned int ms) { for (int i = 0; i < ms; i++) { delayMicroseconds(1000); } } #endif void loop() { UsbKeyboard.update(); //----------------------------------------------------------------- // Read Caliper //----------------------------------------------------------------- switch ( Caliper_Read_State ) { case WAIT_IDLE : { if ( !digitalRead( Caliper_nCLK) == 1 ) num_of_loops_idle++; else { num_of_loops_idle=0; //Caliper_ReadingTMP=0; }; if ( num_of_loops_idle == LOOPS_FOR_IDLE ) Caliper_bit=0; Caliper_ReadingTMP=0; Caliper_Read_State = WAIT_CLK_LOW; digitalWrite(LED, !digitalRead( LED )); break; }; case WAIT_CLK_LOW : { if ( !digitalRead( Caliper_nCLK) == 0 ) Caliper_Read_State = WAIT_CLK_HIGH; else { // check for timeout and return to wait for idle }; break; }; case WAIT_CLK_HIGH : ; { if ( !digitalRead( Caliper_nCLK) == 1 ) { Caliper_nDATA_bit = !digitalRead( Caliper_nDATA); Caliper_bit++; if ( Caliper_bit <= 24 ) { Caliper_Read_State = WAIT_CLK_LOW; if ( (Caliper_bit > 1) and (Caliper_bit < 17 )) // read value bits only, toss 0.5(bit 1) if (Caliper_nDATA_bit>0) Caliper_ReadingTMP += int( 1 << (Caliper_bit-2)); //Caliper_ReadingTMP=1234; } // else { // Caliper_Read_State = WAIT_CLK_HIGH; // } if ( Caliper_bit == 24 ) { Caliper_Read_State =WAIT_IDLE; num_of_loops_idle=0; Caliper_Reading=Caliper_ReadingTMP; // update caliper reading Caliper_ReadingTMP=0; Caliper_Connected = 1; // future feature to allow buttons to perform alt function if caliper not connected } } else { // do timeout }; break; }; } // switch end //digitalWrite(LED, !digitalRead( LED )); // 'main loop' occurs every 25 microseconds -- without button presses/USB keypress sends which can be 60 - 100ms //----------------------------------------------------------------- // Check for button presses and send out sequences via USB //----------------------------------------------------------------- if (digitalRead(F1_BUTTON_PIN) == 0) { //Send F1 Code //Caliper_Reading=12345; SendCaliperValue(); UsbKeyboard.sendKeyStroke(KEY_ENTER); #if BYPASS_TIMER_ISR // check if timer isr fixed. delayMs(20); #else delay(20); #endif } if (digitalRead(F2_BUTTON_PIN) == 0) { //Send F2 Code //Caliper_Reading=6578; SendCaliperValue(); UsbKeyboard.sendKeyStroke(KEY_COMMA); #if BYPASS_TIMER_ISR // check if timer isr fixed. delayMs(20); #else delay(20); #endif } if (digitalRead(F3_BUTTON_PIN) == 0) { //Send F3 Code //Caliper_Reading=9010; SendCaliperValue(); UsbKeyboard.sendKeyStroke(KEY_SLASH); UsbKeyboard.sendKeyStroke(KEY_2); UsbKeyboard.sendKeyStroke(KEY_ENTER); #if BYPASS_TIMER_ISR // check if timer isr fixed. delayMs(20); #else delay(20); #endif } } //----------------------------------------------------------------- // SEND CALIPER VALUE via USB HID keystrokes //----------------------------------------------------------------- void SendCaliperValue() { // convert raw integer caliper to string Caliper_ReadingSTR=String(Caliper_Reading,DEC); // toss any whitespace Caliper_ReadingSTR.trim(); // the ASCII and the USB number sequences don't quite match up // so this silly business to send out the digits for (byte i=1; i <= Caliper_ReadingSTR.length(); i++) { if ( Caliper_ReadingSTR.charAt(i-1) == '0') UsbKeyboard.sendKeyStroke(KEY_0); else UsbKeyboard.sendKeyStroke( byte(Caliper_ReadingSTR.charAt(i-1)) - byte('0')-1 + KEY_1); } }
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.