One INPUT_PULLUP connected to several OUTPUTS

Hi there. I'm trying to connect several switches to one single input. I handle them like the common "keypad" algorithm. I cycle through the outputs, reading the pin 22. This example code will explain it way better:

/**
* Connect pins 23,24,25 to pin 22. (place a switch in the cables so it gets easier to cut the cable, to detect the "switch change")
*/


int readInput(uint8_t pin) {
    digitalWrite(pin,LOW);
    int pstatus = digitalRead(22);
    digitalWrite(pin,HIGH);
    return 1 ^ pstatus;
}

setup(){
  pinMode(22, INPUT_PULLUP);
  digitalWrite(22, HIGH);
pinMode(23, OUTPUT);
pinMode(24, OUTPUT);
pinMode(25, OUTPUT);
}

loop(){
for (int i = 23;i<26;i++){
Serial.println(readInput(i));
}

That's not really the code, but it's the plain algorithm behind it.
The problem is... it doesn't work when more than 1 switch is closed at the same time. I thought this wouldn't happen, because I set to HIGH the output pin after I finish reading the input pin. Why does this happen? My logic is failing apart

Try a delay of 1ms between making the pin low and reading pin 22.

Try a delay of 500ms at the end of loop().

Please don't use this: 1 ^ pstatus
It's not normal to use it like that.

If the buttons on pins 23 and 24 are on, then they both drive pin 22 high, but readInput(23) drives pin 22 low, while pin 24 is still driving it high,

instead of writing high to idle pins, you can switch them to inputs, so they do not drive pin 22 high in between reads

int readInput(uint8_t pin) {
    pinMode(pin,OUTPUT);
    digitalWrite(pin,LOW);
    int pstatus = digitalRead(22);
    pinMode(pin,INPUT_PULLUP);
    return 1 ^ pstatus;
}

to get different return values for different pins change the return statement to

return (1 ^ pstatus) << (pin - 23);

it doesn't work when more than 1 switch is closed at the same time.

Please show your schematic. I think you need diodes in it to prevent this.

Thanks for the suggestions. But I'm still fighting. It only works when "switch" is used. if I close one switch, all other switchs are also read as "closed".

My current read method:

int readGpioInput(uint8_t pin) {
pinMode(pin,OUTPUT);
digitalWrite(pin,LOW);
delay(1);
int pstatus = digitalRead(22);
pinMode(pin,INPUT_PULLUP);
return 1 ^ pstatus;
}

The schematics are pretty simple:
(using an arduino Mega 2560)

Pin 23 ---------- Pin 22
Pin 24 ---------- Pin 22
Pin 25 ---------- Pin 22

(pin 22 is an INPUT_PULLUP)
I think I need some diodes, right?

Can you make a schematic or drawing of your switches ?
To attach a picture, you can click on "Additional Options..." at the lower left of the text field when writing a post.
It should not be so hard to detect 1,2 or 3 buttons at the same time.

Are these 3 buttons all you want ? You are using 4 pins now for 3 buttons.
Or do you want to extend it into an array ? The keypad array doesn't need diodes, it scans column by column and everytime it reads all the rows.
What about using the Keypad library ? Arduino Playground - HomePage

dc740:
. if I close one switch, all other switchs are also read as "closed".

That only makes sense if the switches are normally closed

Here's a diagram, I included the (internal) pullup resistors

so pin 22 should always be high, except when a switch is closed and while that switch line is driven low by readGpioInput(),

You might use it the other way around : Make 22 low, and read 23,24 and 25.
But it should also work this way. I don't know why you can not read more button presses at the same time.
There are other possibilities, with diodes, and a resistor ladder for an analog input.

it's not that complicated, it is a basic 3 row x 1 col key matrix

when idle, all pins are high (input_pullup)

one row at a time is set to output low (the active row)

the column (pin 22) is always an input, normally high

if the button is pressed on the active row, then the column (pin 22) will be driven low (but only while the active row is driven low)

if any other button, on any other row is also pressed, it merely connects another pullup onto the column, which has no effect

only the button on active row can drive the column low

additional columns can be added (orange), each column utilizes one input pin

it does work, next it just (probably) needs a routine debounce filter, and/or a wait-for-release routine

void setup()
{pinMode(22,INPUT_PULLUP);
 pinMode(23,INPUT_PULLUP);
 pinMode(24,INPUT_PULLUP);
 pinMode(25,INPUT_PULLUP);
}

int readGpioInput(uint8_t pin)
{pinMode(pin,OUTPUT);
 digitalWrite(pin,LOW);
 int pstatus=digitalRead(22);
 pinMode(pin,INPUT_PULLUP);
 return 1^pstatus;
}

void loop() 
{for (int i=23;i<26;i++)
 {Serial.print("row ");
  Serial.print(i-23);
  Serial.print(" is ");
  Serial.println(readGpioInput(i));
  delay(1000);
 }
}

serial output (also works with more than one button pressed)

row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 1  -------- button 1 pressed
row 1 is 0
row 2 is 0
row 0 is 1  --------
row 1 is 0
row 2 is 0
row 0 is 1  --------
row 1 is 0
row 2 is 0
row 0 is 0  -------- button 1 released
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0
row 2 is 0
row 0 is 0
row 1 is 0

THANK YOU ALL!!!

It's finally working. After the confirmation of SingTorch I found another bug in my code, which would explain some weird behavior when multiple switches were closed. I didn't use the keypad library because it was just a 3x1 matrix and was supposed to "just work"...

Again, thank you all.