Advertisement
Guest User

Untitled

a guest
Mar 27th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.82 KB | None | 0 0
  1.  
  2. '-----[ Title ]---------------------------------------------------------------
  3. ' Robotics with the Boe-Bot - EscapingLight.bs2
  4.  
  5. ' {$STAMP BS2} ' Stamp directive.
  6. ' {$PBASIC 2.5} ' PBASIC directive.
  7. '-----[ Constants/Variables ]-------------------------------------------------
  8. Negative CON 1 ' For negative numbers
  9. ' Application Variables
  10. light VAR Word ' Brightness/darkness indicator
  11. ndShade VAR Word ' Normalized differential shade
  12. ' Subroutine Variables
  13. tLeft VAR Word ' Stores left RCTIME measurement
  14. tRight VAR Word ' Stores right RCTIME measurement
  15. n VAR Word ' Numerator
  16. d VAR Word ' Denominator
  17. q VAR Word ' Quotient
  18. sumDiff VAR Word ' For sum and difference calcs
  19. duty VAR Byte ' PWM duty argument variable
  20. i VAR Nib ' Index counting variable
  21. temp VAR Nib ' Temp storage for calcs
  22. sign VAR Bit ' Var.BIT15 = 1 if neg, 0 if pos
  23. counter VAR Word
  24. ' Application Variables
  25. pulseLeft VAR Word
  26. pulseRight VAR Word
  27.  
  28. '-----[ Initialization ]------------------------------------------------------
  29. PAUSE 5000
  30.  
  31. DEBUG "Program running..." ' Display program running message
  32. '-----[ Main Routine ]--------------------------------------------------------
  33. DO ' Main Loop.
  34. GOSUB Light_Shade_Info ' Get light & ndShade
  35. ndShade = -ndShade
  36.  
  37. ' Navigation Routine
  38. IF (ndShade + 500) > 500 THEN ' If more shade on left...
  39. pulseLeft = 750
  40. pulseRight = 650
  41. ELSE ' If more shade on right...
  42. pulseLeft = 850 ' Left wheel full speed forward
  43. pulseRight= 750
  44. ENDIF
  45. PULSOUT 13, pulseLeft ' Left servo control pulse
  46. PULSOUT 12, pulseRight ' Right servo control pulse
  47. LOOP ' Repeat main loop
  48. '-----[ Subroutine - Light_Shade_Info ]---------------------------------------
  49. ' Uses tLeft and tRight (RCTIME measurements) and pwm var to calculate:
  50. ' o light - Ambient light level on a scale of 0 to 324
  51. ' o ndShade - Normalized differential shade on a scale of -500 to + 500
  52.  
  53. ' (-500 -> dark shade over left, 0 -> equal shade,
  54. ' +500 -> dark shade over right)
  55.  
  56.  
  57.  
  58.  
  59.  
  60. Pan_Left:
  61. PULSOUT 13, 750 ' Pulse servos in circular path
  62. PULSOUT 12, 650
  63.  
  64.  
  65.  
  66. Light_Shade_Info: ' Subroutine label
  67. GOSUB Light_Sensors ' Get raw RC light measurements
  68. sumdiff = (tLeft + tRight) MAX 65535 ' Start light level with sum
  69. IF duty <= 70 THEN ' If duty at min
  70. light=duty-(sumdiff/905) MIN 1 ' Find how much darker
  71. IF sumdiff = 0 THEN light = 0 ' If timeout, max darkness
  72. ELSEIF duty = 255 THEN ' If duty at max
  73. light=duty+((1800-(sumdiff))/26) ' Find how much brighter
  74. ELSE ' If duty in range
  75. light = duty ' light = duty
  76. ENDIF ' Done with light level
  77. GOSUB Duty_Auto_Adjust ' Adjust PWM duty for next loop
  78. n = tLeft ' Set up tLeft/(tLeft+tRight)
  79. d = tLeft + tRight
  80. GOSUB Fraction_Thousandths ' Divide (returns thousandths)
  81. ndShade = 500-q ' Normalized differential shade
  82. RETURN ' Return from subroutine
  83.  
  84. '-----[ Subroutine - Light_Sensors ]------------------------------------------
  85. ' Measure P6 and P3 light sensor circuits. Duty variable must be in 70...255.
  86. ' Stores results in tLeft and tRight.
  87. Light_Sensors: ' Subroutine label
  88. PWM 6, duty, 1 ' Charge cap in P6 circuit
  89. RCTIME 6, 1, tLeft ' Measure P6 decay
  90. PWM 3, duty, 1 ' Charge cap in P3 circuit
  91. RCTIME 3, 1, tRight ' Measure decay
  92. RETURN ' Return from subroutine
  93.  
  94. '-----[ Subroutine - Duty_Auto_Adjust ]---------------------------------------
  95. ' Adjust duty variable to keep tLeft + tRight in the 1800 to 2200 range.
  96. ' Requires sumdiff word variable for calculations.
  97. Duty_Auto_Adjust: ' Subroutine label
  98. sumDiff = (tLeft + tRight) MAX 4000 ' Limit max ambient value
  99. IF sumDiff = 0 THEN sumDiff = 4000 ' If 0 (timeout) then 4000
  100. IF (sumDiff<=1800) OR (sumDiff>=2200) THEN ' If outside 1800 to 2200
  101. sumDiff = 2000 - sumDiff ' Find excursion from target val
  102. sign = sumDiff.BIT15 ' Pos/neg if .BIT15 = 0/1
  103. sumDiff = ABS(sumDiff) / 10 ' Max sumDiff will be +/- 10
  104. sumDiff = sumDiff MAX ((duty-68)/2) ' Reduce adjustment increments
  105. sumDiff = sumDiff MAX ((257-duty)/2) ' near ends of the range
  106. IF sign=NEGATIVE THEN sumDiff=-sumDiff ' Restore sign
  107. duty = duty + sumDiff MIN 70 MAX 255 ' Limit duty to 70 to 255
  108. ENDIF ' End of if outside 1800 to 2200
  109. RETURN ' Return from subroutine
  110.  
  111. '-----[ Subroutine - Fraction_Thousandths ]-----------------------------------
  112. ' Calculate q = n/d as a number of thousandths.
  113. ' n and d should be unsigned and n < d. Requires Nib size temp & i variables.
  114. Fraction_Thousandths: ' Subroutine label
  115. q = 0 ' Clear quotient
  116. IF n > 6500 THEN ' If n > 6500
  117. temp = n / 6500 ' scale n into 0..6500
  118. n = n / temp
  119. d = d / temp ' scale d with n
  120. ENDIF
  121. FOR i = 0 TO 3 ' Long division ten thousandths
  122. n = n // d * 10 ' Multiply remainder by 10
  123. q = q * 10 + (n/d) ' Add next digit to quotient
  124. NEXT
  125. IF q//10>=5 THEN q=q/10+1 ELSE q=q/10 ' Round q to nearest thousandth
  126. RETURN ' Return from subroutine
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement