In this chapter, I have described the basic software
communication with CHcomm Com port signals and Portdrv Com port signals.
Jim's motion platform makes use of a utility called CHcomm3
written by Claude Hanssens. Check
http://www.jimspage.co.nz/main.htm for more info how to get it and
install it.
This is indeed a wonderful utility that lets you select certain parameters
from FS2004 and send it to the com1 port. Jim has written the GWbasic
program that reads the data, makes some conversions and then drive relays
via the parallel port.
Jim's software is written such that it detects a change in pitch and roll (≥
2 degrees different from previous read cycle) and then switches a relay that
will drive the platform motor to get the platform moving in the direction of
the change. As soon as the pitch / roll change is less that 2 degrees, the
motor is switched off, and the platform will automatically return to center.
I have done some software experiments based on the same principle, but
instead of driving relays, I send the data to the
Parallel Port DAC interface.
The software is based on
Jim's motion.bas, with some modifications.
An example of reading the com port is shown in the following GWbasic program:
20 ON ERROR GOTO 140
30 CLOSE #1
40 OPEN "com1:9600,n,8" FOR RANDOM AS #1
50 A$=""
55 ON ERROR GOTO 50
60 LINE INPUT#1, A$
100 PRINT A$
120 GOTO 50
140 RESUME 20
If you run the above GWbasic program in a DOS box while the flightsim is
running on the other PC with CHcomm active, you will see the flightsim data that is send
over the Com1
port on the screen of the second PC. (CHcomm.cfg file same as Jim's).
Once you got that working, you will see that CHcomm will send the pitch
and roll data as ASCII is the format +009–012 where +009 is pitch down
9 degrees and –012 is roll right 12 degrees.
The max update speed of the CHcomm utility is 200msec. (I actually measured 215msec, by measuring a
parallel port bit from an out 888,1 out 888,0 command inserted in the
loop)
Now the pitch and roll numbers must be extracted from the +009–012
example string.
20 ON ERROR GOTO 140
30 CLOSE #1
40 OPEN "com1:9600,n,8" FOR RANDOM AS #1
50 A$=""
55 ON ERROR GOTO 50
60 LINE INPUT#1, A$
70 R=VAL(RIGHT$(A$,4))
80 P=VAL(LEFT$(A$,5))
95 PRINT P;R
130 GOTO 50
140 RESUME 20
The above program will print the following data: R is roll data, P is
pitch data
The R and P data can now be send to the parallel port for
driving the DAC's. An offset has to be applied to get the 0 degrees
in the center of the DAC range (128).
When doing a looping in the Extra, you will find that the pitch and roll
data do not show what you'd expect: When pitch is > –65 degrees or so, the
roll angle starts increasing and pitch decreases again, till you end up with
0 degrees pitch and 180 degrees roll at the top of the loop (when you are
flying inverted). Continuing the loop will result in roll changing sign and
decreasing, while the pitch increases, going to max +85 degrees then back to
0. Roll will be back at zero at about +64 degrees pitch. I think the pitch
and roll data exactly follows the attitude plate, that will also flip over
twice when going through a loop.
Driving your platform with this kind of data will not make sense. Therefore
I think it's better to limit the platform drive when the pitch data exceeds
+65 or –65 degrees.
In the following program, I have send roll data on one DAC
channel and the pitch data on the 2nd DAC channel (I added a range overflow check to
avoid exceeding the DAC range with roll angle > 64 degrees)
20 ON ERROR GOTO 140
30 CLOSE #1
40 OPEN "com1:9600,n,8" FOR RANDOM AS #1
50 A$=""
55 ON ERROR GOTO 50
60 LINE INPUT#1, A$
70 R=VAL(RIGHT$(A$,4))
80 P=VAL(LEFT$(A$,5))
90 DAC1=2*R+127
94 DAC2=2*P+127
95 PRINT P;R;DAC1;DAC2
96 IF DAC1>255 or DAC1<0 then goto 115
111 OUT 888,DAC1
112 OUT 890,3
113 OUT 890,11
115 IF DAC2>255 or DAC2<0 then goto 130
117 OUT 888,DAC2
118 OUT 890,9
119 OUT 890,11
130 GOTO 50
140 RESUME 20
Experiments with Portdrv utility com port signals
As mentioned in Interfacing , the Portdrv
utility also sends pitch and roll info via the Com port. It has a faster
update speed, and this can be an advantage when fast response motion
signals are wanted.
The same com port reading software can be used as with CHcomm, as long as
you make sure the baud setting is the same as the info in the portdrv.cfg file.
The format in which the info is send is as following: KDPPRRCC
where KD is a header, PP is pitch info and RR is roll
data and CC contains some interesting dashboard indication info. All info
is send as hex format.
To extract the pitch and roll info, I used the GWbasic MID command.
70 P$=mid$(A$,3,2)
To convert the hex to decimal, I used a lookup instruction (after
checking various examples on the net)
85 P=INSTR("123456789ABCDEF",right$(P$,1))+16*INSTR("123456789ABCDEF",left$(P$,1))
Now that I got this worked out I was able to check the pitch and roll
data printed on screen during flight. Output is for testing roll and pitch
data. Note that Portdrvr has build in offset and scaling. In this case no
overflow can occur.
20 ON ERROR GOTO 140
30 CLOSE #1
40 OPEN "com1:9600,n,8" FOR RANDOM AS #1
50 A$=""
55 ON ERROR GOTO 50
60 LINE INPUT#1, A$
70 P$=mid$(A$,3,2)
80 R$=mid$(A$,5,2)
85 P=INSTR("123456789ABCDEF",right$(P$,1))+16*INSTR("123456789ABCDEF",left$(P$,1))
86 R=INSTR("123456789ABCDEF",right$(R$,1))+16*INSTR("123456789ABCDEF",left$(R$,1))
90 DAC1=R
91 DAC2=P
100 PRINT DAC1;" "DAC2
111 OUT 888,DAC1
112 OUT 890,3
113 OUT 890,11
117 OUT 888,DAC2
118 OUT 890,9
119 OUT 890,11
130 GOTO 50
140 RESUME 20
For extracting the dashboard indication byte, the following code can be
used.
85 D=INSTR("123456789ABCDEF",right$(D$,1))+16*INSTR("123456789ABCDEF",left$(D$,1))
This byte contains the following info:
bit 0 = landing lights
bit 1 = wheels on ground
bit 2 = stall
bit 3 = overspeed
bit 4 = auto pilot on|
bit 5 = brakes on
bit 6 = landing gear
bit 7 = flaps
To activate a certain effect can be done by AND
function:
90 IF D AND 2^7 GOTO 95 else GOTO 120
extract the dashboard indicator byte from Portdrv utility (7th bit = extend
flaps)
The above examples I have send pitch and roll directly to the DAC's that drive the
platform pitch and roll. You'll find that this will not result in realistic
motion. To get more convincing motion, a lot of tweaking needs to be done,
where de data from FS will only be used to trigger certain effects, instead
of directly driving the platform axis. The subchapters below describe the
various "motion tweaking" subjects.
Note on GWbasic program timing:
With the Portdrv utility, the update speed is in the order of 45msec. This
means that the complete program for driving the DAC's needs to be finished
well within 45msec. My GWbasic motion software is running on a Pentium 1
200MHz PC. I measured the speed of some executions within the program, (by
inserting certain output to DAC commands). Generally, GWbasic runs pretty
fast on a Pentium. Below the measurements and test program (random vibration
with sine interpolation) for checking speed.
20 ON ERROR GOTO 140
30 CLOSE #1
40 OPEN "com1:9600,n,8" FOR RANDOM AS #1
50 OUT 888,0 ' +18usec
51 OUT 890,9
52 OUT 890,11
53 A$=""
55 ON ERROR GOTO 50
57 OUT 888,20 '+24usec
58 OUT 890,9
59 OUT 890,11
60 LINE INPUT#1, A$
62 OUT 888,50 '+ 45msec (wait for data)
63 OUT 890,9
64 OUT 890,11
70 P$=mid$(A$,3,2)
80 R$=mid$(A$,5,2)
81 D$=right$(A$,2)
82 OUT 888,60 '+44usec
83 OUT 890,9
84 OUT 890,11
85 P=INSTR("123456789ABCDEF",right$(P$,1))+16*INSTR("123456789ABCDEF",left$(P$,1))
86 R=INSTR("123456789ABCDEF",right$(R$,1))+16*INSTR("123456789ABCDEF",left$(R$,1))
87 D=INSTR("123456789ABCDEF",right$(D$,1))+16*INSTR("123456789ABCDEF",left$(D$,1))
90 IF D AND 2^7 GOTO 92 else Rout=50:GOTO 120
92 OUT 888,100 '+118usec
93 OUT 890,9
94 OUT 890,11
100 N=N+1
101 'PRINT N, ROLD, RNEW, Rout: 'will add ~ 5msec
102 IF N=0 then Rout=ROLD
103 IF N=1 then Rout=INT((RNEW-ROLD)*0.011+ROLD)
104 IF N=2 then Rout=INT((RNEW-ROLD)*0.043+ROLD)
105 IF N=3 then Rout=INT((RNEW-ROLD)*0.095+ROLD)
106 IF N=4 then Rout=INT((RNEW-ROLD)*0.165+ROLD)
107 IF N=5 then Rout=INT((RNEW-ROLD)*0.25+ROLD)
108 IF N=6 then Rout=INT((RNEW-ROLD)*0.345+ROLD)
109 IF N=7 then Rout=INT((RNEW-ROLD)*0.447+ROLD)
110 IF N=8 then Rout=INT((RNEW-ROLD)*0.552+ROLD)
111 IF N=9 then Rout=INT((RNEW-ROLD)*0.654+ROLD)
112 IF N=10 then Rout=INT((RNEW-ROLD)*0.75+ROLD)
113 IF N=11 then Rout=INT((RNEW-ROLD)*0.834+ROLD)
114 IF N=12 then Rout=INT((RNEW-ROLD)*0.904+ROLD)
115 IF N=13 then Rout=INT((RNEW-ROLD)*0.956+ROLD)
116 IF N=14 then Rout=INT((RNEW-ROLD)*0.989+ROLD)
117 IF N=15 then Rout=RNEW:ROLD=RNEW:RNEW=INT(RND*100):N=-1
118 OUT 888,130 '+200usec
119 OUT 890,9
120 OUT 890,11
121 DAC1=50+Rout
122 DAC2=127
123 IF DAC1>255 or DAC1<0 then goto 127
124 OUT 888,DAC1
125 OUT 890,3
126 OUT 890,11
127 IF DAC2>255 or DAC2<0 then goto 131
128 OUT 888,255 '+84usec
129 OUT 890,9
130 OUT 890,11
131 GOTO 50
140 RESUME 20
As can be seen, there is no critical speed issue. The complete program as
shown above will finish within 0.5msec. Only when inserting a print command,
the timing will be increased with 5msec.
Line 60 is the point where the program will wait for new input from serial
port.
Data Extraction Portdrvr Utility Roll & Pitch Derivative Roll and Washout Random Vibrations Runway Effects Take-off Effects Landing effects G-parameter