Jump to content

[KSP 1.8.1+] KSPEthernetIO [0.1.2] Android Client [0.2 beta] Ethernet based remote control


Recommended Posts

Inspired by the original KSPSerialIO by @zitronen I wanted to create my own physical display and input device for KSP. My plan was to add an external Navball but the limited hardware of the Arduino makes it nearly impossible to do the vector calculation and rendering on it. So I decided to use a RaspberryPi. In first step I have edit the original KSPSerialIO to create a similar Add-On using a TCP connection for data exchange so that it's possible to connect any client in the same network with the host computer. The second step was to create and test a client application. I decided to use Java for the client to create an Android client as well as a RaspberryPi client with (nearly) the same code.

Currently I'm testing the KSPEthernetIO Plug-In with the Android client. If this works reliable I start working on the RaspberryPi client.


KSPEthernetIO [0.1.2]:


Opens a TCP server and sends broadcasts through the network. Waits for incoming connection. When connected performs optional handshake to verify client. Continously exchanges control and vessel data between client and host.

Tested on Windows 7 and Windows 10
Tested with KSP 1.8.1 and 1.9


  • All functions of the original KSPSerialIO
  • Slighly extended version of the original KSPSerialIO data packets
  • Automatic client detection via UDP broadcasts
  • Connection control and automatic reconnect
  • Some new functions (control camera and ui mode, open main menu, toggle map)


Add-On (Windows):

v0.1.2: https://perske.eu/KSPEthernetIO-0.1.2.zip
Source: https://github.com/DrMarcel/KSPEthernetIO

Old versions:

v0.1.0: https://perske.eu/KSPEthernetIO-0.1.0.zip
v0.1.1: https://perske.eu/KSPEthernetIO-0.1.1.zip


KSPEthernetIO Android client [0.2 beta]:


Remote control App for KSPEthernetIO. Automatic connect to a KSPEthernetIO host and remote control your vessel.

Currently I can only provide a download link for the APK. I have uploaded the current version to the Android PlayStore but the release may take a few days. If you struggle to install an APK from an external source just wait a few days until I can provide a download link for the PlayStore. Edit: App is now avaiable in Google Playstore.


  • Live render navball
  • Show vector nodes on navball
  • Control SAS, RCS, ActionGroups, etc.
  • Show velocity, altitude and some orbit information
  • Show fuel states
  • Change UI and Camera Mode
  • Toggle Map
  • Open Main Menu (a little bit hidden - long press the "..."-button for that)


PlayStore: https://play.google.com/store/apps/details?id=com.kspethernetiodemo
APK: https://perske.eu/KSPEthernetIO-AndroidClient.0.2.zip
Source: https://github.com/DrMarcel/KSPEthernetIO-Android-Client

Old versions:

APK: https://perske.eu/KSPEthernetIO-AndroidClient.0.1.zip






KSPEthernetIO RaspberryPi Client:


Planned for the next weeks, currently wip.


Additional information:

Original post:


	<int name="Port">2342</int>
	<int name="Refresh">50</int>
	<int name="BroadcastDisable">0</int>
	<int name="Broadcast">1000</int>
	<int name="WatchdogDisable">0</int>
	<int name="WatchdogTimeout">1500</int>
	<int name="HandshakeDisable">0</int>
	<int name="HandshakeTimeout">1500</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.2</double>

Port: Communication TCP port
Refresh: Data send delay in milliseconds
BroadcastDisable: 1=Disable sending broadcast messages
Broadcast: Broadcast send delay in milliseconds
WatchdogDisable: 1=Disable watchdog timer
WatchdogTimeout: If no data is received within this time the connection is reset
HandshakeDisable: 1=Accept all incoming connections
HandshakeTimeout: If no data is received within this time after connection the connection is reset
ThrottleEnable: enable value of throttle axis
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
3: If the external value is not zero use it, otherwise use the internal value

See above for default config

Issues / TODOs:

  • Bring client application to the PlayStore [12.02.2020]
  • Add more orbital infos [17.02.2020]
  • Permanent save app settings [17.02.2020]
  • Custom actiongroup names in settings [17.02.2020]
  • Centralize all coloring in config files
  • Tests on different screen sizes
  • Reset data on active vessel change - Transmit vessel ID ? [17.02.2020]
  • Code documentation [14.02.2020]
  • Clean compiler warning
  • Buffer incoming data with adaptive playout to get "smooth" data stream
  • Navball rendering is very CPU intense - Implement OpenGL rendering
  • Split fight info in smaller classes


