Communication between development boards and Air Manager

Working on a instrument project or just finished a project? Show it to others!

Moderators: russ, Ralph

Post Reply
Message
Author
User avatar
WillemijnL
Posts: 107
Joined: Sat Jan 30, 2016 1:14 pm

Communication between development boards and Air Manager

#1 Post by WillemijnL »

Sim Innovations is working on hardware support for the Raspberry Pi. With help from Sim Innovations, I am creating libraries for other development boards which can communicate with Air Manager. The libraries will connect to the Air manager plugin, so it makes communication possible with FSX, Prepar3d and X-Plane. Also inter-instrument communication will be supported.

As far as possible the functions in the libraries will be identical to the Air Manager API you are familiar with. I'm now working on Arduino libraries. There will be four Arduino libraries. One general libray and three libraries supporting Arduino Ethernet, Arduino Ethernet2 and Arduino Wifi. You should use the general library and one of the others, depending on you hardware.

The libraries will have an "Air Manager" class for the communication with Air Manager and at first two classes supporting hardware controls: a switch class for pushbuttons and switches and a rotary encoder class. These control classes and the "Air Manager" class work seamless together.

The libraries will support three levels of programming, because every method/function is public:
- High level: setup Air Manager and your controls and let it work by putting one line for each control in the loop().
- Mid level: take some control and let the library do the sending automatically.
- Low level: take full control and do everything yourself.

I'm developing on the new Teensy 3.6 with a WizNet W5500 ethernet module connected. The Ethernet2 shield has also a W5500 chip, so I can use the Arduino Ethernet2 library. For Wifi support I'm testing with the Sparkfun ESP32 Thing. The new ESP32 processor from Espressif is quite powerful as the Teensy 3.6 is. And finally I'm trying the libraries on the Arduino Mega with a Arduino2 shield. The Arduino Mega has limited capacity, but for now it is working on the Mega.

The first version of the libraries will support X-Plane commands, FSX/P3D events and Air Manager commands (inter-instrument). X-Plane commands and Air Manager commands are already implemented. I'm now implementing FSX/P3D events. After that I have to test the whole thing and create example sketches. Still quite a lot of work to do, so it will take a couple of weeks to finish the first version.

The second version will support sending datarefs and variables. In version 3 I hope to implement dataref/variable subscriptions. That will be the most difficult part. I have also plans to translate the libraries to MicroPython and Python to support a larger range of development boards.

JackZ
Posts: 2267
Joined: Mon Feb 22, 2016 1:02 pm

Re: Communication between development boards and Air Manager

#2 Post by JackZ »

Wow...what an interesting program! Just add FSuipc offset interface, and you will definitely be the King of the Hill ;) !

Can't wait to get my hands dirty, Willemjin, if you ever need some help with Arduino scripts or beta testing, please let me know...I have two Arduino Mega and the Ethernet Shield

Really impressed, congratulations!

Jacques
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

Aviador_Virtual
Posts: 11
Joined: Tue Nov 01, 2016 2:01 pm

Re: Communication between development boards and Air Manager

#3 Post by Aviador_Virtual »

Nice to hear this.. congrats for your work.
My home cockpit uses 2 Arduino Mega talking thru Ethernet, now using Svglobe (Vlad) plugin and libraries for Xplane mixed with my own code for some special functions.
Now working on the code for a 3rd Arduino for the control loader, hardware part already done, controling motors using Sabertooth drivers.
Using Air Manager on separate pc which draws instruments on 2X 17" monitors.
If need beta tester i can help.

Good luck with your project

User avatar
WillemijnL
Posts: 107
Joined: Sat Jan 30, 2016 1:14 pm

Re: Communication between development boards and Air Manager

#4 Post by WillemijnL »

