UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


projects:ukhas_glider_project:master
$regfile = "m168def.dat"
$crystal = 16000000
$baud = 16000
$hwstack = 32
$swstack = 64
$framesize = 96
OPEN "comc.4:125000,8,N,1" FOR OUTPUT AS #1
OPEN "comc.3:125000,8,N,1" FOR INPUT AS #2
OPEN "comd.2:4800,8,n,1" FOR INPUT AS #3                    'rx from pc
OPEN "comb.4:19200,8,n,1" FOR OUTPUT AS #4                  'Logger
Config Adc = SINGLE , Prescaler = Auto , Reference = Internal
Config Portd.7 = OUTPUT
Config Portb.0 = OUTPUT
Config Portb.2 = OUTPUT
Config Portb.1 = OUTPUT
Config Portd.2 = INPUT                                      'rx from pc
Config Portd.6 = OUTPUT
Config Portd.3 = INPUT
Config Portc.2 = INPUT
Config Portd.4 = INPUT
Config Portc.1 = OUTPUT
Config Portc.0 = INPUT
Config Portc.5 = INPUT
Config Watchdog = 4096
'Config Portc.4 = Output
'Config Portc.3 = Input
Ledone ALIAS Portd.7
Ledtwo ALIAS Portb.0
Radiocts ALIAS Pind.3
'Cts Alias Portd.2
Groundcontrol ALIAS Pind.4
Statusled ALIAS Portd.6
Requestsecond ALIAS Portc.1
Clearsecond ALIAS Pinc.2
Cutdownpinone ALIAS Portb.1
Cutdownpintwo ALIAS Portb.2
Cutdownpinone = 0
Cutdownpintwo = 0
Baud = 4800
DECLARE SUB Checkvoltage()
DECLARE SUB Cutdown(BYVAL Channel AS Byte , BYVAL Duration AS Byte)
DECLARE SUB Radiocomms()
Echo OFF
Start Adc
DIM Rate AS INTEGER
DIM Temperature AS INTEGER , ERROR AS Byte , Heading AS SINGLE , Filteredrate AS SINGLE , Pulselenght AS Word
DIM Pulses AS Byte
DIM S AS STRING * 100
DIM T AS STRING * 15
DIM Printstring AS STRING * 20
DIM K AS SINGLE
DIM Iterations AS Byte , Flashcount AS Byte
DIM Windxs(251) AS Eram Byte
DIM Windys(251) AS Eram Byte , Placemark AS Eram Byte
DIM Target_es AS Eram SINGLE
DIM Target_ns AS Eram SINGLE
DIM LOCK AS Bit
DIM Gpfloatone AS SINGLE , Gpsheading AS SINGLE
DIM U AS STRING * 100
DIM B AS STRING * 6
DIM Contents(17) AS STRING * 15
DIM Transfer AS STRING * 11
DIM N AS Byte
DIM I AS Byte
DIM Statuscode AS Byte
DIM Heightupto AS Byte , Rxenable AS Byte , Servoenable AS Byte
DIM Gpbyteone AS Byte , Gpbytetwo AS Byte , Telcounter AS Byte , Landcount AS Byte
DIM Gpintegerone AS INTEGER
DIM Intcount AS INTEGER , Timeelapsed AS INTEGER
DIM Store AS INTEGER
DIM Test AS INTEGER
DIM L AS INTEGER
DIM Arrayat AS INTEGER
DIM Rudder AS SINGLE
DIM Integral AS SINGLE
DIM Derivative AS SINGLE
DIM Target AS SINGLE
DIM Target_e AS SINGLE
DIM Target_n AS SINGLE
DIM Offset AS SINGLE
DIM Windy_total AS SINGLE
DIM Windx_total AS SINGLE
DIM Wind_speed AS SINGLE
DIM Airspeed AS SINGLE
DIM X AS SINGLE
DIM Y AS SINGLE
DIM V AS SINGLE , Altitude AS SINGLE
DIM Wind_x AS SINGLE
DIM Wind_y AS SINGLE
DIM North AS SINGLE
DIM East AS SINGLE
DIM Store_east AS SINGLE
DIM Store_north AS SINGLE
DIM V_x AS SINGLE
DIM V_y AS SINGLE
DIM Minutes AS STRING * 7
DIM Degrees AS STRING * 3
DIM Command AS STRING * 10
Statuscode = 0
LOCK = 0
Iterations = 0
Timeelapsed = 0
Wind_x = 0
Wind_y = 0
Landcount = 0
Telcounter = 0
Portd.3 = 1
Waitms 100
Gpintegerone = Getadc(5)
Gpfloatone = Gpintegerone
Gpintegerone = Getadc(0)
Gpfloatone = Gpfloatone / Gpintegerone
IF Gpfloatone < 0.5 AND Gpfloatone > 0.4 THEN
 PRINT "Button pressed"
