GPS Simulator Code

Near space is the poorman's space program. It permits you to fly experiments into a space like environment for a faction of the cost of a satellite launch. This forum is where Nuts and Volts readers can share information and data from near space missions - both past flights and those under preparation.

Moderator: Paul Verhage

Post Reply
Paul Verhage
Posts: 22
Joined: Wed Aug 03, 2011 10:01 am
Contact:

GPS Simulator Code

Post by Paul Verhage » Mon Jan 09, 2012 12:49 pm

I forgot to give N&V the code for my GPS Simulator article, so I've attached it here. To use it, copy the text, paste it into Notepad, and give it a name ending in .BAS.

By the way, NearSys LLC is selling the GPS simulator as a kit. See it at, http://nearsys.com/catalog/sensor/gpssim.htm

Onwards and Upwards,
Your Near Space Guide

'******************************************************************
'* NearSys GPS Simulator V.2.2.5 *
'* *
'* Note: Define the mission by setting the first ten parameters *
'* GPS sentences transmitted every second *
'* Ascent rate after knee = 80% of initial ascent rate *
'* Wind heading at 135 degrees, speed varies based on altitude *
'* PIN0 determines when launch takes place *
'* PIN1 determines status of GPS lock *
'* GPS lock LED *
'* Lock: LED = green *
'* Lost of lock: LED = red *
'* Launch LED *
'* On the ground: LED = off *
'* Ascent: LED = green *
'* Descent: LED = red *
'* Floating: LED blinks between red and green *
'* Sentences transmitted are: GGA, GGL, GSA, GSV, RMC, VTG *
'* GPZDA was dropped to keep sentence update to once per second *
'* Current altitude is displayed over programming port at 9600 *
'* LPV 11 June 2011 *
'******************************************************************

' ** Set these parameters for each simulation **
symbol StartHour = 14 ' hour (UTC) at beginning of simulation
symbol Day = 13 ' day of the simulation
symbol Month = 06 ' month of the simulation
symbol Year = 11 ' last two digits of year of the simulation
symbol LaunchAltitude = 290 ' altitude of launch site in meters - can't launch from higher than Mt. Everest
symbol AscentRate = 1200 ' ascent rate in feet/minute
symbol FloatAltitude = 35000 ' floating altitude of balloon, if higher than burst, no floating
symbol BurstAltitude = 26000 ' altitude of balloon burst in meters
symbol DescentRate = 1000 ' descent rate at sea level
symbol RecoveryAltitude = 320 ' altitude or recovery zone in meters

' ** Don't need to change these constants **
symbol Hemisphere = "W" ' west or east
symbol CourseMag = 135
symbol CourseTrue = 149

' ** Variables **
symbol Launched = Bit0 ' 0 = not launched, 1 = launched - LED is off
symbol Landed = Bit1 ' 0 = not landed, 1 = landed - LED is off
symbol Ascent = Bit2 ' 0 = not ascending, 1 = ascending - LED is green
symbol Descent = Bit3 ' 0 = not descending, 1 = descending - LED is red
symbol Float = Bit4 ' 0 = not floating, 1 = floating - LED flashes red and green
symbol PrevLock = Bit5 ' was lock button pressed (0) or unpressed (1) last time
symbol Conditions = B0
symbol GPSHour = B1
symbol GPSMinute1 = B2
symbol GPSMinute2 = B3
symbol GPSSecond1 = B4
symbol GPSSecond2 = B5
symbol GPSLatDeg = B6
symbol GPSLatMin1 = B7
symbol GPSLatMin2 = B8
symbol GPSLatDecMin1 = B9
symbol GPSLatDecMin2 = B10
symbol GPSLatDecMin3 = B11
symbol GPSLatDecMin4 = B12
symbol Fix = B13
symbol Speed = B14
symbol KMPH = B15
symbol GPSAlt1 = B16
symbol GPSAlt2 = B17
symbol GPSAlt3 = B18
symbol GPSAlt4 = B19
symbol GPSAlt5 = B20
symbol WorkByte = B21
symbol RandomAmount = W11 ' can't use random amount and random word at same time
symbol RandomByte = B23
symbol WorkWord = W12
symbol WorkSpace = W13

