Connection pushbuttons - SOLVED (solved again)

Hello , I have this code and axies work perfectly, but not how to connect buttons to Arduino Leonardo.

thanks

/*
Arduino Leonardo Joystick!

*/


JoyState_t joySt;

void setup()
{
	pinMode(13, OUTPUT);


	joySt.xAxis = 0;
	joySt.yAxis = 0;
	joySt.zAxis = 0;
	joySt.xRotAxis = 0;
	joySt.yRotAxis = 0;
	joySt.zRotAxis = 0;
	joySt.throttle = 0;
	joySt.rudder = 0;
	joySt.hatSw1 = 0;
	joySt.hatSw2 = 0;
	joySt.buttons = 0;

}


void loop()
{



	joySt.xAxis = random (255);
	joySt.yAxis = random(255);
	joySt.zAxis = random(255);
	joySt.xRotAxis = random(255);
	joySt.yRotAxis = random(255);
	joySt.zRotAxis = random(255);
	joySt.throttle = random(255);
	joySt.rudder = random(255);

	joySt.throttle++;


	joySt.buttons <<= 1;
	if (joySt.buttons == 0)
		joySt.buttons = 1;

	joySt.hatSw1++;
	joySt.hatSw2--;

	if (joySt.hatSw1 > 8)
		joySt.hatSw1 = 0;
	if (joySt.hatSw2 > 8)
		joySt.hatSw2 = 8;

	delay(100);

	if (joySt.throttle > 127)
		digitalWrite(13, HIGH);
	else
		digitalWrite(13, LOW);


	// Call Joystick.move
	Joystick.setState(&joySt);

}

but not how to connect buttons to Arduino Leonardo.

What do you mean by this?

You connect push buttons between input and ground and enable the internal pull up resistor.

Hi,
We need all of your code to help you and information on what you are connecting to the Leonardo, as well as what you want it to do.

Tom...... :slight_smile:

It's dead simple:

Step 1: Find the correct orientation of the button. Do this with a multimeter and set the multimeter to beep mode. When you connect RED and BLACK it should beep. Now find two pins on the button that beep when the button is pressed. This is usually diagonal from each other.

Now you should know which two pins on the button are connected when creating a press.

Step 2: Wire in the button to the Arduino. You can choose to switch 5v with the switch or ground. I use ground. That means you put ground on one pin of the button and the other goes to input pin on your Arduino.

Step 3: Measure button pressed in code on the Arduino.

When you put something on a pin the Arduino will register it. If you release the button however, the pin will not be connected. This state (nothing attached to pin) is called 'floating'. Floating will give invalid results (sometimes 1, sometimes 0) and can be fixed with a resistor.

You need to put a resistor on your input pin and then connect 5v to the resistor. In your code the pin will now ALWAYS be 1. Also put the ground that comes from the button onto the 5v that goes to resistor. What will happen is called pulling upwards with a resistor. When the button is open (not pressed) the value will be floating. In this case the 5v goes through the resistor to the input pin and will read 1. When you press the button you will expose GROUND to the 5V and because of that all of the 5v will go to ground leaving the pin 0.

The cool thing is you don't need to use a resistor because the Arduino has resistors built in on each pin. You don't even need to connect the 5v to make it 1 by default. Arduino also does this:

Just register you pins like so:

INPUT_PULLUP

This is my working sketch:

// SparkFun Pro Micro 5v/16mhz 
// Board: "SparkFun Pro Micro 5v/16mhz (Joystick HID)"
// Programmer: AVRISP MkII

const int buttonPins[] = {2, 3, 4, 5, 6, 7};
const int size = sizeof(buttonPins) / sizeof(int);
const int pollRate = 50;

long m = millis();
JoyState_t joyState;

void setup() {        
  for (int i = 0; i < size; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);    

  m = millis();
}

void loop() {
  if (millis() - m > pollRate)
  {
    m = millis();
    
    joyState.buttons = 0;
    
    for (int i = 0; i < size; i++) {
       int state = digitalRead(buttonPins[i]); 
       if (state == LOW) 
         joyState.buttons += 1 << i;
    }   
     
    Joystick.setState(&joyState);
  }
}

As for the circuit: Connect button to ground and pin, that's all.

If you are using a Leonardo then you need to include the line:-

while (!Serial) ; // wait for serial

In your setup function.

Hi Mike,