CC BY 4.0




I hope you like this project.
I'm happy about any feedback, bug reports and ideas.

Have a good flight



  • [10.02.2020] Changed broken download links
  • [10.02.2020] Changed download link http->https
  • [12.02.2020] Added playstore link
  • [14.02.2020] Updated TODO list
  • [17.02.2020] Release KSPEthernetIO 0.1.1 and Client 0.2 beta
  • [10.03.2020] Changed version numbers 1.x.0 was actually 0.1.x
  • [10.03.2020] Release KSPEthernetIO 0.1.2
Edited by DrMarcel
[10.03.2020] Release KSPEthernetIO 0.1.2
Link to comment
Share on other sites

Thanks for the response and the positive feedback :D

I have changed the broken download link. Even after a reupload google drive filesharing didn't work.

About the packet size:

The payload is 29 bytes from client to host and 212 bytes from host to client. But there is some overhead by the TCP headers. The actual packet size is 83 and 266 bytes. But as you can see in the wireshark snippet below you don't get any overhead by the TCP ACK commands because they are automaticly bundled with the data packets.

Currently I'm running very stable with 50ms refresh time on both sides. I've tried down to 20ms is still stable. The main problem is at some point the network adapter starts prebuffering small packets, so that more than one data packet is sent within the same TCP packet. When live rendering the packets that's equal to a packet loss. It's not possible to fully turn off this behaviour by software, so currently the refresh rate is limited somewhere above 10ms.

A short look into wireshark also shows a high latency of ~15ms on the client side. You can see the host packet comes with stable 50ms but the client with the same settings is sending all 65ms with some jitter.


I think a good improvement would be to buffer the incoming packages while measuring the average receive clock and the make some adaptive playout from the package buffer to get a "smooth and continous" data stream rather than rendering the data live. Than it wouldn't matter if more than one data package is bundled in the same TCP packet.

I gonna test this out the next days.

Link to comment
Share on other sites

Update 14.02.20:

  • Added PlayStore link
  • Added some TODOs
  • Code documentation done (JavaDoc and xml summaries)
  • New develop branch in Android Client git
  • Some tidy up in Android Client (Matrix3x1 replaced by Vector class because of redundancy, some refactoring)

The Android App is currently in beta state, so if there are any crashes, bugs or other issues contact me or send the crash reports. I can review the crash logs from the PlayStore console.

Link to comment
Share on other sites

Update 17.02.20: Release notes

KSPEthernetIO Android client 0.2 beta
KSPEthernetIO 0.1.1

  • Data is now synchronized on vessel change. Added vesselSync value in VesselData and ControlPacket. Sync value is increased by the host on every vessel change - the client mirrors the sync value so the client can synchronize with the preselected actiongroups of the new vessel to avoid bad things happening on vessel change.
  • Custom action group names in App settings
  • App settings now saved permanent on device
  • Added new StatusPacket from host to client to transmit flight start and flight end
  • Some color adjustments
  • Added more orbital info
  • Small bugfixes on navball velocity vectors

The new App Version is not compatible with the initial KSPEthernetIO release. If you update the App you also have to update the KSP Add-On as well.

Edited by DrMarcel
File version was 0.1.1 not 1.1.0
Link to comment
Share on other sites

  • 3 weeks later...

Hey! I'm about to start work on a KSP controller and I think I may end up using your plugin and building the hardware around an STM32, haven't decided which MCU yet but either an F4 or F7.  I'm a hardware engineer by trade, and my software skills are passable. I might be bugging you with some help but given that it's a raw TCP feed, I should be ok (famous last words). I'll keep you posted.

Link to comment
Share on other sites

Doesn't look like you implemented the Watchdog disable in your PacketHandler code. I've just cranked up the timeout, but it makes debugging a pain when I haven't written my sender yet. lol. 

Edited by Wakestrap
Link to comment
Share on other sites

Hi Wakestrap,

nice to hear you are using this project to create your controller. Implementing TCP on a microcontroller sounds very interesting. So far I have only worked with small PICs and Atmegas but never with network communication. I hope you share your results here :)


Thanks for the info about the watchdog timer. You are totally right, the background worker of the packet handler doesn't check for the _watchdogDisable bit.

I will fix this tomorrow and upload a new compiled version. If you need it today and compile the addon by yourself, you could change L362 of PacketHandler:

