Might have bit off more than I can chew. 56 buttons, 5 rotaries and 2 joys

No problem, fixed and hopefully easier to zoom in. I've been working from my laptop that has a horrible screen and 1280x768 resolution and the white was way to bright but after getting back to my PC with 2560x1440 and better calibrated settings I was feeling your pain :smiley:

Fihn:
I think I finally have it...

Yellow (9) analog input should go to Leonardo Analog input, that is to pin with "A" in front.
Flip all diodes except on analog joystics.
I will examine schematic further when you connect all buttons.

PaulRB:
Please attach the image file to your forum post, post it, copy the address, modify the post, click the insert image icon and paste the image address.

For some strange reason you came to a conclusion you have some sort of authority here – this is the second time you are demanding something. Don't like the way he's posting – don't read it. Go be forum nazi elsewhere where people don't put their code in "Code" tags or something, your not being useful here anyway.

Sheee, some people feels like they are center of the universe...

P.S. I preferred gray background.

Thanks, that's much better.

So... let me see if I have understood:

To detect if pushbutton D1 is pressed, the code will make column "1" OUTPUT/LOW and columns "2" to "7" will be either INPUT or OUTPUT/HIGH. Rows "A" to "H" will be INPUT_PULLUP. If button D1 is pressed, column "D" will be pulled LOW, otherwise it will read HIGH. Correct?

If I am correct, I don't understand your wiring of the double-throw momentary toggle switches. For example "A6A7": I would expect to see the COM pin wired to "A" and the other two pins wired, each with its own diode, to "6" and "7".

Paul, I honestly don't know I'm still trying to understand what's all happening with the design. I get the matrix part of it but when it comes to what's input and what's output I'm uncertain. Correct me if I'm wrong but my take is the Arduino will be sending a signal out over whatever is designated as output and the signal will return back through the input. And this is the purpose of the diodes as they are current blocking?

Further schematic fixed will be finished this afternoon. In the meantime here's the schematic with grey background. I aim to please everyone :slight_smile:

Fihn:
I get the matrix part of it but when it comes to what's input and what's output I'm uncertain. Correct me if I'm wrong but my take is the Arduino will be sending a signal out over whatever is designated as output and the signal will return back through the input. And this is the purpose of the diodes as they are current blocking?

No, diode purpose is to prevent false button press detection if more than one button is pressed (ghosting), diodes do not limit current.

Martix will work like this:
All input lines will be pulled up (5V) by internal Leonardo Pullup resistors. All output lines will be usually high. You will set one Output at the time to "LOW" and read Inputs. If button will be pressed Input will get LOW.
I know it's a bit confusing, but if you bare with me I will get you true it. If you want to make "normal" way you have to add pullup and current limiting resistors I tols you before. Let me know what path you want to take.

Fihn:
Further schematic fixed will be finished this afternoon. In the meantime here's the schematic with grey background. I aim to please everyone :slight_smile:

I'm not picky – either way is OK. Work as fast/slow as you want – I'll be here if you need me :smiley:
If you don't want to add resistors than you'll have to flip all diodes around (leave analog diodes as it is).

I'll be working as fast as the help keeps coming in. I'm really excited to be making headway on this project and can't wait to see my son's face when he opens the gift wrap to see what I made and gets to use it on his games. After all this work I may have to play around with it as well :grinning:

Fihn:
I'll be working as fast as the help keeps coming in. I'm really excited to be making headway on this project and can't wait to see my son's face when he opens the gift wrap to see what I made and gets to use it on his games. After all this work I may have to play around with it as well :grinning:

Well, hardware diagram is almost done, waiting you to flip diodes and connect 3 button that aren't connected. That will be it.

Ok here we go, final (hopefully :grinning: ) schematic in both flavors, white and grey :sunglasses: also included white and grey EasyEDA json files in both flavors as well.

Fihn:
Ok here we go, final (hopefully :grinning: ) schematic in both flavors, white and grey :sunglasses: also included white and grey EasyEDA json files in both flavors as well.

:smiley: Don't waste your time, 1 version is plenty.

I will review it and update this post if I notice something.

Today I "upgraded" my rotary encoder code, now it's extremely solid and accurate (0 false step detection or skipping) even on very slow or high speed. It might be useful to you as well, tho modifications will be needed for usage in matrix, I'll try to do them tomorrow. Please link what rotary encoders you are using and how many steps per revolution they have.

EDIT:
I made a mistake – analog inputs will not work in this configuration!

Soldering iron is heating up as I type. My button naming scheme was my second reference point to verify I have no two of the same wires to multiple buttons so I'm confident that is good to go. I also used wire colors that match the colors I used in my schematic to reference back to as well to make sure no wrong colors are landed at the wrong terminal. Thank you again, I will have soldering done tonight and ready for code when you are.

Amazon encoder link No info is given about steps per revolution.