Simulator_Initialization:
setfreq M8 ' run at 8 MHz
high 4 ' set lock LED red
low 5 ' set lock LED red
Conditions = 32 ' set PrevLock = lock button unpressed
RandomAmount = LaunchAltitude + AscentRate + FloatAltitude + BurstAltitude + RecoveryAltitude
GPSLatDeg = 6 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatMin1 = 5 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatMin2 = 9 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatDecMin1 = 9 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatDecMin2 = 9 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatDecMin3 = 9 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSLatDecMin4 = 9 ' begin at 36 deg 59.9999 and 96 deg 59.9999
GPSAlt1 = 0 ' load launch altitude into current altitude
GPSAlt2 = LaunchAltitude/1000 ' load launch altitude into current altitude
WorkSpace = GPSAlt2 * 10 ' load launch altitude into current altitude
GPSAlt3 = LaunchAltitude/100 ' load launch altitude into current altitude
GPSAlt3 = GPSAlt3 - WorkSpace ' load launch altitude into current altitude
WorkSpace = WorkSpace + GPSAlt3 ' load launch altitude into current altitude
WorkSpace = WorkSpace * 10 ' load launch altitude into current altitude
GPSAlt4 = LaunchAltitude/10 ' load launch altitude into current altitude
GPSAlt4 = GPSAlt4 - WorkSpace ' load launch altitude into current altitude
WorkSpace = WorkSpace + GPSAlt4 ' load launch altitude into current altitude
WorkSpace = WorkSpace * 10 ' load launch altitude into current altitude
GPSAlt5 = LaunchAltitude - WorkSpace ' load launch altitude into current altitude
Fix = 1 ' no fix
Speed = 0 ' on the ground - no speed
KMPH = 0 ' on the ground - no speed

GPS_Simulator:
for GPSHour = StartHour to 23 ' mission time from HR:00:00 to 23:59:59
for GPSMinute1 = 0 to 5 ' mission time from HR:00:00 to 23:59:59
for GPSMinute2 = 0 to 9 ' mission time from HR:00:00 to 23:59:59
for GPSSecond1 = 0 to 5 ' mission time from HR:00:00 to 23:59:59
for GPSSecond2 = 0 to 9 ' mission time from HR:00:00 to 23:59:59
' pause 50 ' tweak value to get timing correct (once per second)

CheckLockButton:
if pin0 = PrevLock then CheckLaunchButton ' no change in lock button from last time
PrevLock = pin0 ' update current status of button
if pin0 = 0 and Fix = 1 then ' change fix status if lock button is pressed
Fix = 3 ' lock gained
toggle 4,5 ' so change lock LED green
elseif pin0 = 0 and Fix = 3 then ' change fix status if lock button is pressed
Fix = 1 ' lock lost
toggle 4,5 ; so change lock LED red
endif

CheckLaunchButton:
if pin1 = 0 AND Launched = 0 then ' if launch button is pushed
Launched = 1 ' go to ascent mode
Ascent = 1 ' go to ascent mode
low 6 ' set launch led green
high 7 ' set launch led green
endif

CheckFlightPhase:
if Launched = 0 OR Landed = 1 then AddJitter ' haven't launched
if Float = 1 then UpdateLatLong ' floating

