I'm trying to code a switch panel for microsoft flight simulator. FSX for those who know about it. I have an on/off switch. Its wired to GND and D3. I can get it to turn the landing lights on by flipping the switch. But then the switch just stays on until I flip it off. At which point the computer recognizes the button is no longer pressed. BUT the landing lights stay on.
Obviously, without another button being pressed to turn the lights off the simulator doesn't know I want that to happen.
So, is there a way to code the switch so that when it goes from on to off the computer can recognize that it needs to basically hit the button again? I know I could probably just buy a momentary switch but that isn't really something I want to do because I already have this switch and if I can get it working then all the better.
Take a look at the StateChangeDetection example in the IDE
You need to detect and act when the input becomes a particular state rather than when it is a particular state
Implement the switch as a joystick button, then you don't have this problem.
I'll take a closer look. I've looked at the example before. I have a bit of code that I have a question on.
// Read pin values
for (int index = 0; index < 13; index++)
{
int currentButtonState = !digitalRead(index + pinToButtonMap);
if (currentButtonState != lastButtonState[index])
{
Joystick.setButton(index, currentButtonState);
lastButtonState[index] = currentButtonState;
}
}
I'm wondering what index + pinToButtonMap means. Specifically the index part. I'm going to assume that if I change that code to the following it will do the trick?
// Read pin values
for (int index = 0; index < 13; index++)
{
int currentButtonState = !digitalRead(index + pinToButtonMap);
if (currentButtonState != lastButtonState[index])
{
// if the state has changed, increment the counter
if (currentButtonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
{
Joystick.setButton(index, currentButtonState);
lastButtonState[index] = currentButtonState;
}
I think I'm missing something though because I'm not trying to print on or off, I'm trying to actually make it happen in the sim. So I'm confused at what to do with the Serial.print parts for that purpose.
You have a switch or a pushbutton?
Seems like the computer expects you to use a momentary push button, while you went for a toggle switch. No worries, you can have the arduino detect the change in state of the switch, instead of the state itself. This will send a pulse to the computer everytime you toggle the switch, which is probably the behaviour you want. Just check the StateChangeDetection example.
Note that probably, when you start the game with the lights on vs off, the behaviour of the switch will be reversed. Because now, there is no way for the computer to know which side the switch is flipped.
Then your whole button-test-code becomes something like:
Joystick.setButton(index, !digitalRead(index + pinToButtonMap));
You can check the button state in the m$ joystick calibration dialog (at least it was there the last time I used m$ on xp).
Oh, another point: If the state is lost when you begin the simulation, it's most likely one of these tiny bugs: you need to toggle all buttons on simultion begin. Same on XPlane.
zwieblum:
Then your whole button-test-code becomes something like:
Joystick.setButton(index, !digitalRead(index + pinToButtonMap));
You can check the button state in the m$ joystick calibration dialog (at least it was there the last time I used m$ on xp).
Oh, another point: If the state is lost when you begin the simulation, it's most likely one of these tiny bugs: you need to toggle all buttons on simultion begin. Same on XPlane.
Hope I'm understanding this right. I'm still learning. When you say the code becomes that are you saying I need to change the line in the code? To this?
// Read pin values
for (int index = 0; index < 13; index++)
{
int currentButtonState = !digitalRead(index + pinToButtonMap);
if (currentButtonState != lastButtonState[index])
{
Joystick.setButton(index, !digitalRead(index + pinToButtonMap));
}
}
for (int index = 0; index < 13; index++) {
Joystick.setButton(index, !digitalRead(index + pinToButtonMap));
}
Thanks, I changed that in my code. I think I understand it a little better now. But after testing it I still have the same problem. When I flip the switch on I can get the landing lights to turn on. But when I flip it off again it doesn't change anything.
Here is my entire code. What am I doing wrong here?
// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// Ground digital pins 9, 10, 11, and 12 to press the joystick
// buttons 0, 1, 2, and 3.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
// Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------
#include <Joystick.h>
Joystick_ Joystick;
void setup() {
// Initialize Button Pins
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
// Initialize Joystick Library
Joystick.begin();
}
// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 3;
// Last state of the button
int lastButtonState[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
void loop() {
// Read pin values
for (int index = 0; index < 13; index++)
{
Joystick.setButton(index, !digitalRead(index + pinToButtonMap));
}
delay(50);
}
What happen when you do: ON->OFF->ON->OFF?
zwieblum:
What happen when you do: ON->OFF->ON->OFF?
It turns them on, then nothing, then OFF, then nothing.
So I know I could just flip the switch a few times. But my goal is realism in the Sim. On should mean on and off should mean off.
Well, then you have to configure your sim correctly. It's configured to use the joysick bottons as pushbottons to change state - don't know how to do it in FSX.
// Initialize Button Pins
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
Can be replaced by:
for (byte i=3; i<14; i++)
pinMode(i, INPUT_PULLUP);
TimMJN:
Seems like the computer expects you to use a momentary push button, while you went for a toggle switch. No worries, you can have the arduino detect the change in state of the switch, instead of the state itself. This will send a pulse to the computer everytime you toggle the switch, which is probably the behaviour you want. Just check the StateChangeDetection example.
Note that probably, when you start the game with the lights on vs off, the behaviour of the switch will be reversed. Because now, there is no way for the computer to know which side the switch is flipped.
Can you please explain how to get the state change code in the example to send that pulse to the computer as a button push? In the code it simply prints on or off rather than actually sending a pulse the Sim would recognize as a button push.
Do I just delete the print part out of the code, or am I missing something else here?
This won't solve your problem: switches on the panel and state of sim will always be out of sync.
zwieblum:
This won't solve your problem: switches on the panel and state of sim will always be out of sync.
Sorry, I just don't quite understand why that is. I thought that sending a pulse when the switch changes it's state from HIGH to LOW and vise versa is what we have been talking about all along.
It makes sense to me that when the switch is flipped "on" the computer recognizes it as a continuous holding down of the "button" without the state change code. But with a state change code wouldn't it be a single pulse when it is turned "on" and then another when turned "off" like the click of a momentary button rather than a continuous holding down of the "button" for when it's on?
So I'm not quite understanding why such an option wouldn't work. Unless I'm wrong and doing a state change code doesn't send a pulse when it is turned off?
The state change you'll get when reacting to on/off or off/on events on the flip switch is 2x button press. The sim does not know if the switch is in ON or OFF position, it just changes state.
So on one occation you get:
switch off->on --> lights on && switch on->off --> lights off
the other day you get:
switch off->on --> lights off && switch on->off --> lights on
Reson is: your sim is configured in a way tht the joystick buttons are momentary swotches, not toggle switches.
zwieblum:
The state change you'll get when reacting to on/off or off/on events on the flip switch is 2x button press. The sim does not know if the switch is in ON or OFF position, it just changes state.
So on one occation you get:
switch off->on --> lights on && switch on->off --> lights off
the other day you get:
switch off->on --> lights off && switch on->off --> lights on
Reson is: your sim is configured in a way tht the joystick buttons are momentary swotches, not toggle switches.
So basically what you are saying is that with the state change the switch sends 1 pulse when turned on and 1 pulse when turned off? Isn't that the same thing a momentary switch would do?
Or is the switch sending a continuous pulse (as if a button is being held down) when turned on and then nothing when turned off?
I get that the Sim expects a button push, I am just having a hard time understanding why that would mess it up.