Fihn:
Soldering iron is heating up as I type. My button naming scheme was my second reference point to verify I have no two of the same wires to multiple buttons so I'm confident that is good to go. I also used wire colors that match the colors I used in my schematic to reference back to as well to make sure no wrong colors are landed at the wrong terminal. Thank you again, I will have soldering done tonight and ready for code when you are.

Amazon encoder link No info is given about steps per revolution.

You are rich to pay that much for those encoders, on Ali they are few times cheaper...
Anyway, I think they are 15 steps – you have to take one, rotate it slowly and count steps per 360 revolution (you feel snapping when rotating, one snap – one step).

Btw, you did a great job with the matrix design – I think not many people can do what you did.

Thank you, took my time with it for sure but I want to get this right so it works as good as I hope it will.

The encoders are 20 steps in a full 360 revolution.

Just to make sure I'm hooking these up right, the cathode side of the diode (-) (side with solid band around it) connects to the terminal of a button and the wire connects to the non-band side (the + side).

Fihn:
Thank you, took my time with it for sure but I want to get this right so it works as good as I hope it will.

Well, this will depend on the code, in your case hardware is the easy part... :smiley:

Do all digital inputs has 8 buttons attaches to them? Would be great to remove 9 from 9G and 9H. If no spare digital input – leave it like this, not perfect but it will do.

Fihn:
The encoders are 20 steps in a full 360 revolution.

I'll have to admit – encoders will be annoying to code due to nature of the matrix...
While seeing that there are extra 2 pins on Leonardo I kinda want to redesign entire matrix to 10x7 or 10x8 – it would make coding waaaaay easier. I bet you are swearing me now :smiley: Sorry that I'm writing this only now, but it's kinda important to make coding simple as possible, cos it will be complicated as it is.

Are you up to it? I will understand if you want to keep everything as it is and I will help you with the code, but I had to code 38 buttons and only 2 encoders and it was pain in the but, and you have 5 encoders...

Yes they all have 8 inputs attached. I'd rather make a change now than after I get it all soldered. Since we are talking about code now I just want to verify. All button presses and joystick axis movements will be detected as Joystick / Gamepad button presses? I don't want to have them assigned to a keystroke but rather as a joystick / gamepad input in games.

Fihn:
Yes they all have 8 inputs attached. I'd rather make a change now than after I get it all soldered. Since we are talking about code now I just want to verify. All button presses and joystick axis movements will be detected as Joystick / Gamepad button presses? I don't want to have them assigned to a keystroke but rather as a joystick / gamepad input in games.

OK, lets remake to 10x9 matrix, you have no idea how much easier coding will be. I kinda missed this part cos it was a while, but today after playing with encoders I remember that it's a bit complicated if matrix isn't "clean". I will make you new matrix design tomorrow. All you will have to do is solder it.

What comes to Joystick stuff – I have no experience there. :o My keyboard is only "keyboard", not a joystick. I thought you already have Joystick inputs figured out. I will help you to get to a point where when any button is pressed it would call specific Arduino function. After this point you'll have to figure out what should be written in those functions.
You will not get any help from me about "Joystick" stuff simply cos I've never made a project with "joystick" HID.

Ok. So your 9x10 matrix, I'll still solder all diodes as per the current schematic?

Fihn:
Ok. So your 9x10 matrix, I'll still solder all diodes as per the current schematic?

No, just don't do anything, I will change stuff around so diodes may go to other pins, will be clear tomorrow.

Here’s an example of joystick code from the library I’ll be working with. Can you look at it and see if what we are doing may work with it?

/// Program used to test the USB Joystick object on the
// Arduino Leonardo or Arduino Micro.
//
// Matthew Heironimus
// 2015-03-28 - Original Version
// 2015-11-18 - Updated to use the new Joystick library
//              written for Arduino IDE Version 1.6.6 and
//              above.
// 2016-05-13   Updated to use new dynamic Joystick library
//              that can be customized.
//------------------------------------------------------------

#include "Joystick.h"

// Create Joystick
Joystick_ Joystick;

// Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
//const bool testAutoSendMode = true;
const bool testAutoSendMode = false;

const unsigned long gcCycleDelta = 1000;
const unsigned long gcAnalogDelta = 25;
const unsigned long gcButtonDelta = 500;
unsigned long gNextTime = 0;
unsigned int gCurrentStep = 0;


void testXYAxis(unsigned int currentStep)
{
  int xAxis;
  int yAxis;

  if (currentStep < 256)
  {
    xAxis = currentStep - 127;
    yAxis = -127;
    Joystick.setXAxis(xAxis);
    Joystick.setYAxis(yAxis);
  }
  else if (currentStep < 512)
  {
    yAxis = currentStep - 256 - 127;
    Joystick.setYAxis(yAxis);
  }
  else if (currentStep < 768)
  {
    xAxis = 128 - (currentStep - 512);
    Joystick.setXAxis(xAxis);
  }
  else if (currentStep < 1024)
  {
    yAxis = 128 - (currentStep - 768);
    Joystick.setYAxis(yAxis);
  }
  else if (currentStep < 1024 + 128)
  {
    xAxis = currentStep - 1024 - 127;
    Joystick.setXAxis(xAxis);
    Joystick.setYAxis(xAxis);
  }
}


void testZAxis(unsigned int currentStep)
{
  if (currentStep < 128)
  {
    Joystick.setZAxis(-currentStep);
  }
  else if (currentStep < 256 + 128)
  {
    Joystick.setZAxis(currentStep - 128 - 127);
  }
  else if (currentStep < 256 + 128 + 127)
  {
    Joystick.setZAxis(127 - (currentStep - 383));
  }
}


void testHatSwitch(unsigned int currentStep)
{
  if (currentStep < 8)
  {
    Joystick.setHatSwitch(0, currentStep * 45);
  }
  else if (currentStep == 8)
  {
    Joystick.setHatSwitch(0, -1);
  }
  else if (currentStep < 17)
  {
    Joystick.setHatSwitch(1, (currentStep - 9) * 45);
  }
  else if (currentStep == 17)
  {
    Joystick.setHatSwitch(1, -1);
  }
  else if (currentStep == 18)
  {
    Joystick.setHatSwitch(0, 0);
    Joystick.setHatSwitch(1, 0);
  }
  else if (currentStep < 27)
  {
    Joystick.setHatSwitch(0, (currentStep - 18) * 45);
    Joystick.setHatSwitch(1, (8 - (currentStep - 18)) * 45);
  }
  else if (currentStep == 27)
  {
    Joystick.setHatSwitch(0, -1);
    Joystick.setHatSwitch(1, -1);
  }
}


void testThrottleRudder(unsigned int value)
{
  Joystick.setThrottle(value);
  Joystick.setRudder(value);
}


void testXYZAxisRotation(unsigned int degree)
{
  Joystick.setRxAxis(degree);
  Joystick.setRyAxis(degree);
  Joystick.setRzAxis(degree * 2);
}


void setup() {

  // Set Range Values
  Joystick.setXAxisRange(-127, 127);
  Joystick.setYAxisRange(-127, 127);
  Joystick.setZAxisRange(-127, 127);
  Joystick.setRxAxisRange(0, 360);
  Joystick.setRyAxisRange(360, 0);
  Joystick.setRzAxisRange(0, 720);
  Joystick.setThrottleRange(0, 255);
  Joystick.setRudderRange(255, 0);

  if (testAutoSendMode)
  {
    Joystick.begin();
  }
  else
  {
    Joystick.begin(false);
  }

  pinMode(A0, INPUT_PULLUP);
  pinMode(13, OUTPUT);
}


void loop() {

  // System Disabled
  if (digitalRead(A0) != 0)
  {
    // Turn indicator light off.
    digitalWrite(13, 0);
    return;
  }

  // Turn indicator light on.
  digitalWrite(13, 1);

  if (millis() >= gNextTime)
  {

    if (gCurrentStep < 33)
    {
      gNextTime = millis() + gcButtonDelta;
      testSingleButtonPush(gCurrentStep);
    }
    else if (gCurrentStep < 37)
    {
      gNextTime = millis() + gcButtonDelta;
      testMultiButtonPush(gCurrentStep - 33);
    }
    else if (gCurrentStep < (37 + 256))
    {
      gNextTime = millis() + gcAnalogDelta;
      testThrottleRudder(gCurrentStep - 37);
    }
    else if (gCurrentStep < (37 + 256 + 1024 + 128))
    {
      gNextTime = millis() + gcAnalogDelta;
      testXYAxis(gCurrentStep - (37 + 256));
    }
    else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510))
    {
      gNextTime = millis() + gcAnalogDelta;
      testZAxis(gCurrentStep - (37 + 256 + 1024 + 128));
    }
    else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510 + 28))
    {
      gNextTime = millis() + gcButtonDelta;
      testHatSwitch(gCurrentStep - (37 + 256 + 1024 + 128 + 510));
    }
    else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510 + 28 + 360))
    {
      gNextTime = millis() + gcAnalogDelta;
      testXYZAxisRotation(gCurrentStep - (37 + 256 + 1024 + 128 + 510 + 28));
    }

    if (testAutoSendMode == false)
    {
      Joystick.sendState();
    }

    gCurrentStep++;
    if (gCurrentStep == (37 + 256 + 1024 + 128 + 510 + 28 + 360))
    {
      gNextTime = millis() + gcCycleDelta;
      gCurrentStep = 0;
    }
  }
}

Fihn:
Here's an example of joystick code from the library I'll be working with. Can you look at it and see if what we are doing may work with it?

You should be able to make it work...

If I'm looking at the code correctly would these be the pins it is looking for to read XYZ axis? Is this the same as the wire 9 as the input with diodes (input_pullup) and then the outputs in the matrix being a,b,c,d,e,f?

pinMode(A0, INPUT_PULLUP);
  pinMode(13, OUTPUT);