0
votes

I am currently working on a project which involves a LCD, a sensor, and a keypad.

The Arduino Uno has 14 input/output pins (0-13, 0 being Rx, 1 being Tx).

The LCD itself occupies 5 pins (pin 8-12), the sensor 1 (pin 7) and the keypad 7 (pin 0-6), which is nice because I have 14 potential pins.

So I downloaded a basic programm to quickly test the keypad and adjust the neccesary variables. I wanted to display the numbers on the computer via serial communication. Row 1 and 4 worked, row 2 & 3 didn't. The keypad can't be faulty as I measured the resistance for every combination. Then I realized that the pins that hold the information about row 2 & 3 are connected to pin 0 & 1 of the Arduino Uno (Rx & Tx).

Is it possible to use pin 0 & 1 as input while serial communication is active?

If yes, it must be the code:

/*     SparkFun Keypad Pinout:
       Rows and columns are connected as such:
       -------------
     R1  | 1 | 2 | 3 | - 5 (grün)
     R2  | 4 | 5 | 6 | - 0 (braun)
     R3  | 7 | 8 | 9 | - 1 (schwarz)
     R4  | * | 0 | # | - 3 (violett)
       -------------
           |C1 |C2 |C3
     4(blau) 6(gelb) 2(weiß)
    */
    // Pins 1-7 of the keypad connected to the Arduino respectively:
    int keypadPins[7] = {0, 1, 2, 3, 4, 5, 6};
    int keypadStatus;  // Used to monitor which buttons are pressed.
    int timeout;  // timeout variable used in loop
    
    void setup()
    {
      Serial.begin(9600);
      for (int i=0; i<7; i++)
      {
        pinMode(keypadPins[i], INPUT);  // Set all keypad pins as inputs
        digitalWrite(keypadPins[i], HIGH);  // pull all keypad pins high
      }
    }
    
    void loop()
    {
      keypadStatus = getKeypadStatus();  // read which buttons are pressed
      if (keypadStatus != 0)  // If a button is pressed go into here
      {
        sendKeyPress(keypadStatus);  // send the button over USB
        timeout = 2000;  // top of the repeat delay
        while ((getKeypadStatus() == keypadStatus) && (--timeout))  // Decrement timeout and check if key is being held down
          delayMicroseconds(1);
        while (getKeypadStatus() == keypadStatus)  // while the same button is held down
        {
          sendKeyPress(keypadStatus);  // continue to send the button over USB
          delay(50);  // 50ms repeat rate
        }
      }
    }
    
    /* sendKeyPress(int key): This function sends a single key over USB
       It requires an int, of which the 12 LSbs are used. Each bit in
       key represents a single button on the keypad.
       This function will only send a key press if a single button
       is being pressed */
    void sendKeyPress(int key)
    {
      switch(key)
      {
        case 1:  // 0x001
          Serial.print('1');  // Sends a keyboard '1'
          break;
        case 2:  // 0x002
          Serial.print('2');
          break;
        case 4:  // 0x004
          Serial.print('3');
          break;
        case 8:  // 0x008
          Serial.print('4');
          break;
        case 16:  // 0x010
          Serial.print('5');
          break;
        case 32:  // 0x020
          Serial.print('6');
          break;
        case 64:  // 0x040
          Serial.print('7');
          break;
        case 128:  // 0x080
          Serial.print('8');
          break;
        case 256:  // 0x100
          Serial.print('9');
          break;
        case 512:  // 0x200
          Serial.print('*');
          break;
        case 1024:  // 0x400
          Serial.print('0');  // Sends a keyboard '0'
          break;
        case 2048:  // 0x800
          Serial.print('\n');  // Sends the 'ENTER' key
          break;
      }
    }
    
    /* getKeypadStatus(): This function returns an int that represents
    the status of the 12-button keypad. Only the 12 LSb's of the return
    value hold any significange. Each bit represents the status of a single
    key on the button pad. '1' is bit 0, '2' is bit 1, '3' is bit 2, ..., 
    '#' is bit 11.
    
    This function doesn't work for multitouch.
    */
    int getKeypadStatus()
    {
      int rowPins[4] = {keypadPins[5], keypadPins[0], keypadPins[1], keypadPins[3]};  // row pins are 5, 0, 1, and 3 of the keypad
      int columnPins[3] = {keypadPins[4], keypadPins[6], keypadPins[2]};  // column pins are pins 2, 4, and 6 of the keypad
      int keypadStatus = 0;  // this will be what's returned
      
      /* initialize all pins, inputs w/ pull-ups */
      for (int i=0; i<7; i++)
      {
        pinMode(keypadPins[i], INPUT);
        digitalWrite(keypadPins[i], HIGH);
      }
      
      for (int row=0; row<4; row++)
      {  // initial for loop to check all 4 rows
        pinMode(rowPins[row], OUTPUT);  // set the row pin as an output
        digitalWrite(rowPins[row], LOW);  // pull the row pins low
        for (int col=0; col<3; col++)
        {  // embedded for loop to check all 3 columns of each row
          if (!digitalRead(columnPins[col]))
          {
            keypadStatus |= 1 << ((row+1)*3 + (col+1) - 4);  // set the status bit of the keypad return value
          }
        }
        pinMode(rowPins[row], INPUT);  // reset the row pin as an input
        digitalWrite(rowPins[row], HIGH);  // pull the row pin high
      }
      
      return keypadStatus;
    }
1

1 Answers

0
votes

Is it possible to use Pin 0 & 1 as input while secial communication?

I have never used this part but still it just took me a few minutes to locate the relevant text by RTFM ATmega328P p.71

• TXD/PCINT17 – Port D, Bit 1 TXD, transmit Data (data output pin for the USART). When the USART transmitter is enabled, this pin is configured as an output regardless of the value of DDD1.

• RXD/PCINT16 – Port D, Bit 0 RXD, Receive Data (data input pin for the USART). When the USART receiver is enabled this pin is configured as an input regardless of the value of DDD0. When the USART forces this pin to be an input, the pull-up can still be controlled by the PORTD0 bit.

So instead of Arduino this & Arduino that, I would advise to familiarize yourself with the friendly MCU manual.