It's time for a little update. I develop the Arduino-libraries on a Teensy 3.6. When I finished the code and did the first test, everything worked fine. When I compiled the code for the two other boards, I ran into a problem. Although using the same Arduino IDE, the compilers seemed to be a little different, so I got compiler errors. I have rewritten a part of the code, to be compatible whith most Arduino-like developement boards. I'm now starting alpha testing. For that I'll create three setups for the three boards I want to test with, each with 3 rotary encoders, 3 toggleswitches and 4 pushbuttons, so I'm able to compare them. I've done already a test with the Teensy 3.6 and X-Plane and it works. Now I created a copy of the sketch for FSX. This also works. I'm not so familiar with FSX but I found out that not all things can be done with FSX events. The taxi lights can only be switched by a toggle event. Not very suitable when you're using a toggleswitch. Other lights have an on and off event but the taxi lights not. I found a FSX variable to switch the taxi lights on and off with a toggleswitch, but unfortunately variables are not suported in version one of the library.

Here is a preview of sketches using the libraries. These sketches I use for testing.

Sketch for Teensy 3.6 with WizNet W5500 ethernet module and X-Plane:

Code: Select all

// Sketch for Teensy 3.6 with WizNet W5500 ethernet module

#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>

#include <SBxAirManagerEthernet2.h>
#include <SBxAmSwitch.h>
#include <SBxAmRotaryEncoder.h>

// MAC address: DE-75-80-6F-C3-C7
uint8_t mac[6] = {0xDE,0x75,0x80,0x6F,0xC3,0xC7};

// Flightsim ip address
IPAddress flightsimIp = IPAddress(192,168,2,3);

int statusLEDPin = 32;
int ethernetResetPin = 9;

/*************************************************************
 * Declare Air Manager
 * When also using interinstrumant communications, you have to begin
 * also interinstrument communication. Example:
 *   SBxAirManager airManagerXPL;
 *   SBxAirManager airManagerAM;
 *************************************************************/
SBxAirManager airManagerXPL;

/*************************************************************
 * Declare controles
 * > SBxAmSwitch(pin number, use pullup resistor)
 * > SBxAmRotaryEncoder(left pin number, right pin number, use pullup resistors)
 *************************************************************/
// pushbuttons
SBxAmSwitch apAutopilotButton(24, true);
SBxAmSwitch apFlightDirectorButton(25, true);
SBxAmSwitch apNavigationButton(26, true);
SBxAmSwitch apAutoThrottleButton(27, true);

// switches
SBxAmSwitch taxiLightSwitch(28, true);
SBxAmSwitch landingLightSwitch(29, true);
SBxAmSwitch landingGearSwitch(30, true);

// rotary encoders
SBxAmRotaryEncoder airSpeedEncoder(0, 1, true);
SBxAmSwitch airSpeedEncoderButton(2, true);
SBxAmRotaryEncoder altitudeEncoder(3, 4, true);
SBxAmSwitch altitudeEncoderButton(5, true);
SBxAmRotaryEncoder headingEncoder(6, 7, true);
SBxAmSwitch headingEncoderButton(8, true);