if (_server.ClientConnected && (HandshakeReceived || _handshakeDisable) && !_watchdogDisable)


Edited by DrMarcel
Link to comment
Share on other sites

Awesome! Thanks for taking care of that so quickly! I'll give this a test later tonight.

I will 100% release everything here! The code might make you cringe but it should get the job done. 

I realized I had an STM32F746ZG Nucleo development board laying around, so that's what I'm developing on. https://www.st.com/en/evaluation-tools/nucleo-f746zg.html

Tons of IO, relatively cheap at ~$25USD and plenty powerful. I've got the TCP receive handler working, so I can connect to your server and get vessel data without issue. Next up is packetizing the control data and sending it back. I'm leaving the UDP broadcast read until the end as it's only a few lines of code. My work life has me pretty flat out so I've only gotten a couple of hours to pick at it but so far so good. Luckily your code is easy to read so I haven't had any issues reverse engineering the client side. 



Link to comment
Share on other sites

Hey @DrMarcel! So I've got all the pieces working. I'm sending valid control packets. I can adjust throttle and orientation but I'm having some issues with the variables that shared with the VesselData packet. In particular I can't get SAS controls working. What is the relationship between the NavballSASMode variable the plugin sends me and the NavballSASMode variable I'm sending back to the plugin? Who's the master in the relationship and does MainControls just act as a master disable for SAS?I assume I just resend the vesselsync variable back to the plugin?  

Thanks so much! Once I get this last bit sorted, I just have to actually design the actual controller and we're good to go.

Edit: Scratch that! I'm good, had a look at the SerialIO code. I'm all set.

Edited by Wakestrap
Link to comment
Share on other sites

We now have a working shell. VesselData and Control Data are flowing smoothly between KSPServer and my MCU dev board. I can now control everything without issue. The only controls I've got implemented in this first release is pressing the User Button on the dev board deactivates SAS and activates RCS. You can enable outputs to the debug console by enabling the macro OUTPUTENABLE. It'll print AP, Vsurf, Vessel Sync and a couple of other variables to the console.

Once I had all the pieces working with test code, I had started to write the full code from scratch but when I released how quick it would be to just port the SerialIO arduino code over to mbed, I decided to go that route. mbed has some strange quirks that including no byte type support (char is the usual substitute)  and it (like many embedded compilers) pads structs, so I was having major issues with byte alignment when trying to memcpy from byte array to struct and visa versa. I ended up just writing a disgusting amount of code to just manually pull the vessel data from the packet buffer and stuff the Control Packet, it's ugly and I'm sorry. The handshake packet worked fine because it's all the same data type so no padding problems.  Fixed this issue by using pragma pack. 

I'll update you again when I actually get a controller built. I wanted to get the core code out now in case anyone else wants to play with it while I'm working on the rest of the hardware. 

Thanks again @DrMarcel for writing the EthernetIO plugin and @zitronen for writing the SerialIO code. I hope this adds to the project in some way. I'll try to get a youtube demo video published when I get some controls hooked up. 



mbed project link: https://os.mbed.com/users/wakestrap/code/KSPmbedIO/

Tested on: Nucleo STM32F746ZG Dev Board https://www.st.com/en/evaluation-tools/nucleo-f746zg.html



Edit: Added a connection management loop to allow for automatic reconnect, fixed struct padding issue  and fixed a watchdog timeout issue. 

Moved my dev to it's own thread


Edited by Wakestrap
Link to comment
Share on other sites

  • 1 month later...

Oh, so much activity here :) . Thanks for all the response and sorry for my inactivity the last weeks.


@Wakestrap : Cool project and congrats for the really fast progress you performed. I think creating a controller with a STM is very niche so thank you to share this project with us.

@BamBam , @RowBear : I'm glad to hear that the App is working fine so far. I have only one device to test the App, so I'm really happy to see it's also working on other devices without any trouble.

@f0restperson : Using a RaspberryPi as a control desk is possible, but not "out of the box". The server ( = the KSP Addon) doesn't care which device is connected to it, so it's possible to connect a RaspberryPi as well. But so far I have neither a RPI image nor some nearly finished source code for that. So there is some work to do on the client side. If you program the RPI in Java it's possible to use much code from the Android App without any change.


The open ToDos of the App are nice to have but currently not essential. So I can not say when I will implement them. But if you recognize some bugs or have any pull requests for it, just contact me. The next thing I will focus on is the RPI client.

Stay healthy  and have a good flight

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...