Simple toggle switch

Status
Not open for further replies.
Hi guys,

I have a very simple question i suppose, i want to make 2 single switches for gaming, that when you press them, one press "Y" on the computer the other one "E", everytime you turn the toggle switch, it should do it, so on/off both presses the letters
I can find a load of tutorials that looks like it, but nothing specific, can you help me find a tutorial for that, or what should the code be?

Hope you guys can help me!
 
I can't understand what you're up to... at least for me haha :)

Are you using a toggle switch or a button switch or two buttons and a toggle switch?

Here's my guess code routine:
Code:
// other side of button pins and toggle switch connect to GND
// we will be using a SPST-type toggle switch here (just 2 pins)

#define button1pin 0 // you can change this
#define button2pin 1 // to match what pin numbers
#define togglepin  2 // you want to use

#include <Bounce.h>
Bounce button1 = Bounce(button1pin, 10);
Bounce button2 = Bounce(button2pin, 10);

void setup () {
  pinMode(button1pin, INPUT_PULLUP);
  pinMode(button2pin, INPUT_PULLUP);
  pinMode(togglepin, INPUT_PULLUP);
}

void loop() {
  button1.update();
  button2.update();
  if(digitalRead(togglepin) == LOW) { // if toggle switch is off (LOW)
    if(button1.fallingEdge()) { // if button 1 is pressed
      Keyboard.print('Y'); // press Y
    }
    if(button2.fallingEdge()) { // if button 2 is pressed
      Keyboard.print('E'); // press E
    }
  }
  else { // if toggle switch is HIGH
    if(button1.fallingEdge() || button2.fallingEdge()) { // if either buttons are pressed
      Keyboard.set_key1(KEY_Y); // press both Y and E
      Keyboard.set_key2(KEY_E);
      Keyboard.send_now();
      delay(50); // you can change this delay
      Keyboard.set_key1(0); // release both Y and E (lift finger)
      Keyboard.set_key2(0);
      Keyboard.send_now();
    }
  }
}
 
Sorry for my bad english, i'll try to explain it more simple.

I have 2 Toggle Switches, I want to do like this:
pictures.jpg

One of them I want to press Y, whether i press the toggle switch ON/OFF, the other one should do exactly the same, just press E instead of Y

Hope that I made my self more clear :D
 

Attachments

  • 09276-1.jpg
    09276-1.jpg
    65.9 KB · Views: 152
Sorry at least to me, this is still a little unclear.... That is I can not tell from your diagrams and pictures, what this switch is? Is it a Single Pull double throw? That is does it have three contacts on the bottom? Where there is one common pin that gets connected to one of the two other pins when you press it to the on position and likewise connects to the other pin when you press toward the off?

If so, then You need to connect the common pin to one of the IO pins on your Teensy and the other two pins to ground.

Then @RevaLogics - code above should get you somewhere near... If assuming that your Teensy should act like a USB keyboard. As his code also tries to show you things like what should happen if both buttons are done at same time? Should there be any repeating? That is if you hold one of the switches on for lets say 5 seconds, should it only send one key press? Or should it do some form of logical repeat keys.... If so how fast?

To do this, you will also need to setup the Arduino IDE where you set the USB Type in the Tools menu to one of the types that includes Keyboard.

If however you meant for this to act like a Joystick button? then some of the code will be different... But the handling of the switches would be the same.
 
Hi KurtE,

Thank you for your reply, the contacts are SPST (Single pole, single throw), it's correct the toggle switches should act like a USB keyboard, it shall only send one key press, exactly like when you use a normal keyboard and press Y, i just want the toggle switch to press Y, one time, everytime i either turn the toggle switch ON/OFF.

Heres a photo of the toggle switchs bottom
toggleswitch.PNG

Hope it makes more sense :)
 
Last edited:
In that case, you can do as mentioned and hook up switches with one wire going to ground and another going to IO pin.
You can then use the bounce library as shown in previous code.

Again I have not used the Keyboard stuff myself so others may need to fill in...
But maybe something like:

Code:
uint32_t  key1_pressed_time = 0;   // Might used elapsedMillis
uint32_5 key2_pressed_time = 0; 
#define  KEY_RELEASE_TIME 50
void loop() {
  button1.update();
  button2.update();

  boolean key_updated = false;
  if (button1.fallingEdge() || button1.risingEdge()) {
    // Switch changed. 
    Keyboard.set_key1(KEY_Y); // press both Y and E
    key1_pressed_time = millis();
    key_updated = true;
  }

  if (button2.fallingEdge() || button2.risingEdge()) {
    // Switch changed. 
    Keyboard.set_key2(KEY_E); // press both Y and E
    key2_pressed_time = millis();
    key_updated = true;
  }

  if (key1_pressed_time && ((millis()-key1_pressed_time) >= KEY_RELEASE_TIME)) {
    Keyboard.set_key1(0); // release both Y and E (lift finger)
    key_updated = true;
    key1_pressed_time = 0;
  }

  if (key2_pressed_time && ((millis()-key2_pressed_time) >= KEY_RELEASE_TIME)) {
    Keyboard.set_key2(0); // release both Y and E (lift finger)
    key_updated = true;
    key2_pressed_time = 0;
  }

  if (key_updated) {
      Keyboard.send_now();
  }
}
Again I don't use the keyboard stuff and typed on fly so probably issues, but might hopefully give you a starting point?
 
Hi guys,

Thank you so much for your help!

I have tried the following code and it works! But only when i press the Toggle Switch on, how can i make type a Y, also when i press off?

Code:
#define button1pin 2 // you can change this to what pin you're using