void setup() {
  pinMode(statusLEDPin,OUTPUT);
  digitalWrite(statusLEDPin, LOW); // status LED off

  /*************************************************************
   * Specify commands
   * > SBxAmSwitch.setXPLSwitchOnCommand(command[, type])
   * > SBxAmSwitch.setXPLSwitchOffCommand(command[, type])
   * > SBxAmRotaryEncoder.setXPLLeftTurnCommand(command[, type])
   * > SBxAmRotaryEncoder.setXPLRightTurnCommand(command[, type])
   * Default type: ONCE
   *************************************************************/
  // pushbuttons
  apAutopilotButton.setXPLSwitchOnCommand("sim/autopilot/servos_toggle");
  apFlightDirectorButton.setXPLSwitchOnCommand("sim/autopilot/fdir_toggle");
  apNavigationButton.setXPLSwitchOnCommand("sim/autopilot/NAV");
  apAutoThrottleButton.setXPLSwitchOnCommand("sim/autopilot/autothrottle_toggle");

  // switches
  taxiLightSwitch.setXPLSwitchOnCommand("sim/lights/taxi_lights_on");
  taxiLightSwitch.setXPLSwitchOffCommand("sim/lights/taxi_lights_off");
  landingLightSwitch.setXPLSwitchOnCommand("sim/lights/landing_lights_on");
  landingLightSwitch.setXPLSwitchOffCommand("sim/lights/landing_lights_off");
  landingGearSwitch.setXPLSwitchOnCommand("sim/flight_controls/landing_gear_up");
  landingGearSwitch.setXPLSwitchOffCommand("sim/flight_controls/landing_gear_down");
 
  // rotary encoders
  airSpeedEncoder.setXPLLeftTurnCommand("sim/autopilot/airspeed_down");
  airSpeedEncoder.setXPLRightTurnCommand("sim/autopilot/airspeed_up");
  airSpeedEncoderButton.setXPLSwitchOnCommand("sim/autopilot/airspeed_sync");

  altitudeEncoder.setXPLLeftTurnCommand("sim/autopilot/altitude_down");
  altitudeEncoder.setXPLRightTurnCommand("sim/autopilot/altitude_up");
  altitudeEncoderButton.setXPLSwitchOnCommand("sim/autopilot/altitude_sync");

  headingEncoder.setXPLLeftTurnCommand("sim/autopilot/heading_down");
  headingEncoder.setXPLRightTurnCommand("sim/autopilot/heading_up");
  headingEncoderButton.setXPLSwitchOnCommand("sim/autopilot/heading_sync");

  // start ethernet
  resetEthernetModule();
  Ethernet.begin(mac);

  /*************************************************************
   * Start Air Manager communication
   * > SBxAirManager.begin(flightsim IP address , flightsim type)
   * > flightsim type: XPlane, FSX, Prepar3d, AirManager
   * 
   * When you want to use interinstrumant communications, you have
   * also to begin interinstrument communication. Example:
   *   airManagerXPL.begin(flightsim IP address, XPLANE)
   *   airManagerAM.begin(flightsim IP address, AirManager)
   *************************************************************/
  // start Air Manager communication
  airManagerXPL.begin(flightsimIp, XPlane);   // > SBxAirManager.begin(IP address, flightsim type) > flightsim type: XPlane, FSX, Prepar3d, AirManager

  delay(1500);
  syncFlightSim(); // sets status LED on

} //** end setup()



void loop() {
  // pushbuttons
  airManagerXPL.update(apAutopilotButton);
  airManagerXPL.update(apFlightDirectorButton);
  airManagerXPL.update(apNavigationButton);
  airManagerXPL.update(apAutoThrottleButton);

  // switches
  airManagerXPL.update(taxiLightSwitch);
  airManagerXPL.update(landingLightSwitch);
  airManagerXPL.update(landingGearSwitch);

  // rotary encoders
  airManagerXPL.update(airSpeedEncoder);
  airManagerXPL.update(airSpeedEncoderButton);
  airManagerXPL.update(altitudeEncoder);
  airManagerXPL.update(altitudeEncoderButton);
  airManagerXPL.update(headingEncoder);
  airManagerXPL.update(headingEncoderButton);

} //** end loop()



void syncFlightSim() {
  // Send state of switches to sync flight simulator
  digitalWrite(statusLEDPin, LOW); // status LED off
  taxiLightSwitch.update();
  airManagerXPL.send(taxiLightSwitch);
  landingLightSwitch.update();
  airManagerXPL.send(landingLightSwitch);
  landingGearSwitch.update();
  airManagerXPL.send(landingGearSwitch);
  delay(500);
  digitalWrite(statusLEDPin, HIGH); // status LED on
}

void resetEthernetModule() {
  // Reset WIZnet W5500 ethernet module before use
  pinMode(ethernetResetPin, OUTPUT); // connected to reset pin
  digitalWrite(ethernetResetPin, LOW);
  delay(1);
  digitalWrite(ethernetResetPin, HIGH);
  delay(450);
}

Sketch for Teensy 3.6 with WizNet W5500 ethernet module and FSX:

Code: Select all

// Sketch for Teensy 3.6 with WizNet W5500 ethernet module

#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>

#include <SBxAirManagerEthernet2.h>
#include <SBxAmSwitch.h>
#include <SBxAmRotaryEncoder.h>

// MAC address: DE-75-80-6F-C3-C7
uint8_t mac[6] = {0xDE,0x75,0x80,0x6F,0xC3,0xC7};

// Flightsim ip address
IPAddress flightsimIp = IPAddress(192,168,2,3);

int statusLEDPin = 32;
int ethernetResetPin = 9;

/*************************************************************
 * Declare Air Manager
 * When also using interinstrumant communications, you have to begin
 * also interinstrument communication. Example:
 *   SBxAirManager airManagerFSX;
 *   SBxAirManager airManagerAM;
 *************************************************************/