ELSE
 PRINT "Watchdog reset"
 Start Watchdog
 Target_n = Target_ns
 Target_e = Target_es
 SELECT CASE Placemark
 CASE 1:
 GOTO Cutdownlbl                                            'cutdown if error during ascent
 CASE 2:
 GOTO Descentloop
 CASE ELSE:
 GOTO Cutdownlbl
 END SELECT
END IF
Waitms 50
CALL Checkvoltage()
'Call Cutdown(1 , 4)
PRINT "wind records:"
FOR Gpbyteone = 1 TO 251
 Gpbytetwo = Windxs(gpbyteone)
 PRINT Gpbyteone ; "," ; Gpbytetwo ; "," ;
 Gpbytetwo = Windys(gpbyteone)
 PRINT Gpbytetwo
NEXT
PRINT Version()
PRINT "Demo flight: 4km/20 minute"
PRINT "Now check gps"
DO
 INPUT S
 B = Mid(s , 2 , 6)
 IF B = "$GPGGA" THEN
  PRINT S                                                   'shows us the GGA string
  I = Split(s , Contents(1) , ",")
  K = 0
  K = VAL(contents(10))
  IF K <> 0 THEN                                            'if nonzero altitude then we've got something
   GOTO Gotlock
  END IF
 END IF
LOOP
Gotlock:
PRINT "Okay we have GPS"
PRINT "check rc ground control, then"
PRINT "Enter target north and east"
INPUT #3 , Target_n
PRINT Target_n
INPUT #3 , Target_e
PRINT Target_e
Gpfloatone = Target_ns
IF Target_n <> Gpfloatone THEN Target_ns = Target_n         'store in eeprom
Gpfloatone = Target_es
IF Target_e <> Gpfloatone THEN Target_es = Target_e
Portd.3 = 1
PRINT "Launch!"                                             'radiocts pullup
Start Watchdog
Placemark = 1                                               'write eeprom to say in ascent
DO
 RESET Watchdog
 DO
  INPUT U
  B = Mid(u , 2 , 6)
 LOOP UNTIL B = "$GPGGA"
 DO
  INPUT S
  B = Mid(s , 2 , 6)
 LOOP UNTIL B = "$GPRMC"
   I = Split(s , Contents(1) , ",")                         'process rmc
   K = VAL(contents(9))
   V = VAL(contents(8))
   K = Deg2rad(k)
   Wind_x = SIN(k)                                          'WORK OUT WIND IN Y=NORTH frame - the trig library works in radians
   Wind_x = Wind_x * V
   Wind_y = COS(k)
   Wind_y = Wind_y * V
   Windx_total = Windx_total + Wind_x                       'add it to our total wind
   Windy_total = Windy_total + Wind_y
   Incr L                                                   'incrament the denominator for our averaging
   Incr Timeelapsed
   I = Split(u , Contents(1) , ",")                         'now process gga
   K = VAL(contents(10))
   K = K / 100
   Arrayat = INT(k)                                         'find the altitude in 100m incraments
   IF Arrayat > Heightupto THEN
    Incr Heightupto                                         'do we now fall into another (higher) 100m incrament ?
    Windx_total = Windx_total / L
    Gpbyteone = Windx_total + 127
    Windxs(heightupto) = Gpbyteone                          'we are storing as a signed byte
    Windy_total = Windy_total / L
    Gpbyteone = Windy_total + 127                           'we find the average and shove it in the eeprom
    Windys(heightupto) = Gpbyteone
    L = 0                                                   'this was forgotten in the flight code doh
   END IF
   IF Arrayat > 40 THEN
    PRINT "Altitude cutdown" ; Arrayat
    GOTO Cutdownlbl                                         '4Km/20 minute cutdown
   END IF
   IF Timeelapsed > 1200 THEN
    PRINT "Time cutdown"
    GOTO Cutdownlbl
   END IF
   Requestsecond = 1
   WHILE Clearsecond = 0
    Waitus 10
   WEND
   Requestsecond = 0
   Waitus 50
   Printbin #1 , Statuscode
   Waitus 150                                               'tells slave we are going up
   Inputbin #2 , Rate , Temperature , ERROR
   Incr Telcounter
   IF Telcounter > 10 THEN CALL Checkvoltage()              ' our callsign is UKHAS
   IF Radiocts = 1 THEN                                     'is CTS=1 from the radio modem?
    CALL Radiocomms()
   END IF