I'm not doing that on my Leonardo's, could you elaborate? Also this sketch doesn't rely on Serial because it sends HID reports (but I'm not sure if it uses Serial internally)

I'm not doing that on my Leonardo's, could you elaborate?

I was talking to the OP who is using a Leonardo. He says so in the first post. If you are not using a Leonardo or a Micro then there is no need for that line. It does no harm having it in but it is not needed.

I am using a 32u4 (Leonardo) and I am not doing that. Why does the Leonardo need it as opposed to 328p's?

Why does the Leonardo need it as opposed to 328p's?

RTFM

Since the boards do not have a dedicated chip to handle serial communication, it means that the serial port is virtual -- it's a software routine, both on your operating system, and on the board itself. Just as your computer creates an instance of the serial port driver when you plug in any Arduino, the Leonardo/Micro creates a serial instance whenever it runs its bootloader. The board is an instance of USB's Connected Device Class (CDC) driver.

To work around this, you can check to see if the serial port is open after calling Serial.begin() like so:

Serial.begin(9600);
// while the serial stream is not open, do nothing:
while (!Serial) ;

http://www.arduino.cc/en/Guide/ArduinoLeonardoMicro?from=Guide.ArduinoLeonardo

charlesdavis018:
How you can say that it is running software if its don't have important button which is not implemented by you till..

What important button?

Grumpy_Mike:
What do you mean by this?

You connect push buttons between input and ground and enable the internal pull up resistor.

I mean , how to make connections on the board , as the sketch allows me 32 buttons

I connect according to the diagram:

But do not recognize keystrokes in windows control panel

TomGeorge:
Hi,
We need all of your code to help you and information on what you are connecting to the Leonardo, as well as what you want it to do.

Tom...... :slight_smile:

This is all code, no more. Right now they are just connected the pots , central pin A0 to A5, and the other two pins to GND and + 5V

Edit: theoretically , with the code of the first post , should recognize the beats of the 32 buttons, but not how to make connections on the board to recognize them

Sorry for my English , are translations of google

But do not recognize keystrokes in windows control panel

You have to write code to do that.
This is some code I wrote to generate phrases on a key press. They are meant to be funny but I suspect it will not translate into your language.

// Buzz phrase generator - Mike Cook May 2012
// For the Arduino Leonardo
// Ground pin 2 for a buzz word phrase to be typed in directly into your report

// add extra words in before the "0"
String word1[] = { "integrated ", "synchronised ", "responsive ", "parallel ", "balanced ", "total ", "functional ", "user friendly "
                   "optimal ", "compatible ","new ", "64-bit ","synergetic ","*"};
String word2[] = { "managerial ", "organisational ", "monitored ", "reciprocal ", "digital ", "logistical ", "transitional ",
                   "incremental ", "fifth generational ", "lifestyle ", "aspirational ", "*"};
String word3[] = { "policy ", "options ", "flexibility ", "capability ", "mobility ", "programming ", "concept ", "time phase ",
                    "projection ", "hardware ", "software ", "contingency ","*" };
  
int numberOfWords1=0,numberOfWords2=0,numberOfWords3 =0;
void setup() {
  // make pin 2 an input and turn on the 
  // pullup resistor so it goes high unless
  // connected to ground:
 pinMode(2, INPUT_PULLUP);
  Keyboard.begin();
  // find out how many words are in each array
  while(word1[numberOfWords1] != "*") numberOfWords1++;
  numberOfWords1--; // to make random number call correct
  while(word1[numberOfWords2] != "*") numberOfWords2++;
  numberOfWords2--;
  while(word1[numberOfWords3] != "*") numberOfWords3++;
  numberOfWords3--;
}

void loop(){
  while(digitalRead(2) == HIGH) { 
    // do nothing until pin 2 goes low
    delay(50);
    random(0,100); // just keep the random number ticking over
  }
  delay(100);
  
  Keyboard.print(word1[random(0,numberOfWords1)]);
  Keyboard.print(word2[random(0,numberOfWords2)]);
  Keyboard.print(word3[random(0,numberOfWords3)]);

// do nothing:
  while(digitalRead(2) == LOW);
  delay(100);
  while(digitalRead(2) == LOW); // get rid of any bounce
  delay(100);
}

how to make connections on the board , as the sketch allows me 32 buttons