SBxAirManager airManagerFSX;

/*************************************************************
 * Declare controles
 * > SBxAmSwitch(pin number, use pullup resistor)
 * > SBxAmRotaryEncoder(left pin number, right pin number, use pullup resistors)
 *************************************************************/
// pushbuttons
SBxAmSwitch apAutopilotButton(24, true);
SBxAmSwitch apFlightDirectorButton(25, true);
SBxAmSwitch apNavigationButton(26, true);
SBxAmSwitch apAutoThrottleButton(27, true);
SBxAmSwitch fsSyncButton(31, true);           // button to manually sync controls to flight simulator

// switches
SBxAmSwitch taxiLightSwitch(28, true);
SBxAmSwitch landingLightSwitch(29, true);
SBxAmSwitch landingGearSwitch(30, true);

// rotary encoders
SBxAmRotaryEncoder airSpeedEncoder(0, 1, true);
SBxAmSwitch airSpeedEncoderButton(2, true);
SBxAmRotaryEncoder altitudeEncoder(3, 4, true);
SBxAmSwitch altitudeEncoderButton(5, true);
SBxAmRotaryEncoder headingEncoder(6, 7, true);
SBxAmSwitch headingEncoderButton(8, true);



void setup() {
  pinMode(statusLEDPin,OUTPUT);
  digitalWrite(statusLEDPin, LOW); // status LED off

  /*************************************************************
   * Specify events
   * > SBxAmSwitch.setFSXSwitchOnCommand(event[, value])
   * > SBxAmSwitch.setFSXSwitchOffCommand(event[, value])
   * > SBxAmRotaryEncoder.setFSXLeftTurnCommand(event[, value])
   * > SBxAmRotaryEncoder.setFSXRightTurnCommand(event[, value])
   *************************************************************/
  // pushbuttons
  apAutopilotButton.setFSXSwitchOnEvent("AP_MASTER");
  apFlightDirectorButton.setFSXSwitchOnEvent("TOGGLE_FLIGHT_DIRECTOR");
  apNavigationButton.setFSXSwitchOnEvent("AP_LOC_HOLD_ON");
  apAutoThrottleButton.setFSXSwitchOnEvent("AUTO_THROTTLE_ARM");
  //fsSyncButton: no events needed

  // switches
  taxiLightSwitch.setFSXSwitchOnEvent("TOGGLE_TAXI_LIGHTS");
  taxiLightSwitch.setFSXSwitchOffEvent("TOGGLE_TAXI_LIGHTS");
  landingLightSwitch.setFSXSwitchOnEvent("LANDING_LIGHTS_ON");
  landingLightSwitch.setFSXSwitchOffEvent("LANDING_LIGHTS_OFF");
  landingGearSwitch.setFSXSwitchOnEvent("GEAR_SET", 0);
  landingGearSwitch.setFSXSwitchOffEvent("GEAR_SET", 1);
 
  // rotary encoders
  airSpeedEncoder.setFSXLeftTurnEvent("AP_SPD_VAR_DEC");
  airSpeedEncoder.setXPLRightTurnCommand("AP_SPD_VAR_INC");
  airSpeedEncoderButton.setFSXSwitchOnEvent("AP_PANEL_SPEED_HOLD_TOGGLE");

  altitudeEncoder.setFSXLeftTurnEvent("AP_ALT_VAR_DEC");
  altitudeEncoder.setFSXRightTurnEvent("AP_ALT_VAR_INC");
  altitudeEncoderButton.setFSXSwitchOnEvent("AP_ALT_HOLD");

  headingEncoder.setFSXLeftTurnEvent("???");
  headingEncoder.setFSXRightTurnEvent("???");
  headingEncoderButton.setFSXSwitchOnEvent("AP_PANEL_HEADING_HOLD");

  // start ethernet
  resetEthernetModule();
  Ethernet.begin(mac);

  /*************************************************************
   * Start Air Manager communication
   * > SBxAirManager.begin(flightsim IP address , flightsim type)
   * > flightsim type: XPlane, FSX, Prepar3d, AirManager
   * 
   * When you want to use interinstrumant communications, you have
   * also to begin interinstrument communication. Example:
   *   airManagerFSX.begin(flightsim IP address, FSX)
   *   airManagerAM.begin(flightsim IP address, AirManager)
   *************************************************************/
  airManagerFSX.begin(flightsimIp, FSX);

  delay(1500);
  syncFlightSim(); // sets status LED on

} //** end setup()



