Please can someone help? (reading from a control pad)


I am doing a project to add a control pad port to a portable game console.

The control pad uses a DE9 connector, and in order to read all of the buttons, I have to first supply 5V to the "select" pin, read the 6 data pins, then supply 0V to the "select" pin and re-read them to see values for the remaining buttons.

When the states are read, I then output via some digital pins to make some transistors switch the relevant buttons on the game console circuit. At the moment I am using LEDs instead of the transistors attached to the game console button contacts.

I have managed to make a loop that scans the pins in one state or the other, but I don't know how to switch between states and scan all the buttons and keep the outputs (LEDs) updated with their last states.

I will upload some videos to illustrate what's going on. Here is the code that works in either one state or another, thanks for reading:

  Genesis Control Pad Reader
  This program reads pins from the Genesis controller and lights up
  appropriate LEDs to show which buttons have been pressed.

//Setting up the pins for the inputs, and initialising 
//the states of the LED variables
const int upPin = 8;
int upState = LOW;
const int downPin = 9;
int downState = LOW;
const int leftPin = 10;
int leftState = LOW;
const int rightPin = 11;
int rightState = LOW;
const int onePin = 12;
int oneState = LOW;
const int startPin = 13;
int startState = LOW;
const int twoPin = A0;
int twoState = LOW;
int selectPin = 6;

//Setting the pins to read and write
void setup() {
  pinMode(0, INPUT);
  pinMode(2, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(5, INPUT);
  pinMode(selectPin, OUTPUT);
  pinMode(7, INPUT);
  pinMode(upPin, OUTPUT);
  pinMode(downPin, OUTPUT);
  pinMode(leftPin, OUTPUT);
  pinMode(rightPin, OUTPUT);
  pinMode(onePin, OUTPUT);
  pinMode(startPin, OUTPUT);
  pinMode(twoPin, OUTPUT);

void loop() {
  int up = digitalRead(0);
  int down = digitalRead(2);
  int left = digitalRead(A2);
  int right = digitalRead(A1);
  int ab = digitalRead(5);
  int cs = digitalRead(7); 
  digitalWrite(selectPin, LOW);  //This is the select pin that switches between states. I need to do this automatically
  if (up == HIGH) 
  upState = LOW;
  upState = HIGH;
  if (down == HIGH) 
  downState = LOW;
  downState = HIGH;
  if (left == HIGH) 
  leftState = LOW;
  leftState = HIGH;
  if (right == HIGH) 
  rightState = LOW;
  rightState = HIGH;

  if (ab == HIGH) 
  oneState = LOW;
  oneState = HIGH;

  if (cs == HIGH) 
  twoState = LOW;
  twoState = HIGH; 
    digitalWrite(upPin, upState);
    digitalWrite(downPin, downState);
    digitalWrite(leftPin, leftState);
    digitalWrite(rightPin, rightState);
    digitalWrite(onePin, oneState);
    digitalWrite(twoPin, twoState);

I found the control pad protocol here:

Edit: Here is the video showing what happens:

I have managed to make a loop that scans the pins in one state or the other, but I don't know how to switch between states and scan all the buttons and keep the outputs (LEDs) updated with their last states.

Let me see if I understand...

Right now, you push a button and the LED goes on and when you release the button it goes off?

What you want is to push the button once to turn-on the LED, and you want the LED to stay on when you release the button. Then when you push the button again, you want the LED to "toggle" off?

If that's what you want, you need to use a [u]logical and[/u] along with your if-statement, which looks like '&&' in the Arduino language. In english, the logic is: if the LED is on and I push the button, turn the LED off. If the LED is off and I push the button, turn it on.

There is one complication. Most mechanical switches "bounce" for a few milliseconds. So, when you push/release the switch the Arduino will "think" you pushed the switch several times, and the LED will be on or off randomly depending on the number of bounces. The solution is to delay before reading or accepting a 2nd button-push.

P.S. Of course, there is also an or operator so you can do all kinds of logic... If the LED is on, and I push button-B or button-C, then turn-off the LED.

Hi, thanks for your reply.

I am not trying to toggle the LEDs indefinitely, I just want them to remain on their last state while the arduino is scanning the other half of the buttons and if the last state of the button was "pressed". I don't want to use delays if it can be helped because the game needs to have constant responsiveness from the control pad. Also, the debouncing is already taken care of by the controller and the game console, it shouldn't be a problem.

In the video, the first 2 clips show the behaviour I expect; with "select" pin set high, I can read up, down, left, right, b and c. With "select set low, I can read up and down, a and start, but the others don't work, and left and right are grounded. What I want to happen is for the arduino to read each state consecutively by writing to "select" Pin and reading only the buttons I can read, then hold them at the last state while reading the next set of buttons.

My main problem is, I don't know how to make the program switch between the two states. In the third clip, I try to do this, but it gets stuck , and some weird things happen (e.g. the start button causes two LEDs to turn on at once).

I think I need a simple state machine to switch between 2 commands and I need the outputs to not go crazy when they are not being read. I just don't know how to implement it.