LOOP
 
Cutdownlbl:
IF L > 0 THEN                                               'set a valid wind for cutdown altitude
 Wind_x = Windx_total / L
 Wind_y = Windy_total / L
END IF
CALL Cutdown(1 , 12)
Placemark = 2                                               'write eeprom
Descentloop:
Statuscode = 1
Requestsecond = 1
WHILE Clearsecond = 0
 Waitus 10                                                  'I did commented this out as we should give the slave a message 1 second before the first valid gps
WEND                                                        'but that was a stupid idea as in the slave code, when if first enters the decent loop
Requestsecond = 0                                           'it waits for a new gps before doing anything other than running off the gyro
Waitus 50                                                   ' the first update after this then goes into the gps lag compensation stage, but NOT YET !!!!
Printbin #1 , Statuscode                                    'we are going down so let the slave know
 
 
DO
 RESET Watchdog
 'insert
    DO
     INPUT U
     B = Mid(u , 2 , 6)
    LOOP UNTIL B = "$GPGGA"
    DO
     INPUT S
     B = Mid(s , 2 , 6)
    LOOP UNTIL B = "$GPRMC"
   I = Split(s , Contents(1) , ",")                         'process rmc
   Degrees = Left(contents(4) , 2)
   Minutes = Right(contents(4) , 7)
   North = 0
   North = VAL(minutes)
   North = North / 60
   K = 0
   K = VAL(degrees)
   North = K + North
   Degrees = Left(contents(6) , 3)
   Minutes = Right(contents(6) , 7)
   East = 0
   East = VAL(minutes)
   East = East / 60
   K = 0
   K = VAL(degrees)
   East = K + East
   IF Contents(7) = "W" THEN
    East = -east
   END IF
   East = Target_e - East
   K = Deg2rad(north)
   K = COS(k)
   East = East * K                                          'distance to target in equatorial degree units
   North = Target_n - North
   K = East / North
   Target = ATN(k)
   Target = Rad2deg(target)
   IF North < 0 THEN                                        'direction to target
    Target = Target - 180
   END IF
   IF Target < -180 THEN
    Target = Target + 360                                   'gets it in +-180 degree range
   END IF
   K = 0
   K = VAL(contents(9))
   V = 0
   V = VAL(contents(8))
   IF V < 0.5 THEN                                          'off if we crashed
    IF V = 0 THEN
     V = 0.01
    END IF
    Statusled = 0
   ELSE                                                     'indicator LED
    'Incr Timeelapsed
    Toggle Statusled
   END IF
   K = Deg2rad(k)
   X = SIN(k)
   X = X * V
   Y = COS(k)
   Y = Y * V
   X = X - Wind_x                                           'wind compensation  in Y=NORTH frame
   Y = Y - Wind_y
   Airspeed = X * X
   K = Y * Y
   Airspeed = Airspeed + K
   Airspeed = SQR(airspeed)
   IF Y = 0 THEN
    X = 0
    ELSE
    X = X / Y                                               'stops us getting infinity
   END IF
   K = ATN(x)
   K = Rad2deg(k)
   IF Y < 0 THEN
    K = K - 180
   END IF                                                   'all to keep us in +-180 degree range
   IF K < -180 THEN
    K = K + 360                                             'K is now our air vector heading
   END IF
   Gpsheading = K
   K = K - Target                                           'k is now our heading offset (from now on is just for
   IF K < -180 THEN                                         'the pretty leds)
    K = K + 360
   END IF
   IF K > 180 THEN
    K = K - 360
   END IF
   IF K > 0 THEN
    Ledone = 0                                              'left/right indictor LEDs
    Ledtwo = 1
   ELSE
    Ledone = 1
    Ledtwo = 0
   END IF
 'end insert
  I = Split(u , Contents(1) , ",")                          'now we do the gga
  K = VAL(contents(10))
  Altitude = K
 IF V < 0.5 AND Altitude < 250 THEN                         'we have landed ?
  Incr Landcount
 ELSE
  Landcount = 0
 END IF
 IF Landcount > 4 THEN
   Landcount = 5                                            'ie we had 5 stationary gps updates
   Incr Flashcount                                          'flashes leds
   IF Flashcount > 9 THEN
    Cutdownpintwo = 1
    Flashcount = 0
   ELSE
    Cutdownpintwo = 0                                       'turn off landing lights
   END IF
   Servoenable = 0                                          'turn servo off on landing
 ELSE
  IF Altitude < 300 THEN                                    'so we are moving but low
    Cutdownpintwo = 1                                       'turn on landing lights
    Rxenable = 1                                            'enable ground control near the ground
  ELSE
    Cutdownpintwo = 0
    Rxenable = 0
  END IF
  Flashcount = 0
  Servoenable = 1                                           'always enable servo
 END IF
 Requestsecond = 1
 WHILE Clearsecond = 0
  Waitus 10
 WEND
 Requestsecond = 0
 Waitus 50                                                  'make sure slave is ready
 Printbin #1 , Statuscode ; Gpsheading ; Target ; Servoenable ; Rxenable
 Waitus 200
 Inputbin #2 , Rate , Temperature , ERROR , Heading , Filteredrate , Pulselenght , Pulses
 K = K / 100
 Arrayat = INT(k)
 Incr Arrayat                                               'as minimum altitude incrament=0 but array starts at 1
 Gpbyteone = Windxs(arrayat)                                'gives us the correct wind for our altitude
 IF Gpbyteone <> 255 THEN Wind_x = Gpbyteone - 127          'handles an unrecorded eeprom byte
 Gpbyteone = Windys(arrayat)
 IF Gpbyteone <> 255 THEN Wind_y = Gpbyteone - 127          'handles unrecorded
 Incr Telcounter
 IF Telcounter > 10 THEN CALL Checkvoltage()
 IF Radiocts = 1 THEN                                       'is CTS=1 from the radio modem?
  CALL Radiocomms()
 END IF
LOOP
 
SUB Checkvoltage()
S = "UKHASD,"
Gpintegerone = Getadc(5)
Gpfloatone = Gpintegerone
Gpfloatone = Gpfloatone * 9.503
Gpfloatone = Gpfloatone / 1000
Printstring = Str(gpfloatone )                              'servo
S = S + Printstring
S = S + ","
Gpintegerone = Getadc(0)
Gpfloatone = Gpintegerone
Gpfloatone = Gpfloatone * 4.250
Gpfloatone = Gpfloatone / 1000
Printstring = Str(gpfloatone )
S = S + Printstring
S = S + ","
Printstring = Str(pulselenght)
S = S + Printstring
S = S + ","
Printstring = Str(pulses)
S = S + Printstring
PRINT S
PRINT #4 , S
Telcounter = 0
END SUB
 
 
SUB Cutdown(BYVAL Channel AS Byte , BYVAL Duration AS Byte)
Gpbyteone = 0
WHILE Radiocts = 0 AND Gpbyteone < 30                       'wait for radio with timeout
 Waitms 500
 RESET Watchdog
 Incr Gpbyteone
WEND
PRINT "UKHASC,Cutdown channel=" ; Channel ; " Time=" ; Duration
IF Channel = 1 THEN Cutdownpinone = 1
IF Channel = 2 THEN Cutdownpintwo = 1
FOR Gpbyteone = 0 TO Duration
 WAIT 1
 RESET Watchdog
NEXT
Cutdownpinone = 0
Cutdownpintwo = 0
END SUB
 
SUB Radiocomms()
 IF Statuscode = 0 THEN
  S = "UKHAS>"
 ELSE
  S = "UKHAS<"
 END IF
 S = S + Contents(3)
 S = S + Contents(4)
 S = S + Contents(5)
 S = S + Contents(6)
 S = S + Contents(10)                                       'nmea data
 Printstring = Fusing(gpsheading , "#.#")
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Fusing(target , "#.#")
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Str(rate)
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Str(temperature)
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Str(ERROR)
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Fusing(heading , "#.#")
 Printstring = "," + Printstring
 S = S + Printstring
 Printstring = Fusing(filteredrate , "#.#")
 Printstring = "," + Printstring
 S = S + Printstring
 Gpbyteone = Checksum(s)
 S = S + "*"
 Printstring = Hex(gpbyteone)
 S = S + Printstring
 PRINT S
 PRINT #4 , S
END SUB
projects/ukhas_glider_project/master.txt ยท Last modified: 2008/07/19 23:33 (external edit)