// Wire Slave Receiver for 4x4 Matrix Keypad Control // and ATTiny88 // Demonstrates use of the Wire library // Receives data as an I2C slave device // Refer to the "Keypad I2C Master" example for use with this sketch. // This example code is in the public domain. #include #define CLR 11 // Clear pin. Low pulse to clear all registers. #define CLK 12 // Clock pulse pin. Low to high transition loads data. #define DAT 13 // Data to be shifted out. const int ROWS[] = {17, 20, 18, 19}; const int COLS[] = {16, 22, 15, 21}; const int BTNS[] = {5, 6, 7, 8}; void setup() { //set register control pins to output pinMode(DAT, OUTPUT); pinMode(CLK, OUTPUT); pinMode(CLR, OUTPUT); for (int i = 0; i < 4; i++) { pinMode(ROWS[i], INPUT_PULLUP); pinMode(COLS[i], OUTPUT); pinMode(BTNS[i], INPUT_PULLUP); digitalWrite(ROWS[i], HIGH); } digitalWrite(CLK, LOW); digitalWrite(CLR, HIGH); // Reset all registers digitalWrite(CLR, LOW); digitalWrite(CLR, HIGH); Wire.begin(8); // join i2c bus with address #8 Wire.onReceive(receiveEvent); // register event Wire.onRequest(requestEvent); // register event //Serial.begin(9600); // start serial for output } byte leds = 0; byte flag = 1; // Initialize (Clear) byte cmd = 4; // Led operation - 0 Clear Single, 1 Set Single, // 2 Clear Value (OR) 3 Set Value (OR) // 4 Set value 5 Invert // 6 Rotate Left, 7 Rotate Right // 8 Shift Left, 9 Shift Right // (OR) means that if a bit in the value is not set // then the corresponding LED is unchanged byte dat = 0x00; // cmd parameter int r = -1; // Row # (-1 = not pressed) int c = -1; // Column # (-1 = not pressed) void loop() { byte val = 0; if (flag == 1) { // Update has been received switch (cmd) { case 0: // Clear single val = ~(1 << dat); leds &= val; break; case 1: // Set single val = (1 << dat); leds |= val; break; case 2: // Clear value (OR) leds &= ~dat; break; case 3: // Set value (OR) leds |= dat; break; case 4: // Set value leds = dat; break; case 5: // Invert leds = ~leds; break; case 6: // Rotate Left leds = (leds << 1) | ((leds & B10000000) >> 7); break; case 7: // Rotate Right leds = (leds >> 1) | ((leds & 1) << 7); break; case 8: // Shift Left and fill leds = leds << 1; leds |= (dat & 1); break; case 9: // Shift Right and fill leds = leds >> 1; leds |= ((dat << 7) & B10000000); break; } //Serial.println(leds, BIN); //Serial.println(); shiftOut(DAT, CLK, LSBFIRST, ~leds) ; // Inverted for pullup to Vcc. // wired to Vcc (ie, LOW is on). flag = 0; // Update received flag delay(100); } // Keypad scan for keypress. for (int i = 0; i < 4; i++) { // For each row, digitalWrite(COLS[i], LOW); // Set it LOW for (int j = 0; j < 4; j++) { // For each column if (digitalRead(ROWS[j]) == LOW) { // if it's LOW r = i; c = j; // then that button is pressed //Serial.print(r); //Serial.println(c); break; } } digitalWrite(COLS[i], HIGH); // Re-set it HIGH } // Button row scan for button press for (int i = 0; i < 4; i++) { // For each button, if (digitalRead(BTNS[i]) == LOW) { // if it's LOW r = 4; // insert the button number. c = i; break; } } } // Function that executes whenever data is received from master. // This function has been registered as an event in setup(). void receiveEvent(int numBytes) { if (numBytes > 1) { cmd = Wire.read(); // Receive byte 0 dat = Wire.read(); // Receive byte 1 flag = 1; // Flag for LED update required } } // Function that executes whenever data is requested by master. // This function has been registered as an event in setup(). void requestEvent() { Wire.write(r); // Respond with latest row Wire.write(c); // Respond with latest column r = -1; // Reset c = -1; }