#include <Bounce.h>
Bounce button1 = Bounce(button1pin, 10);

void setup () {
  pinMode(button1pin, INPUT_PULLUP);
}

void loop() {
  button1.update();
  
    if(digitalRead(button1pin) == LOW) { // if toggle switch is off (LOW)
     
        if(button1.fallingEdge()) { // if button 1 is pressed
          Keyboard.print('Y'); // press Y
        }

      }
}
 
Did you try the stuff I mentioned in previous post? Note: I did not put in the setup code as that should be the same as the code earlier in the thread...

Not sure why it is checking using digitalRead? In your code here it first checks to see if the level is low and then checks for falling edge... The falling edge code itself first checks if the previous call to button.update the level was high and this time low, so not sure why the extra test...

What happens if you simply do:
Code:
#define button1pin 2 // you can change this to what pin you're using

#include <Bounce.h>
Bounce button1 = Bounce(button1pin, 10);

void setup () {
  pinMode(button1pin, INPUT_PULLUP);
}

void loop() {
  button1.update();
  if(button1.fallingEdge() || button1.risingEdge()) { // if button 1 is pressed
    Keyboard.print('Y'); // press Y
  }
}
 
No i didn't i just used it as inspiration, and it was great! It works exactly how i want it now, thank you so much!

The final code was:

Code:
#define button1pin 2 // you can change this to what pin you're using

#include <Bounce.h>
Bounce button1 = Bounce(button1pin, 10);

void setup () {
  pinMode(button1pin, INPUT_PULLUP);
}

void loop() {
  button1.update();
  
    if(digitalRead(button1pin) == LOW) { // if toggle switch is off (LOW)
     
        if(button1.fallingEdge() || button1.risingEdge()) { // if button 1 is pressed
          Keyboard.print('Y'); // press Y
        }

      } else {
        if(button1.fallingEdge() || button1.risingEdge()) {
          Keyboard.print('Y'); // press Y
        }
      }
}

I put the if statement in to test if the digitalRead, was high, when i didn't had that if statement my contact acted weird.

But it works perfectly now!
 
I just have a minor problem, when i try to enter the game (Space Engineers) and use it as a button there, nothing happens, i tried to change the code to this:

Code:
#define button1pin 2 // you can change this to what pin you're using

#include <Bounce.h>
Bounce button1 = Bounce(button1pin, 10);

void setup () {
  pinMode(button1pin, INPUT_PULLUP);
  Keyboard.begin();
}

void loop() {
  button1.update();
  
    if(digitalRead(button1pin) == LOW) { // if toggle switch is off (LOW)
     
        if(button1.fallingEdge() || button1.risingEdge()) { // if button 1 is pressed
          Keyboard.press(KEY_Y);
          Keyboard.release(KEY_Y);
          }

      } else {
        if(button1.fallingEdge() || button1.risingEdge()) {
          Keyboard.press(KEY_Y);
          Keyboard.release(KEY_Y);
          }
      }
}

Shouldn't work then?

It's like it's working sometimes, seems like somekind of delay..
 
Last edited:
No, do not use digitalRead. The Bounce library does this for you.

First, test the hardware using a text editor where you can clearly see which characters it is sending. DO NOT test with your video game until you have confirmed the hardware is working correctly. Testing unknown hardware with the added complexity of a game will only make everything much harder.

You might need to increase the Bounce time, if you are getting more than 1 keystroke. You can tell if the Teensy is sending more than one by testing with the text editor and carefully watching how many chars appear as you move the switch.

Or you might need to add a brief delay between the press and release.
 
Hi Paul,

I removed the digitalRead, and changed the bouncetime to 30 instead of 10, and tried to put in a delay for 5 secods, and it works just perfect in Notepad, i've tried it in Counter-Strike and it works fine there.
But in Space Engineers and Alien: Isolation, it only works sometimes, if i push the button 20 times, it works 1-2 times, but in counter strike 20 times.

It doesnt make sense for me :D
 
why not create a state machine, where it flips the bool to only run once until the signal changes and do it again
 
Code:
bool toggle_sw; //global

void loop() {
  if ( toggle_sw == 0 && digitalReadFast(pin) == 1 ) {
    toggle_sw = 1;
    Keyboard.press(KEY_Y);
    Keyboard.release(KEY_Y);
    delay(10); // debounce prevent
  }
  if ( toggle_sw == 1 && digitalReadFast(pin) == 0 ) {
    toggle_sw = 0;
    Keyboard.press(KEY_Y);
    Keyboard.release(KEY_Y);
    delay(10); // debounce prevent
  }
}

quick untested but it fires only one time, this may be the easiest to understand from a new person view
 
Hi Paul,

I removed the digitalRead, and changed the bouncetime to 30 instead of 10, and tried to put in a delay for 5 secods, and it works just perfect in Notepad, i've tried it in Counter-Strike and it works fine there.
But in Space Engineers and Alien: Isolation, it only works sometimes, if i push the button 20 times, it works 1-2 times, but in counter strike 20 times.

It doesnt make sense for me :D

As I mentioned, I have not played much with keyboard stuff, but wonder if you may need a small delay between when you press the key and when you release the key...
i.e this code:
Code:
        if(button1.fallingEdge() || button1.risingEdge()) { // if button 1 is pressed
          Keyboard.press(KEY_Y);
          Keyboard.release(KEY_Y);
          }
To maybe something like:
Code:
        if(button1.fallingEdge() || button1.risingEdge()) { // if button 1 is pressed
          Keyboard.press(KEY_Y);
          delay(5);
          Keyboard.release(KEY_Y);
          }
 
Status
Not open for further replies.
Back
Top