Jump to content

[Hardware, Plugin] Arduino based physical display + serial port io+ tutorial (24-11-19)


zitronen

Recommended Posts

Hello all. I am trying to get this to work without any luck. First off, I don't see which arduino was originally used here. I am using a Duemilanove with the current KSP update and the newest version of KSPSerialIO. I am also using the current versions of Kethane and Mechjeb2.

Here is the log:

[LOG 15:08:35.334] AddonLoader: Instantiating addon 'KSPSerialPort' from assembly 'KSPSerialIO'

[LOG 15:08:35.340] KSPSerialIO: Version 0.15.2

[LOG 15:08:35.341] KSPSerialIO: Getting serial ports...

[LOG 15:08:35.343] KSPSerialIO: Output packet size: 165/255

[LOG 15:08:35.348] KSPSerialIO: Found 2 serial ports

[LOG 15:08:35.350] KSPSerialIO: trying default port

[LOG 15:08:35.353] Error opening serial port : Object reference not set to an instance of an object

[LOG 15:08:35.356] KSPSerialIO: trying port \Device\VCP0 - COM3

[LOG 15:08:39.425] KSPSerialIO: KSP Display not found

[LOG 15:08:39.428] AddonLoader: Instantiating addon 'KSPSerialIO' from assembly 'KSPSerialIO'

So every time I load up a vessel on the launch pad there is a longer than usual load time. I added some code to the arduino so that one of the LEDs will turn on and then off when the arduino first turns on. During this loading time that LED is flashes twice(sometimes three times) making me think that my arduino is restarting while it is loading. In the end it always says "no display found" at the top right. Since the log and that message are showing information, I assume that the problem is on the side of the arduino. Now I don't actually have an LCD/LED display connected to the arduino since that is not my end goal. Since it is having problems with the com port I assume that by "no display found" it actually means "Arduino not found". Can someone confirm that for me?

I got this to work once, but that was after a few hours of messing with it and it wouldn't work immediately after. Any help would be greatly appreciated.

Thanks in advance.

Link to comment
Share on other sites

I see you are using version 0.15.2. That version only works with the demo code (7) posted in the same post because of changes in the data packet. If you are using the demo code from the first post, make sure you are using version 0.15.1. The plugin and arduino code on the first post are "stable", other links in the thread are "experimental". edit: I added a line to the first post to make it more clear.

Other than that, yes display means arduino, because originally I made the plugin for my own display, and it should work with any arduino or arduino clone.

Edited by zitronen
Link to comment
Share on other sites

Alright, I'm trying to get this up and running on my system, but I'm not sure if I'm putting the plugin in the right directory. I don't have an Arduino (I prefer the MSP430 myself), but I've put in an FT232R to at least test if the plugin is working. I've tried putting the folder in both $KSP/GameData and $KSP/Plugins and get the same error on loading for both places. Here's the log:

...
[LOG 10:54:20.544] Load(Assembly): Plugins/KSPSerialIO/KSPSerialIO
[LOG 10:54:20.545] AssemblyLoader: Loading assembly at C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program\Plugins\KSPSerialIO\KSPSerialIO.dll
[LOG 10:54:20.546] Load(Assembly): Plugins/KSPSerialIO/SerialPort
[LOG 10:54:20.546] AssemblyLoader: Loading assembly at C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program\Plugins\KSPSerialIO\SerialPort.dll
...
...
...
[LOG 10:55:39.886] KSPSerialIO: Loading settings...
[LOG 10:55:39.887] Parsing double
[LOG 10:55:39.887] Parsing string
[LOG 10:55:39.887] Parsing int
[LOG 10:55:39.887] Parsing int
[LOG 10:55:39.888] Parsing bool
[LOG 10:55:39.888] Parsing bool
[LOG 10:55:39.888] Parsing bool
[LOG 10:55:39.888] Parsing bool
[LOG 10:55:39.889] Parsing bool
[LOG 10:55:39.889] Parsing bool
[LOG 10:55:39.889] Parsing bool
[LOG 10:55:39.890] Parsing double
[LOG 10:55:39.890] KSPSerialIO: Default Port = COM7
[LOG 10:55:39.890] KSPSerialIO: Refreshrate = 0.08
[LOG 10:55:39.891] KSPSerialIO: BaudRate = 38400
[LOG 10:55:39.891] KSPSerialIO: Handshake Delay = 2500
[LOG 10:55:39.891] KSPSerialIO: Throttle Enable = False
[LOG 10:55:39.892] KSPSerialIO: Pitch Enable = False
[LOG 10:55:39.892] KSPSerialIO: Roll Enable = False
[LOG 10:55:39.892] KSPSerialIO: Yaw Enable = False
[LOG 10:55:39.893] KSPSerialIO: Translate X Enable = False
[LOG 10:55:39.893] KSPSerialIO: Translate Y Enable = False
[LOG 10:55:39.893] KSPSerialIO: Translate Z Enable = False
[LOG 10:55:39.894] KSPSerialIO: SAS Tol = 0.1
[EXC 10:55:39.909] NullReferenceException: Object reference not set to an instance of an object

I was hoping to at least see KSP start a handshake to tell me it's searching for the Serial Port, but no luck there. I've tried both 015.1 and 015.2 with the same result. Am I putting things in the wrong place? Or is it searching for a specific tag that is only available from an Arduino? (If so, can we please make it more general for those of us who use other hardware?)

Link to comment
Share on other sites

This is the same as any other plugin, install in the gamedata folder.

No it should work with any micro processor using the same data packet format.

Is the log from the main menu or did you try to launch? The plugin only activates serial port stuff when you launch.

Edit: is that the full log? Nothing after that? KSP generates a nullreference thing by itself without any mods.

Edited by zitronen
Link to comment
Share on other sites

Yes, that did it. From the demo video you had, it looked as though your screen was responding on loading the game, so I had assumed there would be a handshaking done there too. So far I've been able to get it to handshake (manually sending the handshake packet from another computer) and receive the telemetry data. Thanks so much for this!

I expect this isn't something you'd want to do in the base package, but for me it'd be great to include the O2, H2O, food, etc. from TAC Life Support (http://www.curse.com/ksp-mods/kerbal/221022-tac-life-support). I'll start going through the source code when I get a chance, but not having done something like this before, will it be obvious where to modify the packet definition in the dll?

Also, just a note, I saved the telemetry to a file and loaded it up in Python to plot it. Looks like there's an occasional error in some of the data; not a big deal, and actually almost desirable from a realism point of view. Here's an example of what I mean:

ksp_altitude_test.png

Another note, I noticed the mission elapsed time reset when I dropped the launch stage on this vehicle; is that expected? I haven't done the test with a multi-stage rocket yet, so I don't know if it's a characteristic of dropping to the reentry vehicle only or not.

ksp_met_test.png

Link to comment
Share on other sites

The video is from a much older version, when there was handshake at main menu.

Unfortunately it would not be possible to make the plugin compatible with all the possible mods people want to use, I have a hard enough time debugging software, firmware, and hardware problems over the intarwebs as it is, imagine having to test with all the possible combinations of mods! If you want additional functionality from a mod, I would suggest you simply fork the plugin code and maintain your own version, like cm2227 with his mechjeb version.

Are you using your own code for capturing data or the arduino code? In my code the data packets are error checked so it is very unlikely to have packet errors, they are probably caused by KSP itself. MET is just FlightGlobals.ActiveVessel.missionTime, donno why it would reset. I don't really use it in my own display, so I have not really test it much.

Link to comment
Share on other sites

Yes, my own code, and no, I did mean the ksp packets have errors. I am error checking, and they were all received correctly, so the errors are with ksp, not the serial stream. It does mean some checking may be required if someone wants to build a flight computer or autopilot system, to not react to bad data, but for display purposes it won't even be seen.

Thanks again; I'll let you know if I'm successful at forking the code.

Link to comment
Share on other sites

  • 2 weeks later...

I'm having problems getting the precision control and the map view controls working. I've looked over the code to make sure that it isn't a typo.

Precision Code:

 
if (digitalRead(PRECPIN))
MainControls(PRECISION, HIGH);
else
MainControls(PRECISION, LOW);

Map Switch Code:


if (digitalRead(MODEPIN))
{
if (CPacket.Mode==4){
MapScene(0,HIGH);
MapScene(2,LOW);
}else{
MapScene(2,HIGH);
MapScene(0,LOW);
}
}

MapScene Function:


void MapScene(byte n, boolean s) {
if (s)
CPacket.Mode |= (1 << n);
else
CPacket.Mode &= ~(1 << n);
}

Edited by jandcando
Link to comment
Share on other sites

@ jandcando

Oh thanks so much for telling me! I was getting very frustrated. Are there any other things that are not yet implemented that I should know about? Is the precision one of them?

Edited by jandcando
Link to comment
Share on other sites

  • 2 weeks later...

There are a lot of things I'd like to implement, but don't know how to get KSP to do things. Like Precision, Map, Stage lock etc. The easiest way to do stage lock is just to do it in hardware, put a guard on your switch/button, or add a separate switch that physically disables your launch button.

You can also get a Leonardo or something to emulate keyboard buttons.

Edit: see this one by Mulbin! http://forum.kerbalspaceprogram.com/threads/66393-Hardware-Plugin-Arduino-based-physical-display-serial-port-io-tutorial-%2821-Jul%29?p=999420&viewfull=1#post999420

Edited by zitronen
Link to comment
Share on other sites

Is there a reason the payload length is limited to 255 bytes other than limiting the value of in the header to a single byte? I'm wondering about changing it to a uint16, which would in principle allow payloads of up to 65535 bytes. (Serial transmission rate, sampling frequency, etc. would have to adjust to accommodate, of course.)

What I'm thinking is that this mod could resurrect, in part, some of the functionality of the apparently defunct Flight-Recorder (http://forum.kerbalspaceprogram.com/threads/52403-0-21-1-Flight-Recorder); we could add a part that lets us include data from other rocket parts we want to monitor specifically. (Think temperatures of vital pieces for use with Deadly Reentry, or charge rate from solar panels, or monitoring remaining fuel per stage rather than total fuel, etc.) I'm still trying to track down a copy of the original source code from the Flight-Recorder mod.

Edit: Found it! Forum won't let me put in the link cleanly, for some reason. http://.....................com/space/modpart-flight-recorder-979.html, domain is at kerbal space parts

Edited by drmag
Adding supplementary link to source code
Link to comment
Share on other sites

It is certainly possible to make the packet longer, but remember this is made for micro controllers like the arduino, which have very limited RAM (2KB). So 255 bytes is already a large chunk of the available memory, not even taking into account the RAM need for serial buffer and processing the packet.

Link to comment
Share on other sites

Hi there!

First, I want to thank you for this amazing plugin - I've been wanting to build a flight computer for a while! So thankyou for making that idea a reality! :D

I was wondering how it might be possible to add more flight data into the plugin itself? I'm reasonably proficient with Arduinos, but know nothing of the PC side. I was thinking things like Horizontal land speed, What the current SOI is, and possibly the (many, many) variables that make up the navball? I am asking because I am hoping to make a complete cockpit without relying on any HUD on screen...

I will post pics of my panel based on this plugin as well, once I can get them hosted, though at the moment half of it is breadboard and wires :P

Thanks again! :D

-Amelia Eatyaheart

Link to comment
Share on other sites

Well, to add more stuff you kind of have to know C# and how KSP plugins work. I will try to add horizontal speed, pitch, roll, and heading angles this weekend. SOI is a bit more tricky, I would have to think about it.

Edit: you should be able to calculate horizontal velocity from surface velocity and vertical velocity. Since Hv^2 + Vv^2 = Sv^2

Edited by zitronen
Link to comment
Share on other sites

Not so weekly "Weekly" update 12

Changed:

Added roll, pitch and heading output

All right guys, getting the roll, pitch and heading stuff from KSP was harder than expected. Since the rotation is relative to the world which is inconveniently not flat nor stationary. Luckily after stealing some code from mechjeb, now you have these vital information which can be used to build your own hardware navball and/or autopilot!

Plugin:

https://sites.google.com/site/zitronfiles/KSPSerialIO_015_3.zip

Arduino Code

https://sites.google.com/site/zitronfiles/KSPIODemo8.zip

Link to comment
Share on other sites

  • 2 weeks later...

Hey everyone :)

In case other people are also wanting to work with the current SOI, I have worked out a way to calculate it.

It's a bit... :confused:, but it works :)


#define NoSOI -1
#define KerbolSOI 0
#define KerbinSOI 1
#define MunSOI 2
#define MinmusSOI 3
#define MohoSOI 4
#define EveSOI 5
#define DunaSOI 6
#define IkeSOI 7
#define JoolSOI 8
#define LaytheSOI 9
#define VallSOI 10
#define BopSOI 11
#define TyloSOI 12
#define GillySOI 13
#define PolSOI 14
#define DresSOI 15
#define EElooSOI 16
//same codes as in a savefile


double Oldecc=-1;//keep value of orbital eccentricity for comparison next loop
int currentSOI=-1;

void UpdateDisplayOnNewPacket()
{
if (Oldecc==-1 || currentSOI==-1) currentSOI=resolveSOI();//force refresh if SOI unknown.
else if (Oldecc<=1 && VData.e>1) currentSOI=resolveSOI();//force refresh of SOI if orbit jumps to hyperbolic (e.g. entering a smaller SOI)
else if (Oldecc>=1 && VData.e<1) currentSOI=resolveSOI();//e.g. jumping to solar from planetary
else if ( (VData.e>(Oldecc*1.05) ) || (VData.e<(Oldecc*0.95) ) ) currentSOI=resolveSOI();
//force refresh if the eccentricity 'jumps'; indicates an SOI change without a hyperbolic orbit (e.g. Laythe horseshoe orbit)
//'resolveSOI' could be run every loop, but conditional states used to save some processor time.


//add more display update code here
...
Oldecc=VData.e; //preserve data for next run through loop
}


//--------//


double resolveSOI()
{
//will attempt to find mu, and from that, figure out which world we're orbiting.

//eqn: mu=v^2 / ( (2/OrbRad)-(1/SMA) ) for e<>1.
//eqn: mu=(V^2 * OrbRad)/2 for e==1 aka parabolic orbit.
//all distances in this function are expressed in km, not m, hence a lot of n/1000.
//references- http://en.wikipedia.org/wiki/Hyperbolic_trajectory#Velocity
//http://en.wikipedia.org/wiki/Orbital_mechanics#Formulae_for_free_orbits

double SemiMajorKm=VData.SemiMajorAxis/1000;
double mu=0;
double _BodyRadius=0;

if (VData.e>1 && SemiMajorKm>0) SemiMajorKm=-SemiMajorKm;//SMA must be a negative figure for e>1.
//this is a catch-all - hyper orbits in KSP always have a -ive SMA.
_BodyRadius=((SemiMajorKm*2)-(VData.AP/1000)-(VData.PE/1000))/2;
double vsquared=(VData.VOrbit/1000)*(VData.VOrbit/1000);
if (VData.e!=1) mu=(vsquared)/( (2/(VData.Alt/1000 + _BodyRadius))-(1/SemiMajorKm) );
else mu=(vsquared)*(2/(VData.Alt/1000 + _BodyRadius))/2;



//value will be comparable to wiki mu values, divide 10^10 (conversion factor of m^3 -> km^3

if (mu<=0) return -1;//calculation error
if ( (3531.6*0.95)<mu && mu<(3531.6*1.05) ) return KerbinSOI;
else if ( (65.138398*0.95)<mu && mu<(65.138398*1.05) ) return MunSOI;
else if ( (1.7658*0.95)<mu && mu<(1.7658*1.05) ) return MinmusSOI;
else if ( (168.60938*0.95)<mu && mu<(168.60938*1.05) ) return MohoSOI;
else if ( (8171.7302*0.95)<mu && mu<(8171.7302*1.05) ) return EveSOI;
else if ( (301.36321*0.95)<mu && mu<(301.36321*1.05) ) return DunaSOI;
else if ( (18.568369*0.95)<mu && mu<(18.568369*1.05) ) return IkeSOI;
else if ( (282528*0.95)<mu && mu<(282528*1.05) ) return JoolSOI;
else if ( (1962*0.95)<mu && mu<(1962*1.05) ) return LaytheSOI;
else if ( (207.48150*0.95)<mu && mu<(207.48150*1.05) ) return VallSOI;
else if ( (2.4868349*0.95)<mu && mu<(2.4868349*1.05) ) return BopSOI;
else if ( (2825.2800*0.95)<mu && mu<(2825.2800*1.05) ) return TyloSOI;
else if ( (0.0082894498*0.95)<mu && mu<(0.0082894498*1.05) ) return GillySOI;
else if ( (0.72170208*0.95)<mu && mu<(0.72170208*1.05) ) return PolSOI;
else if ( (21.484489*0.95)<mu && mu<(21.484489*1.05) ) return DresSOI;
else if ( (74.410815*0.95)<mu && mu<(74.410815*1.05) ) return EElooSOI;
else if ( (1172332800*0.95)<mu && mu<(1172332800*1.05) ) return KerbolSOI;

return mu; //catch-all line - unknown value, returning calc result for analysis.


}

Limitations: Cannot calculate SOI unless orbit is closed aka eccentricity<1, however, that also provides an easy way to flush the old SOI when escaping or entering a planetary/lunar system, so this function does not need to be constantly scanned.

Updated: Can now calculate SOI regardless of whether elliptical, parabolic, or hyperbolic aka escape trajectory.

Also, I promised pics once I got them uploaded - I know photobucket's not the best, but it works :)

So, once again, thankyou zitronen, for this wonderful plugin! :D

20140722_160355.jpg

20140808_143325.jpg

kerbal_panel_fuelgauges.jpg

Edited by AmeliaEatyaheart
Updated code block.
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.

Guest
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...