The forums will be updated to new software on November 27th. Data will be lost, please see this post for more information.
Page 1 of 133 1231151101 ... LastLast
Results 1 to 10 of 1327

Thread: [Hardware, Plugin] Arduino based physical display + serial port io+ tutorial (06-Jun)

  1. #1

    [Hardware, Plugin] Arduino based physical display + serial port io+ tutorial (06-Jun)

    Like many people here, I wanted to make an arduino physical display then quickly realized unity does not have the required serial IO name space. So the solution is to borrow someone else's code (, which turns out is kind of incomplete but works. This plugin sends/receives data packets over the serial port, which should make it much easier for people wanting to build hardware for KSP but can't be bothered with making plugins as well.

    Note: currently not working for windows 10 for some reason!

    Compatible with KSP 1.0.5, 1.0, 0.90, versions 0.15 and older compatible with 0.23, 0.23.5, 0.24, 0.25

    This plugin implements the following:
    1. Packeting of serialized C# structure for efficient communications including checksums
    2. Listing of available serial ports (only works on Windows PC, using registry hacks)
    3. Automatic handshake and detection of display COM port at 38400 Baud
    4. Bi-directional data transfer: control KSP from arduino [supported but not fully implemented yet, easy if you want to do it yourself] (added in 0.13)
    5. Analogue axes control (added in 0.14)

    Direct download link for the plugin: (V0.17.3) - There may be newer versions posted in the thread, but this is the current recommended "stable" version.

    Also available on Kerbal Stuff and CKAN (Thanks hakan!)

    Mac/linux version maintained by Marzubus:

    Source code for the plugin

    Source code for arduino - There may be newer versions posted in the thread, but this is the current recommended "stable" version.

    Currently, these vessel parameters are sent to the serial port (updated 06-06-2015):

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct VesselData
            public byte id;             //1   packet id
            public float AP;            //2   apoapsis (m to sea level)
            public float PE;            //3   periapsis (m to sea level)
            public float SemiMajorAxis; //4   orbit semi major axis (m)
            public float SemiMinorAxis; //5   orbit semi minor axis (m)
            public float VVI;           //6   vertical velocity (m/s)
            public float e;             //7   orbital eccentricity (unitless, 0 = circular, > 1 = escape)
            public float inc;           //8   orbital inclination (degrees)
            public float G;             //9   acceleration (Gees)
            public int TAp;             //10  time to AP (seconds)
            public int TPe;             //11  time to Pe (seconds)
            public float TrueAnomaly;   //12  orbital true anomaly (degrees)
            public float Density;       //13  air density (presumably kg/m^3, 1.225 at sea level)
            public int period;          //14  orbital period (seconds)
            public float RAlt;          //15  radar altitude (m)
            public float Alt;           //16  altitude above sea level (m)
            public float Vsurf;         //17  surface velocity (m/s)
            public float Lat;           //18  Latitude (degree)
            public float Lon;           //19  Longitude (degree)
            public float LiquidFuelTot; //20  Liquid Fuel Total
            public float LiquidFuel;    //21  Liquid Fuel remaining
            public float OxidizerTot;   //22  Oxidizer Total
            public float Oxidizer;      //23  Oxidizer remaining
            public float EChargeTot;    //24  Electric Charge Total
            public float ECharge;       //25  Electric Charge remaining
            public float MonoPropTot;   //26  Mono Propellant Total
            public float MonoProp;      //27  Mono Propellant remaining
            public float IntakeAirTot;  //28  Intake Air Total
            public float IntakeAir;     //29  Intake Air remaining
            public float SolidFuelTot;  //30  Solid Fuel Total
            public float SolidFuel;     //31  Solid Fuel remaining
            public float XenonGasTot;   //32  Xenon Gas Total
            public float XenonGas;      //33  Xenon Gas remaining
            public float LiquidFuelTotS;//34  Liquid Fuel Total (stage)
            public float LiquidFuelS;   //35  Liquid Fuel remaining (stage)
            public float OxidizerTotS;  //36  Oxidizer Total (stage)
            public float OxidizerS;     //37  Oxidizer remaining (stage)
            public UInt32 MissionTime;  //38  Time since launch (s)
            public float deltaTime;     //39  Time since last packet (s)
            public float VOrbit;        //40  Orbital speed (m/s)
            public UInt32 MNTime;       //41  Time to next node (s) [0 when no node]
            public float MNDeltaV;      //42  Delta V for next node (m/s) [0 when no node]
            public float Pitch;         //43  Vessel Pitch relative to surface (degrees)
            public float Roll;          //44  Vessel Roll relative to surface (degrees)
            public float Heading;       //45  Vessel Heading relative to surface (degrees)
            public UInt16 ActionGroups; //46  status bit order:SAS, RCS, Light, Gear, Brakes, Abort, Custom01 - 10 
            public byte SOINumber;      //47 SOI Number (decimal format: sun-planet-moon e.g. 130 = kerbin, 131 = mun)
            public  byte MaxOverHeat;   //48  Max part overheat (% percent)
            public  float MachNumber;   //49
            public  float IAS;          //50  Indicated Air Speed
    The input packet from arduino is formated like this (updated 09-03-2015):

    struct ControlPacket {
      byte id;
      byte MainControls;                  //SAS RCS Lights Gear Brakes Precision Abort Stage 
      byte Mode;                          //0 = stage, 1 = docking, 2 = map (Not implemented yet!)
      unsigned int ControlGroup;          //control groups 1-10 in 2 bytes
      byte AdditionalControlByte1;        //other stuff
      byte AdditionalControlByte2;
      int Pitch;                          //-1000 -> 1000
      int Roll;                           //-1000 -> 1000
      int Yaw;                            //-1000 -> 1000
      int TX;                             //-1000 -> 1000
      int TY;                             //-1000 -> 1000
      int TZ;                             //-1000 -> 1000
      int WheelSteer;                     //-1000 -> 1000
      int Throttle;                       //    0 -> 1000
      int WheelThrottle;                  //    0 -> 1000
    Currently implemented controls:
    • SAS
    • RCS
    • Lights
    • Gear
    • Brakes
    • Abort
    • Stage
    • Action groups 1-10
    • Pitch axis
    • Roll axis
    • Yaw axis
    • Translate X axis
    • Translate Y axis
    • Translate Z axis
    • Throttle
    • Wheel Throttle
    • Wheel Steer

    Note: anything not mentioned here (like map view, precision) is not implemented yet.

    Packet format:
    The data packets are byte arrays with the following format:
    Packet = [header][size][payload][checksum]
    Header = [Header1=0xBE][Header2=0xEF]
    size = [payload.length (0-255)]
    Settings file is located in the plugindata folder, currently these are the settings editable by the user:
        <double name="refresh">0.08</double>
        <string name="DefaultPort">COM1</string>
    	<int name="BaudRate">38400</int>
        <int name="HandshakeDelay">2500</int>
    	<int name="ThrottleEnable">2</int>
    	<int name="PitchEnable">2</int>
    	<int name="RollEnable">2</int>
    	<int name="YawEnable">2</int>
    	<int name="TXEnable">2</int>
    	<int name="TYEnable">2</int>
    	<int name="TZEnable">2</int>
    	<int name="WheelSteerEnable">2</int>
    	<int name="WheelThrottleEnable">2</int>
    	<double name="SASTol">0.1</double>
    refresh: how quickly the plugin sends out data, default once every 0.08 seconds (80ms)
    DefaultPort: this is the port the plugin will check first
    BaudRate: serial port baud rate
    HandshakeDelay: we need to wait for the arduino to restart every time we open the port, by default we wait 2500ms. Try increase if you have connection problems.
    ThrottleEnable: enable control of throttle axis from arduino
    PitchEnable: enable value of pitch axis
    RollEnable: enable value of roll axis
    YawEnable: enable value of yaw axis
    TXEnable: enable value of translation X axis
    TYEnable: enable value of translation Y axis
    TZEnable: enable value of translation Z axis
    SASTol: The SAS will override your controls when you turn it on, this value allows you to override SAS if you move the roll pitch yaw control over a certain limit (10% travel by default)

    Enable value settings for axes:
    0: The internal value (supplied by KSP) is always used.
    1: The external value (read from serial packet) is always used.
    2: If the internal value is not zero use it, otherwise use the external value. (Now default!!!)
    3: If the external value is not zero use it, otherwise use the internal value.

    Using this plugin, you can make something like this:

    More pictures:

    If anyone is interested in buying a display or the PCB + parts to build the display yourself, send me a PM. I have some bits left over to make a few more.

    It take too much effort to make and sell these, but send me a PM if you have difficulty finding parts.

    Schematics and BOM below!

    Schematic and BOM for the display: (V1)

    Tutorial for arduino
    1. Simple Warning LEDs
    Connect 3 LEDs and 3 1k resistors to pins 5 (green), 6 (yellow), and 7 (red)

    (I don't have any red LEDs so using blue instead)

    Load the arduino code below. Start KSP and build a simple ship. The green led will turn on at launch, yellow led will turn on when G > 5 or fuel < 10%, and red led will turn on when G > 9 or fuel < 5%. These warnings can of course be customized in the arduino code. Since version 0.15 the warnings are for current stage fuel, not total.

    2. Simple input example
    Connect switches between pins 8 (SAS) and 9 (RCS) and ground (PIN --> Switch --> Ground). By default the input states are sent from the arduino at 40Hz

    3. Action groups
    Action groups are similar to normal inputs. If you set your controls to "toggle" in KSP, you can actually use a switch to turn an action group on and off. In the arduino code you can simply write: ControlGroups(10, HIGH); to turn on control group 10.

    4. Axes
    By default, the demo code uses the analogue input 0 to drive the throttle. Connect a pot to an analog input pin 0 and that's it (see You will need to go to settings file and set ThrottleEnable to 1, by default throttle is not enabled (same with all other axes). Once throttle is enabled you will lose the ability to control it with keyboard.

    Source code for arduino - There may be newer versions posted in the thread, but this is the current recommended "stable" version.
    1. Warning LED demo: use code from demo 4
    2. Input demo: use code from demo 4
    3. Action groups: use code from demo 4
    4. Input Axes:

    Forks and other projects using the plugin
    Daid is forking the plugin code to make a Kerbal control panel with many buttons and switches, allowing you to fly your rocket without a keyboard

    MrOnak has ported the Arduino code to AVR C, so you can use generic AVR micro controllers and not stuck with Arduino IDE

    cm2227 is working on a version that will include mechjeb functionality for his display

    Several people are working on a Mac version
    Working version by Marzubus:

    Mulbin has created a thread listing many example projects (not all using this plugin)

    Known Issues
    1. Seems to have trouble detecting COM ports with high numbers, check and make sure you port number is less than 10, will fix later
    2. If you are getting the handshake reply but not getting any data, it usually means you found the right COM port, everything is working but there is something wrong with the packet. This is typically caused by plugin and arduino code version miss match, try re-downloading the plugin and demo arduino code, you might have missed an update.
    3. If you are having intermittent connection drops, it may be caused by the Arduino serial buffer getting filled up. You can try increasing the size of the rx buffer in HardwareSerial.h in your Arduino install.

    CC BY, attribution appreciated.

    Special Thanks

    1. 25-01-2014 Added a simple tutorial for arduino
    2. 31-01-2014 Added schematics and BOM, updated plugin to 0.11
    3. 04-02-2014 Found new bug, updated packet description
    4. 08-02-2014 Updated plugin to 0.12, added user settings with some help from blacknecro, now you can define a default port which the plugin will try first
    5. 25-02-2014 Updated plugin to 0.13, added support for inputs, added input demo, added description of input packet format
    6. 11-03-2014 Updated plugin to 0.13.4, added action groups, lights, gear, brakes, abort, and stage
    7. 15-03-2014 Updated plugin to 0.13.5, added output for current and total resources, and altitude above sea level
    8. 29-03-2014 Updated plugin to 0.14.1, added analogue throttle control, updated packet structure
    9. 09-04-2014 Updated plugin to 0.14.3, added pitch, roll, yaw, and x, y, z, translation axes controls, fixed a problem with some arduino bootloaders.
    10. 04-05-2014 Updated plugin to 0.15.1 added Mission time, delta time, liquid fuel + oxidizer total and available for current stage, added orbital velocity, time to next node and delta V for next node
    11. 16-08-2014 Updated plugin to 0.15.3 added roll, pitch, heading output, changed handshake so it is possible to connect multiple arduinos/devices (possible but still requires some work)
    12. 08-09-2014 Oops, there were some problems with the latest version. I accidentally uploaded the debug code for 0.15.3 and demo8, so it didn't work. If you have recently downloaded the plugin and arduino code, you need to re-download them again. Sorry about that.
    13. 08-10-2014 Tested to work with 0.25
    14. 29-11-2014 Hopefully fixed a bug with axes controls when changing vessels (thanks AmeliaEatyaheart).
    15. 14-12-2014 Changed to use time.unscaledTime so that the data refresh rate is constant during physical time warp:
    16. 17-12-2014 V0.16.0 Compatibility fix for KSP 0.90: changed stuff related to active vessel SAS
    17. 17-12-2014 V0.16.1 Compatibility fix for KSP 0.90: fixed issue with patched conics null reference in career mode
    18. 09-03-2015 V0.17.1 Added sending back of control statuses in a single uint16: SAS, RCS, Light, Gear, Brakes, Abort, Custom01 - 10, added simple function in arduino for reading the statuses, SAS and RCS controls are now synced when switching vessel (Freshmeat request), added return value for input() function in arduino code (MrOnak post #705), merged the controls code from Stibbons which works really well
    Integrated new axes WheelSteer and WheelThrottle using code from Stibbons, now you can drive your rovers from your control panel, new config file settings for enabling/disabling axes from Stibbons.
    19. 06-06-2015 V0.17.3 Added SOI name output in decimal format: sun-planet-moon (, added max overheat percent (Sputnix request), Mach number, and indicated air speed.
    Last edited by zitronen; 9th November 2015 at 19:10.

  2. #2


    How is the data bus that is sent via serial to the arduino?
    I want to make this reading using PIC!

    ps: Sorry my english

  3. #3
    Mutants Worship Me Nuke's Avatar
    Join Date
    Nov 2011
    probibly use one of those usb<->ttl bridge chips like was used on older arduinos (you can get breakout boards for this chip from sparkfun, see link). newer arduinos just have a usb cdc serial port integrated into the bootloader (may be able to do the same on a pic). never used pic myself, mostly an avr guy. if i change to something its gonna be arm.

    i got a 240x320 color tft screen with a spi interface (currently connected to a leonardo running a modded version of hackvision asteroids). might play around with having an orbiter-esque orbit gauge one of these days. *googles ellipse drawing algorithm*
    Last edited by Nuke; 21st January 2014 at 17:30.
    this space intentionally left blank

  4. #4
    Capsule Communicator MK3424's Avatar
    Join Date
    Mar 2012
    Blog Entries
    There are others who are also in the works of making physical displays, but this display is simple yet handy!

    However, how can i use it while i have no serial port? (while there are serial port adapters, how will the Arduino co-op with that?)

  5. #5
    Mutants Worship Me Nuke's Avatar
    Join Date
    Nov 2011
    its pretty much virtual serial over usb. arduino handles all that for you. on the pc side this interface is exposed as a virtual com port, and on the arduino side with the serial library. this plugin looks like its designed to handle the pc side for you.

    from the looks of it you just need to receive the data packet, and use the data to draw your displays, these could be 7 segment displays, character lcds, graphic lcds, physical gauges, servos etc. this looks pretty versatile.
    Last edited by Nuke; 21st January 2014 at 20:29.
    this space intentionally left blank

  6. #6
    Capsule Communicator MK3424's Avatar
    Join Date
    Mar 2012
    Blog Entries
    How much does the thing cost?

    pre-assembled or only the parts.

  7. #7
    Update: I have made a simple tutorial for arduino and uploaded some simple arduino code to drive a couple LEDs as warning lights, check the first post.

    Quote Originally Posted by brunorichter View Post
    How is the data bus that is sent via serial to the arduino?
    I want to make this reading using PIC!

    ps: Sorry my english
    All you need to do is buy an arduino or any of the arduino clone boards. If you use a PIC you will need to buy your own USB to serial board e.g. FTDI, like the one Nuke mentioned. I wouldn't get it from sparkfun though, everything they sell is more expensive.

    Quote Originally Posted by MK3424 View Post
    How much does the thing cost?

    pre-assembled or only the parts.
    Looks like it will be around £60 + shipping, the PCB is £10, LCD £10, the LED drivers and 4x3 7 seg LEDs another £20, plus the ATMEGA328, crystal, encoder and so on it all adds up very quickly! I don't want to get into business selling these though, my goal is to make it easier for people to build their own.

  8. #8
    Mutants Worship Me Nuke's Avatar
    Join Date
    Nov 2011
    sparkfun is a little expensive. i usually go check ebay first to see if i cant get something for less. im up to my eyeballs in prototyping stuffs so i dont need to buy anything, i just need to allocate time to playing around with this.
    this space intentionally left blank

  9. #9
    Quote Originally Posted by zitronen View Post
    my goal is to make it easier for people to build their own.
    Man this is awesome. I have my arduino sitting here collecting dust, my plans were to do exactly what you've done. I'm bogged down in my other mod projects but when I'm done those I'm going to look at this closely. From what you've said I was going to follow nearly the same path you have.

    Great stuff!

  10. #10
    OK to send a single byte is easy, but once you need to send more data and parse it and also receive from serial it suddenly becomes more complex. Basically, you can just add the serialport.dll in my plugin to your references, and use something like this:

    using OpenNETCF.IO.Ports;
    [KSPAddon(KSPAddon.Startup.Flight, false)]
    public class KSPSerialIO : MonoBehaviour
      void Start()
        public SerialPort Port;
        byte HelloByte= 0xBE;
        Port = new SerialPort("COMx", 38400, Parity.None, 8, StopBits.One);
        Port.Write(HelloByte, 0, 1);
    Have not tested it, so there are probably some errors.

Page 1 of 133 1231151101 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts