' {$STAMP BS2p}
' {$PBASIC 2.5}
' {$PORT COM1}

#DEFINE DebugMode

' NAME THIS FILE run1.bsp  FIRST LINE MUST BE ~ ' {$STAMP BS2p...

' run0.bsp, run1.bsp, run2.bsp, run3.bsp

' Version 12/09/2010

' If dark and motors off then sleep.
' If stow flags then stow
' If sunny tracking then set cloudy dwell.  A larger dwell number is longer time to dwell before invoking cloudy routines.
' Run 2 is loop

' Park:  safe and orientate are brads (binary radians). Altitude_Memory and Azimuth_Memory become helm commands loaded with sensor type data.

' Memory: Azimuth_Path and Altitude_Path are brads calculated from solar position algorthm.  If past limits then Azimuth_Memory = Azimuth_Sensor
' causes Helm TO command Azimuth motor STOP.  Altitude_Memory = Altitude_Sensor causes Helm TO command Altitude motor STOP.
' Altitude_Memory and Azimuth_Memory are stored sensor type data.
' If no memory then Altitude_Memory and Azimuth_Memory helm commands become Azimuth_Path and Altitude_Path commands (brads coverted to sensor type data).

' Check_Stow: If Dark or Stow then do not dwell.

' Helm: If motor off and within in target gap then motor remains off.
' If motor AND ON target THEN turn motor off.  ELSE set direction AND motor go.  Right is XY clockwise from above.

' Motors:  If both switches then all motors off.
' If one switch THEN dish up, azimuth off
' IF the other switch THEN dish down, azimuth off
' IF neither switch THEN automatic (flipped away from power switch).
'
' E_OK:  If motor turns on then record sensor position for detecting movement,
' and start Motor timer at 1.  IF motor off THEN STOP timer at 0.

' Safety more important than function.

cport           PIN      0        ' I2C - DS1307 clock
cclock          PIN      1        ' I2C
North_eye       PIN      2        ' RC Time
South_eye       PIN      3        ' RC Time
East_eye        PIN      5        ' RC Time
West_eye        PIN      4        ' RC Time
'water_off       PIN      6
tm              PIN      7        ' Motor Mind C serial comm. SERIN
fm              PIN      8        ' Motor Mind C serial comm. SEROUT
Xin             PIN      9        ' Rotate X Accelerometer MEMSIC 2125
Yin             PIN      10       ' Rotate Y Accelerometer MEMSIC 2125
Zin             PIN      11       ' Tilt   Z Accelerometer MEMSIC 2125 Altitude_sensor
'temp_1          PIN      12
'temp_2          PIN      13
SW1             PIN      14       ' Pulled high
SW2             PIN      15       ' Pulled high

speed_azimuth   VAR      Word      'PWM storage register for motor 1
speed_altitude  VAR      Word      'PWM storage register for motor 2
time            VAR      Word

work            VAR      Word
work1           VAR      Word
work2           VAR      Word
work3           VAR      Word
work4           VAR      Word
work5           VAR      Word

Azimuth_sensor  VAR      Byte
Altitude_sensor VAR      Byte

flags           VAR      Byte
flag_north      VAR      flags.BIT0
flag_south      VAR      flags.BIT1
flag_run        VAR      flags.BIT2
flag_stow       VAR      flags.BIT3

d               VAR      Byte    ' Declination

Dwell           VAR      Nib
Azimuth_Motor   VAR      Nib
Altitude_Motor  VAR      Nib
Smooth          VAR      Nib

read_flag       VAR      Bit
write_flag      VAR      Bit
flag            VAR      Bit
dark            VAR      Bit
stow_write      VAR      Bit
solar_noon      VAR      Bit

sign            VAR      Smooth.BIT0
cloudy          VAR      Smooth.BIT1
Focus           VAR      Smooth.BIT2

Azimuth_Stow          VAR      Bit
Altitude_Stow         VAR      Bit

azimuth_command       VAR      Bit
altitude_command      VAR      Bit
azimuth_go            VAR      Bit
altitude_go           VAR      Bit

azimuth_spin          VAR      Bit
altitude_spin         VAR      Bit
azimuth_on            VAR      Bit
altitude_on           VAR      Bit

p2hi            VAR      speed_azimuth.HIGHBYTE
p2lo            VAR      speed_azimuth.LOWBYTE
p1hi            VAR      speed_altitude.HIGHBYTE
p1lo            VAR      speed_altitude.LOWBYTE

CKSUM           VAR      work.LOWBYTE
key             VAR      work.LOWBYTE
'dat2            VAR      work.LOWBYTE

dat1            VAR      work.HIGHBYTE
value           VAR      work.HIGHBYTE
set             VAR      work.HIGHBYTE

Azimuth_Memory  VAR      work5.LOWBYTE
Altitude_Memory VAR      work5.HIGHBYTE

Azimuth_Path    VAR      work1.BYTE0
Altitude_Path   VAR      work1.BYTE1

'lat             CON      34   '47 degrees Tacoma = 34 brads  (binary radians 0-255 in circle)

BAUD            CON      45
rampAz          CON      8
rampAlt         CON      64
startAz         CON      368
startAlt        CON      428
maxAz           CON      832                             'max 1023
maxAlt          CON      1023

Azimuth_Gap     CON      2
Altitude_Gap    CON      4

lowZ            CON      51
highZ           CON      204
lowD            CON      6  'degrees down hard limit
highD           CON      90  'degrees up  hard limit

rangeZ          CON      highZ-lowZ
rangeD          CON      highD-lowD
rateZ           CON      rangeZ*180/rangeD*2 '256/128
INVrateZ        CON      rangeD*128/180*256/rangeZ

sunrise         CON      2               'brads up
sunset          CON      2
safe            CON      20
noon            CON      64

stowZ           CON      highZ-Altitude_Gap
horizonQ        CON      lowD*rangeZ/rangeD
horizonZ        CON      lowZ-horizonQ

lowXY           CON      12                        ' travel limit
highXY          CON      233                       ' travel limit
due_south       CON      128                       ' Polar Star
due_north       CON      12
rangeXY         CON      due_south - due_north * 2 ' range/256 = sensors per brad
INVrateXY       CON      65535/rangeXY             ' 256/range = brads per sensor


orientate       CON      64
stowXY          CON      due_north+Azimuth_Gap

HiPulse         CON      1
LoPulse         CON      0
on_             CON      1
off             CON      0
up              CON      1
down            CON      0
right           CON      1
left            CON      0
true            CON      1
false           CON      0
yes             CON      1
no              CON      0
go              CON      1
stop_           CON      0


STORE 7

Working:


mode:

#IF DebugMode #THEN

  DEBUG CRSRXY,0,18,"Status   ",CLREOL
  IF dark THEN
    DEBUG "Dark"
    GOTO continue
  ENDIF
  IF cloudy THEN
    DEBUG "Cloudy"
    GOTO continue
  ENDIF
  IF focus THEN
    DEBUG "Focus"
    GOTO continue
  ENDIF
 DEBUG "Sunny"
#ENDIF

Continue:

IF azimuth_on = off AND altitude_on = off THEN
IF dark THEN SLEEP 120
IF cloudy THEN SLEEP 10
NAP 7
ENDIF

#IF DebugMode #THEN
 GET 3,  Azimuth_Path
 GET 4, Altitude_Path
 GET 7,  Azimuth_Memory
 GET 8, Altitude_Memory

 DEBUG CRSRXY,10,2,"Azimuth",CRSRX,20,"Altitude",CRSRX,0,"Raw"

 DEBUG CRSRXY, 0,3,"Path",CLREOL,CRSRX,10
 'IF flag_north  AND Azimuth_Path > 128 THEN            ' flag_north if declination > latitude
 'DEBUG SDEC due_north - ((256-Azimuth_Path) */ rangeXY)
 'ELSE                                                  ' sensor travel start SSW W N E S W NNW end
 DEBUG DEC due_north + (Azimuth_Path */ rangeXY)
 'ENDIF
 DEBUG CRSRX, 20,DEC Altitude_Path */ rateZ + horizonZ,    'Converts brads to sensor type data.
 CRSRXY, 0,4,"Memory",CLREOL,CRSRX,10,DEC Azimuth_Memory,CRSRX,20,DEC Altitude_Memory,
 CRSRXY, 0,5,"Sensors",CLREOL,CRSRX,10,DEC Azimuth_Sensor,CRSRX,20,DEC Altitude_Sensor,CR,CR,
 CRSRXY,10,7,"Azimuth",CRSRX,20,"Altitude",CRSRX,0,"Brads"

 DEBUG CRSRXY, 0,8,"Path",CLREOL,CRSRX,10,DEC Azimuth_Path,CRSRX, 20,DEC Altitude_Path,
 CRSRXY, 0,9,"Memory",CLREOL,CRSRX,10
 IF Azimuth_Memory = 0 THEN
 DEBUG "0"
 ELSE
 ' IF Azimuth_Memory<due_north  THEN
 '   DEBUG SDEC -1*((due_north-Azimuth_Memory)*/INVrateXY)+1
 ' ELSE
    DEBUG DEC ((Azimuth_Memory-due_north)*/INVrateXY)+1  'Converts sensor type data to brads
 ' ENDIF
 ENDIF

 DEBUG CRSRX,20
 IF Azimuth_Memory = 0 THEN DEBUG "0" ELSE DEBUG DEC ((Altitude_Memory-horizonZ)*/INVrateZ)+1
 DEBUG CRSRXY, 0,10,"Sensors",CLREOL,CRSRX,10
 ' IF Azimuth_Sensor<due_north  THEN
 '   DEBUG SDEC -1*((due_north-Azimuth_Sensor)*/INVrateXY)+1
 ' ELSE
  DEBUG DEC ((Azimuth_Sensor-due_north)*/INVrateXY)+1,
 ' ENDIF
 CRSRX,20,DEC ((Altitude_Sensor-horizonZ)*/INVrateZ)+1

 DEBUG CRSRXY,0,20,"Command",CLREOL,CRSRX,9
 IF Azimuth_Stow THEN DEBUG "Azimuth_Stow"
 IF Altitude_Stow THEN DEBUG CRSRX,23,"Altitude_Stow"
 IF Altitude_Stow OR Azimuth_Stow THEN done
 IF dark THEN
  DEBUG "Park"
  GOTO done
 ENDIF
 IF cloudy THEN
  IF Azimuth_Memory THEN
    DEBUG "Memory"
    ELSE
    DEBUG "Path"
  ENDIF
  GOTO done
 ENDIF
 DEBUG "Eyes"

Done:
#ENDIF

IF Azimuth_Stow OR Altitude_Stow THEN Check_Stow
IF dark THEN park
IF cloudy THEN memory

Sunny:

IF Focus THEN dwell = 8 ELSE dwell = 4
GOSUB Motors

RUN 2

Park:

Altitude_Memory = safe */ rateZ + horizonZ
 Azimuth_Memory = orientate */ rangeXY + due_north
GOTO Check_Stow

Memory:

GET 3,  Azimuth_Path
GET 4, Altitude_Path

IF Altitude_Path > noon OR (Altitude_Path < sunrise AND time < 720) OR (Altitude_Path < sunset AND time > 720) THEN
  Azimuth_Memory = Azimuth_sensor   ' > noon(64)includes before sunrise Path (255). (0~64) sun travel (horizon~vertical).
  Altitude_Memory = Altitude_sensor ' Memory = Sensor commands Helm to stop.
  GOTO Check_Stow
ENDIF

GET 7,  Azimuth_Memory
GET 8, Altitude_Memory

IF Azimuth_Memory = 0 THEN
  Altitude_Memory = Altitude_Path */ rateZ + horizonZ    'Converts brads to sensor type data
  'IF flag_north  AND Azimuth_Path > 128 THEN            ' flag_north if declination > latitude
 'Azimuth_Memory = due_north - ((256-Azimuth_Path) */ rangeXY)
 'ELSE                                                  ' sensor travel start SSW W N E S W NNW end
   Azimuth_Memory = Azimuth_Path */ rangeXY + due_north
  'endif
ENDIF

IF Altitude_Memory < lowZ THEN Altitude_Memory = lowZ
IF Altitude_Memory > highZ THEN Altitude_Memory = highZ
IF Azimuth_Memory < lowXY THEN Azimuth_Memory = lowXY
IF Azimuth_Memory > highXY THEN Azimuth_Memory = highXY

Check_Stow:

IF Altitude_Stow THEN
  Altitude_Memory = stowZ
  IF Azimuth_Stow = no THEN
    Azimuth_Memory = Azimuth_sensor
  ENDIF
ENDIF

IF Azimuth_Stow THEN
  Azimuth_Memory = stowXY
  IF Altitude_Stow = no THEN
    Altitude_Memory = Altitude_sensor
  ENDIF
ENDIF

IF (Azimuth_Stow OR Altitude_Stow) AND stow_write = 0 THEN
  FOR work2 = 1500 TO 1900 STEP 4
    READ work2, value
    IF value = 0 THEN EXIT
  NEXT
  IF work2 < 1900 THEN
    GET 9, key
    WRITE work2, key, time/10, Azimuth_sensor, Altitude_sensor
    stow_write = 1
    #IF DebugMode #THEN DEBUG 7 #ENDIF
  ENDIF
ENDIF

IF Azimuth_Stow OR Altitude_Stow OR dark THEN Helm

clouds:
IF dwell THEN
  azimuth_go = no
  altitude_go = no
  GOSUB motors
  RUN 2
ENDIF

Helm:

IF ABS(Azimuth_sensor - Azimuth_Memory) < Azimuth_Gap AND azimuth_go = no THEN skipper
IF Azimuth_sensor = Azimuth_Memory THEN
  azimuth_go = no
  GOTO skipper
ENDIF

azimuth_go = yes
IF Azimuth_sensor < Azimuth_Memory THEN azimuth_command = right ELSE azimuth_command = left

skipper:

IF ABS(Altitude_sensor - Altitude_Memory) < Altitude_Gap AND altitude_go = no THEN skippy

IF Altitude_sensor = Altitude_Memory THEN
  altitude_go = no
  GOTO skippy
ENDIF

altitude_go = yes
IF Altitude_sensor < Altitude_Memory THEN altitude_command = up ELSE altitude_command = down

skippy:
GOSUB motors
RUN 2

'*************************************************

Motors:

IF sw1 = 0 AND sw2 = 0 THEN
  azimuth_go = no
  altitude_go = no
ENDIF

IF sw1 = 1 AND sw2 = 0 THEN
  altitude_go = yes
  altitude_command = up
  azimuth_go = no
  ENDIF

IF sw1 = 0 AND sw2 = 1 THEN
  altitude_go = yes
  altitude_command = down
  azimuth_go = no
  ENDIF

Set_motors:

work1 = speed_azimuth
work2 = speed_altitude

IF azimuth_on = yes AND azimuth_command <> azimuth_spin  THEN  azimuth_go = no  ' stop on this cycle before reverse
IF azimuth_command = right THEN work1 = ((speed_azimuth + rampAz) * azimuth_go) ELSE work1 = (speed_azimuth - rampAz) * azimuth_go
IF work1 = 0 OR ABS(work1) >= startAz THEN Azimuth_start_OK

IF work1.BIT15 = 0 THEN work1 = startAz ELSE work1 = -startAz

Azimuth_start_OK:

IF ABS(work1) <= maxAz THEN Azimuth_OK
IF work1.BIT15 = 0 THEN work1 = maxAz ELSE work1 = -maxAz  'IF work1 < -maxAz THEN work1 = -maxAz

Azimuth_OK:

IF altitude_on = yes AND altitude_command <> altitude_spin  THEN  altitude_go = no  ' stop on this cycle before reverse
IF altitude_command = up THEN work2 = (speed_altitude + rampAlt) * altitude_go ELSE work2 = (speed_altitude - rampAlt) * altitude_go
IF work2 = 0 OR ABS(work2) >= startAlt THEN Altitude_start_OK

IF work2.BIT15 = 0 THEN work2 = startAlt ELSE work2 = -startAlt

Altitude_start_OK:

IF ABS(work2) <= maxAlt THEN Altitude_OK
IF work2.BIT15 = 0 THEN work2 = maxAlt ELSE work2 = -maxAlt  'IF work2 < -maxAlt THEN work2 = -maxAlt

Altitude_OK:

speed_azimuth = work1
speed_altitude = work2

#IF DebugMode #THEN DEBUG CRSRXY,0,16,"Speed",CLREOL,CRSRX,10,SDEC speed_azimuth,CRSRX,20,SDEC speed_altitude #ENDIF

CKSUM = $D0+$01+$04+p1hi+p1lo+p2hi+p2lo
  SEROUT  FM,BAUD,[$D0,$01,$04,P1HI,P1LO,P2HI,P2LO,CKSUM]
  SERIN   TM,BAUD,150,motor_error,[DAT1]
  IF    DAT1 <> $6 THEN GOTO motor_error ELSE GOTO E_OK

motor_error:
#IF DebugMode #THEN DEBUG CRSRXY,2,22," MOTOR ERROR",CR,HEX dat1," ",HEX cksum,7,CR
  PAUSE 5000
#ENDIF

E_OK:
IF azimuth_go AND azimuth_on = off THEN
  Azimuth_Motor = 1
  PUT 1, Azimuth_sensor
ENDIF

IF azimuth_go = off THEN Azimuth_Motor = 0

IF altitude_go AND altitude_on = off THEN
  Altitude_Motor = 1
  PUT 2,  Altitude_sensor
ENDIF

IF altitude_go = off THEN Altitude_Motor = 0

azimuth_on = azimuth_go
azimuth_spin = azimuth_command
altitude_on  = altitude_go
altitude_spin = altitude_command
RETURN