void loop() {
  // pushbuttons
  airManagerFSX.update(apAutopilotButton);
  airManagerFSX.update(apFlightDirectorButton);
  airManagerFSX.update(apNavigationButton);
  airManagerFSX.update(apAutoThrottleButton);

  fsSyncButton.update();
  if (fsSyncButton.hasChanged()) {
    if (fsSyncButton.getState() == HIGH) syncFlightSim(); // sync on button release
  }

  // switches
  airManagerFSX.update(taxiLightSwitch);
  airManagerFSX.update(landingLightSwitch);
  airManagerFSX.update(landingGearSwitch);

  // rotary encoders
  airManagerFSX.update(airSpeedEncoder);
  airManagerFSX.update(airSpeedEncoderButton);
  airManagerFSX.update(altitudeEncoder);
  airManagerFSX.update(altitudeEncoderButton);
  airManagerFSX.update(headingEncoder);
  airManagerFSX.update(headingEncoderButton);

} //** end loop()


void syncFlightSim() {
  // Send state of switches to sync flight simulator
  digitalWrite(statusLEDPin, LOW); // status LED off
  taxiLightSwitch.update();
  airManagerFSX.send(taxiLightSwitch);
  landingLightSwitch.update();
  airManagerFSX.send(landingLightSwitch);
  landingGearSwitch.update();
  airManagerFSX.send(landingGearSwitch);
  delay(500);
  digitalWrite(statusLEDPin, HIGH); // status LED on
}

void resetEthernetModule() {
  // Reset WIZnet W5500 ethernet module before use
  pinMode(ethernetResetPin, OUTPUT); // connected to reset pin
  digitalWrite(ethernetResetPin, LOW);
  delay(1);
  digitalWrite(ethernetResetPin, HIGH);
  delay(450);
}

The FSX sketch can also be used for Prepar3d. I don't have an example with interinstrument communication yet.

User avatar
WillemijnL
Posts: 107
Joined: Sat Jan 30, 2016 1:14 pm

Re: Communication between development boards and Air Manager

#5 Post by WillemijnL »

A picture of the test setup with the Teensy 3.6. On top the WizNet W5500 ethernet module. I still have to make a panel to mount the controls on.
Attachments
Teensy 3.6 test setup.png

User avatar
russ
Posts: 593
Joined: Tue Oct 27, 2015 5:37 pm

Re: Communication between development boards and Air Manager

#6 Post by russ »

Awesome project. I think when you add access to read/write dataref/variables the toggle limitation on FSX will be overcome. In the meantime this offers a way to build many standalone hardware projects that can interface with a sim using only the Air Manager plugin. Anxious to follow your progress... keep us updated.
Russ Barlow
Air Manager Evangelist

xp-wym
Posts: 66
Joined: Fri Mar 04, 2016 11:13 am

Re: Communication between development boards and Air Manager

#7 Post by xp-wym »

Looks great and looking forward to your further progress!

User avatar
WillemijnL
Posts: 107
Joined: Sat Jan 30, 2016 1:14 pm

Re: Communication between development boards and Air Manager

#8 Post by WillemijnL »

Some news about the project. I did some changes in the structure of the library to have only one piece of code instead of three to support ethernet, ethernet2 and wifi. This reduces work in the future and improves maintenance. Also did some other improvements and changes. After some tests I found out that also writing of (single) X-Plane datarefs would be great. For instance, not all autopilot actions are supported by commands. So I moved writing variables and datarefs (not arrays) to version 1. This is extra work, but with writing commands/events and single variables/datarefs you can do a lot already. So the extra work for version 1 will be worth. After that it all has to be (alpha) tested and I also have to create documentation. Last one is not my favorite :( , but necessary to know how to use the library. Plans for version 2: writing arrays and adding support for potmeters. Version 3 will support subscribing on variables/datarefs.

Post Reply