/* http://www.bristolwatch.com/arduino/arduino6d.htm PCA9555 32-Bit GPIO Expander with Arduino and LCD Display Lewis Loflin lewis@bvu.net */ #include // specify use of Wire.h library. int i, j; byte temp1; volatile byte flag_bit = LOW; void setup() { pinMode(2, INPUT); // IRQ input // setup direction registers U1 Wire.begin(); Wire.beginTransmission(0x20); Wire.write(0x06); // pointer Wire.write(0x0F); // DDR Port0 bits 0-3 input 4-7 output Wire.write(0x00); // DDR Port1 all output Wire.endTransmission(); Wire.beginTransmission(0x20); Wire.write(0x02); // pointer Wire.write(0x00); // U1 bits 4-7 PORT0 LOW Wire.endTransmission(); // Keypad connected to U1 PORT0. // Invert bits on read of U1 PORT0. Wire.beginTransmission(0x20); Wire.write(0x04); // pointer Wire.write(0xFF); // invert bits PORT0 on read Wire.endTransmission(); // clear LEDs U1 PORT1 Wire.beginTransmission(0x20); Wire.write(0x03); // begin here Wire.write(0x00); Wire.endTransmission(); attachInterrupt(0, flag1, FALLING); // Use 0x21 (U2) for LCD display. Wire.beginTransmission(0x21); // setup direction registers U2 Wire.write(0x06); // pointer Wire.write(0x00); // DDR Port1 all output Wire.write(0x00); // DDR Port1 all output Wire.endTransmission(); // setup PORT0 D7 = E; D6 = RS Wire.beginTransmission(0x21); Wire.write(0x02); //pointer Wire.write(B10000000); // setup for command mode by default Wire.endTransmission(); /* writeCommand(byte) sends a control code to display. Hd44780 display commands are: 0x0f = initiate display cursor on blinking 0x0c = initiate display cursor off 0x01 = clear display fills display with spaces (0x20). 0x02 = HOME returns to first line first character 0x38 = 2 lines X 16 char 8 bits mode. Defaults to 1 line mode. 0x10 = cursor left 0x14 = cursor right 0x18 = Shifts entire display left 0x1c = Shifts entire display right 1st line on display is 0 and 2nd line is 1. Characters are numbered 0-15. One can also go to a specific location. writeCommand(0x80); // go to line 0 column 0 writeCommand(0x80 + 0x40); // go to line 1 column 0 */ writeCommand(0x38); // setup for 2 lines writeCommand(0x0F); // blinking cursor writeCommand(0x02); // home writeCommand(0x01); // clear } // end setup void loop() { if (flag_bit = HIGH) { detachInterrupt(0); temp1 = getKey(); // scan keypad for BCD code. flag_bit = 0x00; delay(100); attachInterrupt(0, flag1, FALLING); } // Output message and string length if (temp1 == 0x16) { char String1[] = "Hello World!\n"; typeln(String1, 1); // write to line 1 LCD // could use typeln("Hello World!\n"); instead. char String2[2]; int j = sizeof(String1); itoa(j, String2, 10); // convert int to string // String2[sizeof(String2)] = '\n'; strcat(String2, " bytes!\n"); // concat strings typeln(String2, 2); // write to line 2 LCD } if (temp1 != 0x00) { Wire.beginTransmission(0x20); Wire.write(0x03); // begin here Wire.write(temp1); // display code on LEDs Wire.endTransmission(); if ((temp1 <= 0x39) && (temp1 >= 0x30)) type(temp1); // output number 0-9 if (temp1 == 0x11) type(0x20); // print space if (temp1 == 0x12) writeCommand(0x01); // clear if (temp1 == 0x13) writeCommand(0x10); // cursor left if (temp1 == 0x14) writeCommand(0x14); // cursor right if (temp1 == 0x15) writeCommand(0x02); // home } } // end loop void flag1() // set bit { flag_bit = HIGH; } // Below we pass a pointer to array1[0]. If no '\n' // then the limit is 16 char. (0 - 15) void typeln(char *array1, int i) { delayMicroseconds(1000); if (i == 1) writeCommand(0x80); // begin on 1st line if (i == 2) writeCommand(0x80 + 0x40); // begin on 2nd line for (int j = 0; (array1[j] != '\n') && (j < 16); j++) type(array1[j]); } /* void writeCommand(byte x) Send control command to Hd44780 display E High to Low transition write command or data to Hd44780 display RS 0 for command, default 1 for data setup port0 D7 = E; D6 = RS Data is at port 1 register 0x03 control is at port 0 register 0x02 */ void writeCommand(byte x) { Wire.beginTransmission(0x21); Wire.write(0x03); // begin here Wire.write(x); // command code Wire.endTransmission(); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B10000000); // command mode E high Wire.endTransmission(); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B00000000); // char mode E low Wire.endTransmission(); delayMicroseconds(100); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B10000000); // E high back to command mode Wire.endTransmission(); } /* void type(byte x) Send char to Hd44780 display E High to Low transition write command or data to Hd44780 display RS 0 for command, default 1 for data setup port0 D7 = E; D6 = RS Data is at port 1 register 0x03 control is at port 0 register 0x02 */ void type(byte x) { Wire.beginTransmission(0x21); Wire.write(0x03); // begin here Wire.write(x); // data Wire.endTransmission(); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B11000000); // char mode E high Wire.endTransmission(); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B01000000); // char mode E low Wire.endTransmission(); delayMicroseconds(100); Wire.beginTransmission(0x21); Wire.write(0x02); // pointer Wire.write(B10000000); // E high back to command mode Wire.endTransmission(); } byte getKey() { Wire.beginTransmission(0x20); Wire.write(0); // set data pointer Wire.endTransmission(); Wire.requestFrom(0x20, 1); byte c = Wire.read(); if ((c & 0x0F) == 0) return 0x00; // no key pressed Wire.beginTransmission(0x20); Wire.write(0x02); Wire.write(B11100000); // check row L1 Wire.endTransmission(); Wire.beginTransmission(0x20); Wire.write(0); // set data pointer Wire.endTransmission(); Wire.requestFrom(0x20, 1); c = Wire.read(); if ((c & 0x1F) > 0x10) { if (c==B00010001) c = 0x30; if (c==B00010010) c = 0x31; if (c==B00010100) c = 0x32; if (c==B00011000) c = 0x33; delay(100); resetPort0(); return c; } Wire.beginTransmission(0x20); Wire.write(0x02); Wire.write(B11010000); // check row L2 Wire.endTransmission(); Wire.beginTransmission(0x20); Wire.write(0); // set data pointer Wire.endTransmission(); Wire.requestFrom(0x20, 1); c = Wire.read(); if ((c & 0x2F) > 0x20) { if (c==B00100001) c = 0x34; if (c==B00100010) c = 0x35; if (c==B00100100) c = 0x36; if (c==B00101000) c = 0x37; delay(100); resetPort0(); return c; } Wire.beginTransmission(0x20); Wire.write(0x02); Wire.write(B10110000); // check row L3 Wire.endTransmission(); Wire.beginTransmission(0x20); Wire.write(0); // set data pointer Wire.endTransmission(); Wire.requestFrom(0x20, 1); c = Wire.read(); if ((c & 0x4F) > 0x40) { if (c==B01000001) c = 0x38; if (c==B01000010) c = 0x39; if (c==B01000100) c = 0x11; if (c==B01001000) c = 0x12; delay(100); resetPort0(); return c; } Wire.beginTransmission(0x20); Wire.write(0x02); Wire.write(B01110000); // check row L4 Wire.endTransmission(); Wire.beginTransmission(0x20); Wire.write(0); // set data pointer Wire.endTransmission(); Wire.requestFrom(0x20, 1); c = Wire.read(); if ((c & 0x8F) > 0x80) { if (c==B10000001) c = 0x13; if (c==B10000010) c = 0x14; if (c==B10000100) c = 0x15; if (c==B10001000) c = 0x16; delay(100); resetPort0(); return c; } } // end getKey() // reset port 0 void resetPort0() { Wire.beginTransmission(0x20); // Wire.write(0x02); // pointer Wire.write(0x00); // clear bits 4-7 PORT0 Wire.endTransmission(); }