/* Code for lcd RPM display Author: Jennifer Edwards - 14/11/2018> ++++++++++++++++++++++++++++++++++++++++++++++++++++ + THANKS TO JEFFERY NELSON from "macpod.net" + + He did all of the research and original coding + + of this program, all I did was tweak it to + + use my choice of I2C Two Wire LCD Display + + and added aditional documentation + ++++++++++++++++++++++++++++++++++++++++++++++++++++ Description:code to read tachometer port data of the SX2 mini mill and the SC2 mini lathe. This version will access I2c two wire serial 2x16 LCD display +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + I2C Board Wiring Instructions + + + + From LCD Board: + + jump pin "SCL" to arduino bord pin A5 + + jump pin "SDA" to arduino bord pin A4 + + jump pin "VCC" to arduino bord pin 5V + + jump pin "GND" to arduino bord pin GND + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Tachometer Port Interface: 2 GND 2 5V+ 1 LCDCS - Frame indicator, pulled low during the transmission of a frame. 1 LCDCL - Clock line, pulled low when data should be read (we read on the falling edges) 1 LCDDI - Data line. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + SC2 & SX2, and others Plug Wiring Instructions + + + + From Lathe or Milling Machine: + + + + jump pin 1 "LCDCS" to arduino bord pin 2 + + jump pin 2 "LCDCL" to arduino bord pin 3 + + jump pin 3 "LCDDI" to arduino bord pin 4 + + jump pin 4 "GND" to arduino bord pin GND + + jump pin 5 "+5v" to arduino bord pin Vin + + jump pin 6 N/C + + jump pin 7 N/C + + + + see pinout diagram below -view is looking at port ON machine + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ port pinout: X ---------> the notch in the socket 7 2 6 1 3 5 4 1 - Brown LCDCS 2 - Red LCDCL 3 - Orange LCDDI 4 - Green GND 5 - Blue +5V 6 - Pink GND (not used) 7 - Grey +5V (Not used) Data information: Reports if the spindel is stopped or running Reports speed of the spindel in 10rpm increments Data format: Every .75 seconds a packet is sent over the port. Each packet consists of: (ONLY If the mill uses the new mill protocol): a 36 bit header Following this potential header are 4 frames. Each Frame consists of 17 bytes. The first 8 bits represent an address, and the other bits represent data. Frame 0: Represents 7-segment data used for 1000's place of rpm readout. Address: 0xA0 Data: First bit is always 0 Next 7 bits indicate which of the 7-segments to light up. Last bit is always 0 Frame 1: Represents 7-segment data used for 100's place of rpm readout. Address: 0xA1 Data: First bit is always 0 Next 7 bits indicate which of the 7-segments to light up. Last bit is always 0 Frame 2: Represents 7-segment data used for 10's place of rpm readout. Address: 0xA2 Data: First bit is always 0 Next 7 bits indicate which of the 7-segments to light up. Last bit is 1 if the spindel is not rotating, 0 otherwise. Frame 3: Represents 7-segment data used for 1's place of rpm readout. This isn't used. Address: 0xA3 Data: This is always 0x20 ----------------------------------------------------- - This Version Used 2x16 LCD NOT 7 -Segment Display - - So Following layout is OBSOLETE - - kept in program for possible future use - ----------------------------------------------------- 7-segment display layout: d c g f b e a abcdefg 00 = 1111101 01 = 0000101 02 = 1101011 03 = 1001111 04 = 0010111 05 = 1011110 06 = 1111110 07 = 0001101 08 = 1111111 09 = 1011111 ----------------------------------- - end OBSOLETE Layout Information - ----------------------------------- */ #include // jme - for i2c display setup #include // jme - I2C board driver LiquidCrystal_PCF8574 lcd(0x27); // jme - assign oblect "lcd" to serial address #include #include #define LCDCS 2 #define LCDCL 3 #define LCDCL_INTERRUPT 1 #define LCDDI 4 #define LED_PIN 13 #define PACKET_BITS 68 // For newer mills there is a 36 bit header. #define PACKET_BITS_HEADER 36 // Uncomment for newer mill protocol #define PACKET_BITS_COUNT PACKET_BITS+PACKET_BITS_HEADER // Uncomment for old mill protocol //#define PACKET_BITS_COUNT PACKET_BITS #define MAXCOUNT 503500 #define LCD_RS 5 #define LCD_EN 6 #define LCD_D4 7 #define LCD_D5 8 #define LCD_D6 9 #define LCD_D7 10 volatile uint8_t packet_bits[PACKET_BITS_COUNT]; volatile uint8_t packet_bits_pos; void setup() { Serial.begin(115200); // jme set baud rate and open serial comm, wass 9600 lcd.begin(16, 2); // jme - init lcd lcd.setBacklight(255); // jme - turn on backlight lcd.print("LCD Found"); // jme- setup of i2c two wire LCD dsplay worked if visible delay (2000); // jme - give us two seconds to see above message before entering loop Wire.begin(); // jme - open two wire serial port to LCD Wire.beginTransmission(0x27); // jme - start communications with serial port pinMode(LCDCS, INPUT); pinMode(LCDCL, INPUT); pinMode(LCDDI, INPUT); pinMode(LED_PIN, OUTPUT); lcd.begin(16, 2); // jme - reset LCD lcd.setCursor(0, 1); // jme - Display Welcome Message lcd.print("Arduino UNO R3"); lcd.setCursor(0, 0); lcd.print("Jennifer's RPM"); // jme - It is the narcisisist in me what can I say lcd.setCursor(0, 0); delay (4000); // jme - pause a coupel secs lcd.begin(16, 2); // jme - reset LCD display before looping EIMSK |= (1<> 1; int ret = 0; switch(segments) { case 0x7D: ret = 0; break; case 0x05: ret = 1; break; case 0x6B: ret = 2; break; case 0x4F: ret = 3; break; case 0x17: ret = 4; break; case 0x5E: ret = 5; break; case 0x7E: ret = 6; break; case 0x0D: ret = 7; break; case 0x7F: ret = 8; break; case 0x5F: ret = 9; break; default: ret = -1; break; } return ret; } // Returns 1 if stopped, 0 otherwise. uint8_t spindle_stopped(uint16_t data) { return data & 0x1; } //----------------------------------------------------------------------------------------------------- void print_bits(int start, int len) { if (PACKET_BITS_COUNT != PACKET_BITS) { // Compensate for header start += PACKET_BITS_HEADER; } for (int i = start; i < start+len; i++) { if (packet_bits[i] & B00010000) { Serial.print('1'); } else { Serial.print('0'); } } } // 100000 ~= 88ms void block_delay(unsigned long units) { unsigned long i; for (i = 0; i < units; i++) { asm("nop"); // Stop optimizations } } SIGNAL(INT1_vect) { packet_bits[packet_bits_pos] = PIND; packet_bits_pos++; }