You can not use 32 buttons without any extra hardware. You can only have 19, just repeat that wiring but instead of pin 2 wire each button to a different input pin from 0 to 13 and from A0 to A5. The Analogue inputs can be used as digital inputs in exactly the same way.

As this is a Leonardo you can happily use pins 0 & 1, you can not use these on a Uno.

To get more switches you need a shift register, you cascade them and have 8 buttons per shift register. See:-

Grumpy_Mike:
..... just repeat that wiring but instead of pin 2 wire each button to a different input pin from 0 to 13 and from A0 to A5.

Various questions:

  • The pushbutton have 2 pins, one pin from 0 to 13, and the another pin to GND, correct?
    I'll use this type button :

  • It is necessary include the resistor, or i can use the pull-up resistor?
  • That changes would have to enter in my code to recognize keystrokes making connections as you explain me?

THX

  1. Yes, connect it to GND and PIN0..13

  2. No, you can use the internal pull-up!

  3. Look at my example in post 3. It does exactly what you want!! All you need to change are the pins that the buttons are connected to. Change this line:

const int buttonPins[] = {2, 3, 4, 5, 6, 7};

to whatever pins you have connected. The sketch does the INPUT_PULLUP in the setup so literally don't change anything except the line above.

On Windows you should see a connected HID gamepad if you go to "View Devices and Printers". Open the properties and click advanced to see if the button pressed are indeed sent to Windows.

SOLVED !

I have mixed your code Fexduino with mine and now works perfectly , I have 6-axis and 14 buttons.

Thanks everyone for your help.

This is the code:

//Quadrant 6 ejes y 14 botones
//Ejes de pin A0 a A5
//Botones desde pin 0 a 13

const int buttonPins[] = {0, 1};
const int size = sizeof(buttonPins) / sizeof(int);
const int pollRate = 50;

long m = millis();

JoyState_t joySt;

void setup()
{        
        pinMode(13, OUTPUT);


	joySt.xAxis = 0;
	joySt.yAxis = 0;
	joySt.zAxis = 0;
	joySt.xRotAxis = 0;
	joySt.yRotAxis = 0;
	joySt.zRotAxis = 0;
	joySt.throttle = 0;
	joySt.rudder = 0;
	joySt.hatSw1 = 0;
	joySt.hatSw2 = 0;
	joySt.buttons = 0;

  for (int i = 0; i < size; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);    

  m = millis();
}

void loop() {
  if (millis() - m > pollRate)
  {
    m = millis();
    
    joySt.buttons = 0;
    joySt.xAxis = analogRead(A0) >>2;
    joySt.yAxis = analogRead(A1) >>2;
    joySt.zAxis = analogRead (A2) >>2;
    joySt.xRotAxis = analogRead (A3) >>2;
    joySt.yRotAxis = analogRead (A4) >>2;
    joySt.throttle = analogRead (A5) >>2;
    
    for (int i = 0; i < size; i++) {
       int state = digitalRead(buttonPins[i]); 
       if (state == LOW) 
         joySt.buttons += 1 << i;
    }   
     
     delay(50);

	if (joySt.throttle > 127)
		digitalWrite(13, HIGH);
	else
		digitalWrite(13, LOW);

    Joystick.setState(&joySt);
  }
}

Awesome. Thanks for letting us know and posting your updated sourcecode, that way other googlers and community members can learn from it!

Hi again....

I continued working in my project, now i want to use some rotary encoders like a buttons, when i turn to right may be pressed one button, and when i turn to left another button must be pressed. I found a lot of codes about the rotary encoders, but I do not know how to integrate these instructions in my code...

but I do not know how to integrate these instructions in my code

Mostly these involve interrupts and interrupt service routines ( ISR ) so read up on that first. This works in the background so your code simply uses the value of the variables altered by these routines to make decisions. I think all the examples you will see will increment or decrement a count, you don't want to do that. All you want to do is to set a byte variable to 1 if you were going to increment and -1 if you were going to decrement. You use that variable in your code. Once you have seen it ( being a 1 or -1 ) and have taken action in your code you set this variable to 0 so you make sure your code only take notice of it when the encoder has changed.

I would like to ask for your help with the code , as my knowledge is null and not how to do it

I have given you help. Are you saying you want me to do it for you?

I can help but you have to do some of the work. Start off by posting your code so far including the rotary encoder example you think you should use.