UpdateAltitude:
WorkWord = GPSAlt1*10 + GPSAlt2*10 + GPSAlt3*10 + GPSAlt4*10 + GPSAlt5
if Ascent = 1 then ' if in ascending phase
WorkByte = AscentRate/197 ' convert ft/m to m/s
if WorkWord > 12500 then ' if altitude > 40,000 ft
WorkByte = WorkByte * 8/10 ' adjust ft/s above 40,000 to 80%
endif
WorkWord = WorkWord + WorkByte ' update ascent altitude
if WorkWord > FloatAltitude then ' if current altitude > float altitude
Float = 1 ' now floating
elseif WorkWord > BurstAltitude then ' if current altitude > burst altitude
high 6 ' change launch LED to red
low 7 ' change launch LED to red
Descent = 1 ' set to descent phase
Ascent = 0 ' set to descent phase
endif
else ' if in descending phase
WorkByte = WorkWord/5500*3/2 ' calculate descent speed based altitude
if WorkByte = 0 then
WorkByte = 1
endif
WorkByte = WorkByte * DescentRate/60*5/16
WorkWord = WorkWord - WorkByte ' update descent altitude
if WorkWord < RecoveryAltitude then ' if below landing altitude
WorkWord = RecoveryAltitude ' current altitude = recovery altitude
Landed = 1 ' status is now landed
Speed = 0 ' no horizontal speed
low 6 ' turn off launch LED
low 7 ' turn off launch LED
endif
endif
GPSAlt1 = WorkWord/10000 ' Change current altitude into individual digits
WorkSpace = GPSAlt1 * 10 ' Change current altitude into individual digits
GPSAlt2 = WorkWord/1000 ' Change current altitude into individual digits
GPSAlt2 = GPSAlt2 - WorkSpace ' Change current altitude into individual digits
WorkSpace = WorkSpace + GPSAlt2 ' Change current altitude into individual digits
WorkSpace = WorkSpace * 10 ' Change current altitude into individual digits
GPSAlt3 = WorkWord/100 ' Change current altitude into individual digits
GPSAlt3 = GPSAlt3 - WorkSpace ' Change current altitude into individual digits
WorkSpace = WorkSpace + GPSAlt3 ' Change current altitude into individual digits
WorkSpace = WorkSpace * 10 ' Change current altitude into individual digits
GPSAlt4 = WorkWord/10 ' Change current altitude into individual digits
GPSAlt4 = GPSAlt4 - WorkSpace ' Change current altitude into individual digits
WorkSpace = WorkSpace + GPSAlt4 ' Change current altitude into individual digits
WorkSpace = WorkSpace * 10 ' Change current altitude into individual digits
GPSAlt5 = WorkWord - WorkSpace ' Change current altitude into individual digits

UpdateSpeed:
if Landed = 1 then ' if on the ground
Speed = 0 ' no speed
goto CalcKMPH
else ' if in the air
if WorkWord < 9000 then ' and altitude > 9 km
Speed = WorkWord/1000 ' calculate air speed (no wind < 1 km)
else
if WorkWord < 12000 then ; if current altitude between 9 km and 12 km
WorkWord = WorkWord - 9000 ' calculate air speed between 9-12 km
Speed = WorkWord/1000*9+9
else
if WorkWord < 15000 then ' calculate air speed between 12-15 km
WorkWord = 15000 - WorkWord
Speed = WorkWord/1000*9+9
else
Speed = 6 ' air speed above 15km = 6 m/s
endif
endif
endif
endif

UpdateLatLong:
if Float = 1 then ' if floating, then toggle launch LED
toggle 6,7
endif
WorkWord = GPSLatDecMin1*10 + GPSLatDecMin2*10 + GPSLatDecMin3*10 + GPSLatDecMin4
WorkByte = Speed * 6
if WorkWord > WorkByte then ' decrease in lat/long does not cause overflow
WorkWord = WorkWord - WorkByte
else
WorkWord = 9999 - WorkByte
GPSLatMin2 = GPSLatMin2 - 1
if GPSLatMin2 > 9 then
GPSLatMin2 = 9
GPSLatMin1 = GPSLatMin1 - 1
if GPSLatMin1 > 9 then
GPSLatMin1 = 9
GPSLatDeg = GPSLatDeg - 1
endif
endif
endif
GPSLatDecMin1 = WorkWord/1000 ' Change current decimal min into individual digits
WorkSpace = GPSLatDecMin1 * 10 ' Change current decimal min into individual digits
GPSLatDecMin2 = WorkWord/100 ' Change current decimal min into individual digits
GPSLatDecMin2 = GPSLatDecMin2 - WorkSpace ' Change current decimal min into individual digits
WorkSpace = WorkSpace + GPSLatDecMin2 ' Change current decimal min into individual digits
WorkSpace = WorkSpace * 10 ' Change current decimal min into individual digits
GPSLatDecMin3 = WorkWord/10 ' Change current decimal min into individual digits
GPSLatDecMin3 = GPSLatDecMin3 - WorkSpace ' Change current decimal min into individual digits
WorkSpace = WorkSpace + GPSLatDecMin3 ' Change current decimal min into individual digits
WorkSpace = WorkSpace * 10 ' Change current decimal min into individual digits
GPSLatDecMin4 = WorkWord - WorkSpace ' Change current decimal min into individual digits
Speed = Speed * 2 ' convert speed to knots

CalcKMPH:
KMPH = Speed * 7/5 ' calculate km/hr from knots

AddJitter: ' flucuation in altitude
poke 28,GPSAlt5 ' store last digit of altitude
random RandomAmount ' by a random amount
GPSAlt5 = RandomAmount/7300 ' that's no larger than 9

DisplayGPS:
if FIX = 3 then ' display sentences with GPS fic
serout 1,N4800_8,("$GPGGA,",#GPSHour,#GPSMinute1,#GPSMinute2,#GPSSecond1,#GPSSecond2,".00,3",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",N,09",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",",Hemisphere,",1,06,01.5,",#GPSAlt1,#GPSAlt2,#GPSAlt3,#GPSAlt4,#GPSAlt5,".0,M,0016.3,M,,*5C",CR,LF)
serout 1,N4800_8,("$GPGLL,3",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",N,09",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",W,1",#GPSHour,#GPSMinute1,#GPSMinute2,#GPSSecond1,#GPSSecond2,"00,A,A*65",CR,LF)
serout 1,N4800_8,("$GPGSA,A,3,1,2,3,4,5,6,1.8,1.5,1.6*07",CR,LF)
serout 1,N4800_8,("$GPGSV,0,0,06,26,50,016,40,09,50,173,39,21,43,316,38,17,41,144,42*7C",CR,LF)
serout 1,N4800_8,("$GPRMC,",#GPSHour,#GPSMinute1,#GPSMinute2,#GPSSecond1,#GPSSecond2,".00,A,3",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",N,09",#GPSLatDeg,#GPSLatMin1,#GPSLatMin2,".",#GPSLatDecMin1,#GPSLatDecMin2,#GPSLatDecMin3,#GPSLatDecMin4,",",Hemisphere,",",#Speed,".0,140.0,",#Day,#Month,#Year,",005.0,W,A*22",CR,LF)
serout 1,N4800_8,("$GPVTG,135.0,T,140.0,M,",#SPEED,".0,N,",#KMPH,".0,K,A*1F",CR,LF)
'serout 1,N4800_8,("$GPZDA,",#GPSHour,#GPSMinute1,#GPSMinute2,#GPSSecond1,#GPSSecond2,".00",Day,",",Month,",20",Year,",*6C",CR,LF)
else ' display sentences without GPS fix
serout 1,N4800_8,("$GPGGA,000000.00,0000.0000,N,00000.0000,W,0,00,10.5,00000.0,M,0016.3,M,,*5C",CR,LF)
serout 1,N4800_8,("$GPGLL,3000.0000,N,00000.0000,W,1,000000.00,A,A*65",CR,LF)
serout 1,N4800_8,("$GPGSA,A,1,,,,,6*07",CR,LF)
serout 1,N4800_8,("$GPGSV,0,0,00,,,,,42*7C",CR,LF)
serout 1,N4800_8,("$GPRMC,000000.00,V,0000.0000,N,00000.0000,W,000.0,,,,,,W,N*22",CR,LF)
serout 1,N4800_8,("$GPVTG,135.0,T,140.0,M,000,N,000.0,K,A*1F",CR,LF)
'serout 1,N4800_8,("$GPZDA,000000.00,,,,,,,*6C",CR,LF)
endif
sertxd ("Alt: ",#GPSAlt1,#GPSAlt2,#GPSAlt3,#GPSAlt4,#GPSAlt5, "m",CR,LF) ' this will slow down the GPS ~ 10%
peek 28,GPSAlt5 ' replace true last digit
next
next
next
next
next
end

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests