Camera Path Robot
φ Final Report φ
![]()
AdamKim
AndrewMcAllister
ECE246
ADSLSpring 2003
Overview of Design and Functionality:
The Camera Path Robot was createdwith the filmmaker in mind.Κ Based on astandard piece of movie-making equipment, the jib arm (the mechanicalparallelogram geometry), this robot replaces the work of physically moving thecamera with gearing and stepping motors to move a camera in the same path anynumber of times.Κ By moving in the samepath repeatedly, visual effects can be achieved in editing that could not bedone moving the camera by hand.
The robot is designed to move infour degrees of motion: jib up/down, jib rotate, pan, and tilt.Κ The director, instead of instructing a cameraoperator, would programs a laptop running windows software to move the motorsover a specified degree of arc over a specified period of time.Κ
Design Details:
There were four major modules tothis project.Κ Each of the projectmodules were created and then connected to the other modules to produce thefinal product.Κ These modules wereconnected according to the following blockdiagram:
a. LaptopSoftware φ Directorβs Interface
The software was developed inVisual Basic to display a directorβs control panel.Κ Here is a screenshot of the controls:
![]()
Notice that the director can bothoperate one motor at a time easily, or, in the CPR Code Window, send commandsto multiple motors for more complex movements.Κ
Files for this program are includedon the CD-Rom and are printed and attached in the attachments section of thisdocument.Κ This program is extremelysimple as most of the processing is done on the basic stamp.Κ The code only presents a user interface andgenerates, based on these fields, a command string sent as a packet to thebasic stamp over RS-232.Κ Sending at19200 bps was the best for my application.Κ
The packet encoding is as follows:
| g | <motor> | , | <direction> | , | <arc> | , | <duration> | # |
| Start Byte (ascii) | A number for the motor: 1 = jib rotate, 2 = jib elevate, 3 = pan, 4 = tilt | Comma de-limiter | A number for direction: 1 = CW/Up, 2 = CCW/Down | Comma delimiter | A number for to arc in degrees from one digit to three digits. | Comma de-limiter | A number for the duration of motion in seconds | Ending Byte (ascii) |
This packet is how we γplugged inδthe laptop to the BasicX microcontroller.
b. BasicXBX-24 Microcontroller RS-232 Translator
For this project, we already had aBasicX BX-24 microcontroller, so we decided to implement it on this project dueto our familiarity with it.Κ We acquireda development board to easily communicate and download programs to thecontroller φ by using a dev board we had a γboxδ which contained the chip so aswe built this portion of the project, we did not have to concern ourselves withpower to the chip or if wires were connected solidly.Κ The dev board was crucial to keeping the chipsafe from breaking during prototyping phases.ΚWe also took steps later in the amp to buffer all signals to thecontroller in case a bad connection was made φ the controller is fragile andmust be protected.
We designed the microcontroller todecode the packets as they arrive on the Comm 1 serial port.Κ The code (attached) copies values into anarrays for each variable depending on the motor the director wishes to operate.Κ After the code is successfully decoded, atask is spawned on the microcontroller depending on which motor is to be run,and the variables are copied to that motorβs variable arrays.Κ This way the motor taskβs variables areisolated and semaphores are not necessary.ΚThe code is in the attachments section at the end of this document.
Interesting features of theprogramming include the linear acceleration envelope and how each motor taskcreates the pulse trains.Κ The linearacceleration envelope causes the stepping motors to start and stop smoothly,although a more parabolic acceleration/deceleration envelope would be more desirable.Κ By smoothing out speed transitions, therecorded video looks more professional as it does not γwobbleδ at the end of amovement.Κ This was a crucial designrequirement.
Each task generates the pulsetrains by outputting γPutPin()δ commands, thereby bringing a signal linehigh.Κ Then the task sleeps until itneeds to pull a pin low.Κ This makesmultitasking easy.Κ For more informationon how the pulses must be created, see the chassis section about steppingmotors or references for tutorials on how to use stepping motors provided inthe γreferencesδ section.
c. AmplifyingHardware
A stepping motor requires pulses ofa certain voltage in order to move a preset arc, or step.Κ Being 2-phase, our motors require two pulses,one across each coil of the motor.Κ So weneeded hardware to take the logic level pulses from the BX chip and convertthem to the higher voltage, and more importantly, the higher current necessaryto drive the motors.
To accomplish this, we had manycircuit designs.Κ Motor driver ICs provedto accomplish the task, but they required extra components, and moreimportantly, we didnβt know if they were using the motors optimally.Κ FETs were a potential solution, but usingthem as switches instead of amps failed to provide enough voltage.Κ Relays were highly effective, but they hadthe problem of potential mechanical failure.ΚFinally, we came across a bipolar transistor amp design that workedwell.Κ This BJT design required only twosignals be generated per motor from the controller and outputted four signalsto each motor by using inverters.ΚConcerns for hardware IC and BJT selection were all based on the currenteach motor would require in operation.
Since the circuitry for just onemotor filled an entire breadboard, which in itself was bulky, we decided tosolder it all to one board.Κ For spaceand time concerns, we custom made several resistor-transistor combinations.Κ With the BX chipβs board mounted above thesolder board, we were able to power the motors, the chip, and the amps all offone power supply using two voltage regulators to provide logic level power.Κ The amp hardware is actually capable of beingseparated from the BX chip and the motors without dismantling it.Κ
Here is a photo of the finalassembly:
![]()
The BX Development Board is on topconnected by DB9 (top center) to the laptop, and the rainbow ribbon cable (topleft) connects the dev board to the amplifying hardware on the bottomlayer.Κ Wires exiting the right of thepicture connect the amp to the motor leads on the robot.
d. MechanicalJib-Arm Chassis with Stepping Motors
The chassis took the most time inthis project and went through many redesigns.ΚUsing AutoCAD, we drafted a prototype chassis to be created out ofaluminum.Κ Having never taken TAM or anymechanical engineering courses, we had to learn a lot as we went about gearratios, pros and cons of certain types of gears, what gearing meant for speedand torque characteristics, and other issues such as frictionβs effect ongearing ratios, etc.Κ We first designed ajib arm with four equal arms, two on each side.ΚThis would have been quite heavy, so Craig Z. from the machine shop inEveritt Lab suggested going with a channel.ΚLooking to industry designs, sure enough, this was a good solution; thechannel is a long box of aluminum roughly 2δ by 1δ by the length of the arm.Κ We were concerned with being able to lift thecamera, and we did not want our structural members to bend under the weight φthis was not a concern, however, compared to the γyard stick wobbleδproblem.Κ By using a channel, we wereable to avoid any lateral wobbling while also decreasing the weight of thechassis and also increasing the camera payload capability.Κ
Stepping motors from OrientalMotors were selected due to their easy availability.Κ We purchased them from Servo Systems, a bulkdistributor.Κ The motors we selectedopearate at +7.5 V and .4 Amps, are 2-phase, and unipolar.Κ Note this camera payload was limited in ourdesign by the small stepping motors selected.ΚStepping motors with torque four times larger would be crucial for amore successful stepping motor design.ΚSee the γlimitationsδ section for other ideas on how to improve thisaspect of the design.
The chassis was designed to bemodular also: the jib arm can detach from the pivot box, and the pivot box canbe attached to any standard tripod.Κ Avery sturdy tripod is required, however, because the weight of the arm with thecamera is around 17 pounds.
The stepping motors are interestingdevices as they give control of all poles on the stator to the operator.Κ A switched signal in a phased pattern overfour lines is required to properly turn the stepping motor.ΚΚ Each stepping motor was connected back tothe amplifying hardware using ribbon cables and long wires (approximately 1.5meters, max) to carry the signal.Κ Thedesign required the amplifying hardware and BasicX microcontroller to be nearthe base of the chassis.Κ By doing this,the pulse signals would not be adversely affected much by noise.Κ
The laptop can be connected at upto 30 feet away using RS-232 standard connections.Κ The chassis is powered by a +7.5 DCV, 5 Amppower supply that would require a standard power extension chord connecting to120V A/C power:
![]()
Design schematics are attached, andalthough these designs were not used, the overall dimensions are still thesame.
How to Make It Work:
1. Connectthe RS-232 cable from the laptop serial port to the corresponding port on theBX chip board.
2. Connectthe BasicX development board power to a 7.5-V power supply.Κ This will power all the motors and logic; thereis no need for another separate power supply.Κ All voltage levels are regulated.
3. Wiremotors to board.Κ Center pins are power,surrounding pins are pulses, paired by inverted phases.Κ Note, if motors vibrate and do not rotate,these wires are likely connected incorrectly.
4. StartCamera Path Robot program.
5. Turnon power supply.Κ Window should say, γCPRis ready.δ
6. Tocontrol a simple movement, input arc length and time for completion, then clickmovement type (rotate, elevate, pan, tilt).
7. Formultiple simultaneous movements, click the copy to window checkbox, then inputas per simple movements.Κ Click Run onceall commands are input.
8. Ifnecessary, click emergency stop.Κ Robotwill halt with a brief slowdown period.
9. Iferror occurs, click reset button on BX board.ΚRepeat until window shows γCPR is ready.δ
10. Repeatsteps 5-9 as necessary.
11. Whenfinished, shut down the power supply and close the program.
Helpful Notes:
α Helpful Things:
The robotβs weight was a majorfactor in this project that we did not understand enough at the beginning toconsider.Κ By going through many designiterations on the chassis early in the semester, we were able to get the weightdown a bit, however not enough.Κ The 2pound camera had a very small range of motion the robot was capable ofarticulating it in even with the counterweight.ΚConsider lightening the main aluminum channel on the jib arm withweight-reduction holes φ doing so will not limit the camera payload and willnot increase any γwobbleδ (like a yardstick does).
α Limitations and Solutions to Limitations forNext Design Iteration:
The robot was very slow.Κ This speed can be improved by implementing afeedback control system with optical encoders and DC motors.Κ This should allow for a larger range ofspeeds attainable by the system.Κ Notethat a camera usually moves very slowly if it is γon the airδ so this is not aterrible limitation.Κ Perhaps consideringa smaller gear ratio on the jib motions along with these motors will alsoincrease speed.
Specifically, motor top speeds dueto stepping motor limitations amplified by high gear ratios cause these roboticspeed limitations:
| Motion | 10 Deg Arc Min Time (sec) | Max Deg/Sec | BX Calculation Constant |
| Rotate | 3-4 | 3.33 | 0.12 |
| Elevate | 5-6 | 1.82 | 0.12 |
| Pan | 3 | 3.33 | 0.19 |
| Tilt | 3 (up) 2(down) | 2.5 (up) 5 (down) | 0.14 |
Another limitation was that the BasicXchip was only able to multitask my code to run two motors simultaneously.Κ Better code may achieve all four motorsmultitasking, however I think a better microcontroller is required to pulse allfour motors at the same time.Κ Theamplifying hardware is a separate module, so plugging a new microcontroller (ajava stamp?) into this hardware would be simple.Κ No modifications would be necessary as allinputs are buffered on the amplifying hardware.
Table of Attachments:
Code:
ΚΚΚΚΚΚΚΚΚΚΚ LaptopCode
ΚΚΚΚΚΚΚΚΚΚΚ BasicXBX-24 Microcontroller Code
Amplifying Hardware Sketch
Chassis Schematics
ΚΚΚΚΚΚΚΚΚΚΚ Tableof Contents
ΚΚΚΚΚΚΚΚΚΚΚ MainSchematic
ΚΚΚΚΚΚΚΚΚΚΚ ArmDetail
ΚΚΚΚΚΚΚΚΚΚΚ JibPivot φ Base
ΚΚΚΚΚΚΚΚΚΚΚ JibPivot Detail φ Fulcrum
ΚΚΚΚΚΚΚΚΚΚΚ PlatformDetail φ Pan/Tilt detail
Datasheets
ΚΚΚΚΚΚΚΚΚΚΚ BasicXSummary
ΚΚΚΚΚΚΚΚΚΚΚ MPS6560(BJT)
ΚΚΚΚΚΚΚΚΚΚΚ SN74F04Hex Inverters
ΚΚΚΚΚΚΚΚΚΚΚ 74HC367Hex Buffer
ΚΚΚΚΚΚΚΚΚΚΚ 7805AVoltage Regulator
Various other information
II. References:
http://www.pontech.com/products/vexta/index.htm
http://www.microdolly.com/index3.html
http://www.embedded.com/story/OEG20030410S0057
http://www.cs.uiowa.edu/~jones/step/circuits.html
http://www.solarbotics.net/library/pieces/parts_mech_steppers.html
http://www.ece.uiuc.edu/eshop/parts/
http://www.ti.com
http://www.google.com
http://courses.ece.uiuc.edu/ece345/resources.htm
http://www.basicx.com/
http://www.servosystems.com
http://www.orientalmotors.com
http://fred.unis.no/StampII3Mx/Default.htm
Code for the project:
The Laptop Code (Visual Basic6.0):
Private Function TooFast(MotorAs Integer, _
ΚΚΚΚΚΚΚ Arc As Integer, Duration As Integer, _
ΚΚΚΚΚΚΚ Direction As Integer) As Boolean
ΚΚΚ TooFast = False
ΚΚΚ Select Case Motor
ΚΚΚΚΚΚΚ Case 1
ΚΚΚΚΚΚΚΚΚΚΚ If (CSng((Arc / Duration)) >3.33) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ TooFast = True
ΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Case 2
ΚΚΚΚΚΚΚΚΚΚΚ If (CSng((Arc / Duration)) >1.82) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ TooFast = True
ΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Case 3
ΚΚΚ ΚΚΚΚΚΚΚΚIf (CSng((Arc / Duration)) > 3.33)Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ TooFast = True
ΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Case 4
ΚΚΚΚΚΚΚΚΚΚΚ If ((CSng((Arc / Duration)) >2.5) And _
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ (Direction = 1)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ TooFast = True ' cw/UP CASE
ΚΚΚ ΚΚΚΚΚΚΚΚEnd If
ΚΚΚΚΚΚΚΚΚΚΚ If ((CSng((Arc / Duration)) > 5)And _
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ (Direction = 2)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ TooFast = True ' ccw/DOWN CASE
ΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚ End Select
End Function
Private Sub Clear_Click()
ΚΚΚ CodeWindow.Text = ""
End Sub
Private Sub Command1_Click()
ΚΚΚ If SingleFrame.Enabled = True Then
ΚΚΚΚΚΚΚ EnableButton (False)
ΚΚΚ Else
ΚΚΚΚΚΚΚ EnableButton (True)
ΚΚΚ End If
End Sub
Private Sub Command2_Click()
ΚΚΚ Text3.Text = MSComm1.Input
ΚΚΚ MSComm1.InBufferCount = 0
End Sub
Private Sub Bad_Click()
ΚΚΚ EnableButton (False)
ΚΚΚ MSComm1.Output = "t1,1"
End Sub
Private Sub Command3_Click()
ΚΚΚ MSComm1.Output = "s"
End Sub
Private Sub ElevateJib_Click()
ΚΚΚ If (CopyMode.value = False) Then
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(2, 1)
ΚΚΚ Else
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(2, 2)
ΚΚΚ End If
End Sub
Private Sub CopytoWindow(MotorAs Integer)
End Sub
Private Sub RotateJib_Click()
ΚΚΚ If (CopyMode.value = False) Then
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(1, 1)
ΚΚΚ Else
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(1, 2)
ΚΚΚ End If
End Sub
Private Sub Pan_Click()
ΚΚΚ If (CopyMode.value = False) Then
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(3, 1)
ΚΚΚ Else
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(3, 2)
ΚΚΚ End If
End Sub
Private Sub RunCPRCode_Click()
ΚΚΚ EnableButton (False)
ΚΚΚ MSComm1.Output = CodeWindow.Text
End Sub
Private Sub Tilt_Click()
ΚΚΚ If (CopyMode.value = False) Then
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(4, 1)
ΚΚΚ Else
ΚΚΚΚΚΚΚ Call TransmitSingle_Click(4, 2)
ΚΚΚ End If
End Sub
Private Sub Good_Click()
ΚΚ ΚDimExampleGood As String
ΚΚΚ ExampleGood ="g1,1,13,122#g2,1,45,234" & "#"
ΚΚΚ EnableButton (False)
ΚΚΚ CPRCodeWindow.Text = ExampleGood
ΚΚΚ MSComm1.Output = ExampleGood
End Sub
Private SubTransmitSingle_Click(Motor As Integer, _
ΚΚΚΚΚΚΚ Mode As Integer)
ΚΚΚ Dim RotDirection As String
ΚΚΚ Dim NeedCRLF As String, FastMsg As String,_
ΚΚΚΚΚΚΚ FastTitle As String, junk As Variant
ΚΚΚ FastMsg = "Try a longer duration orless arc, because the speed you selected is too fast."
ΚΚΚ FastTitle = "Woah there, Commander!"
ΚΚΚ NeedCRLF = ""
ΚΚΚ If (Dir(0).value = True) Then
ΚΚΚΚΚΚΚ RotDirection = 1 ' CW
ΚΚΚ Else
ΚΚΚΚΚΚΚ RotDirection = 2 ' CCW
ΚΚΚ End If
ΚΚΚ If (TooFast(Motor, Text2.Text, _
ΚΚΚΚΚΚΚΚΚΚΚ Text4.Text, CInt(RotDirection)))Then
ΚΚΚΚΚΚΚ junk = MsgBox(FastMsg, vbOKOnly,FastTitle)
ΚΚΚΚΚΚΚ GoTo SkipMotorMove
ΚΚΚ End If
ΚΚΚ If (Mode = 1) Then
ΚΚΚΚΚΚΚ MSComm1.Output = "g" &Motor & "," & _
ΚΚΚΚΚΚΚΚΚΚΚ RotDirection & ","& Text2.Text & "," & _
ΚΚΚΚΚΚΚΚΚΚΚ Text4.Text & "#"
ΚΚΚΚΚΚΚ EnableButton (False)
ΚΚΚ Else
ΚΚΚ ΚΚΚΚIf (CodeWindow.Text <> "")Then
ΚΚΚΚΚΚΚΚΚΚΚ NeedCRLF = vbCrLf
ΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ CodeWindow.Text = CodeWindow.Text &NeedCRLF _
ΚΚΚΚΚΚΚΚΚΚΚ & "g" & Motor& "," & _
ΚΚΚΚΚΚΚΚΚΚΚ RotDirection & ","& Text2.Text & "," & _
ΚΚΚΚΚΚΚΚΚΚΚ Text4.Text & "#"
ΚΚΚ EndIf
SkipMotorMove:
ΚΚΚΚΚΚΚ ' Motor: 1 = JR, 2 = JE, 3 = Pan, 4 =Tilt
ΚΚΚΚΚΚΚ ' Rot. Dir: 1 = CW, 2 = CCW
'------------------------------------------------------
'|"g"|motor(1)|,|rotDir(1)|,|Arc(2)|,|Duration(2)|#(1)|
'------------------------------------------------------
End Sub
Private Sub Form_Load()
ΚΚΚ Call EnableButton(False)
ΚΚΚ ' Open the serial port
ΚΚΚ MSComm1.CommPort = 1
ΚΚΚ MSComm1.Settings = "19200,N,8,1"
ΚΚΚ MSComm1.RThreshold = 1
ΚΚΚ MSComm1.InBufferCount = 0Κ ' clear inBuffer
ΚΚΚ If MSComm1.PortOpen = False ThenMSComm1.PortOpen = True
ΚΚΚ Text3.Text = "Laptop is Ready"
ΚΚΚ
End Sub
Private Sub FormClose()
ΚΚΚ MSComm1.PortOpen = False
End Sub
Public Sub MSComm1_OnComm()
ΚΚΚ 'when the com port hears a character,decode it
ΚΚΚ If MSComm1.CommEvent > 0 Then
ΚΚΚΚΚΚΚ DecodeInput (MSComm1.Input)
ΚΚΚ End If
End Sub
Public SubDecodeInput(decodeThis As String)
ΚΚΚ If (InStr(decodeThis, "11")) Then
ΚΚΚΚΚΚΚ Call EnableButton(True)
ΚΚΚΚΚΚΚ Text3.Text = "CPR is Ready"
ΚΚΚ End If
ΚΚΚ If (InStr(decodeThis, "15")) Then
ΚΚΚΚΚΚΚ Call EnableButton(True)
ΚΚΚΚΚΚΚ Text3.Text = "CommandErrored"
ΚΚΚ End If
ΚΚΚ If (InStr(decodeThis, "20")) Then
ΚΚΚΚΚΚΚ Call EnableButton(True)
ΚΚΚΚΚΚΚ Text3.Text = "StopSuccessful"
ΚΚΚ End If
ΚΚΚ 'CodeWindow.Text = decodeThis
End Sub
Public Sub EnableButton(valueAs Boolean)
ΚΚΚ If (value) Then
ΚΚΚΚΚΚΚ SingleFrame.Enabled = True
ΚΚΚ Else
ΚΚΚΚΚΚΚ Text3.Text = "Executing..."
ΚΚΚΚΚΚΚ SingleFrame.Enabled = False
ΚΚΚ End If
ΚΚΚ
End Sub
The BasicX BX-24 MicrocontrollerCode:
CPRController.bas Module:
'-------------------------------------------------------------------------------
Option Explicit
ΚΚΚΚΚΚΚ Const SlowStartQP As Single = 0.2
ΚΚΚΚΚΚΚ Const StartScalar As Single = 1.3
ΚΚΚΚΚΚΚ Const GreenLED As Byte = 26
ΚΚΚΚΚΚΚ Const RedLED As Byte = 25
ΚΚΚΚΚΚΚ Const LEDon As Byte = 0
ΚΚΚΚΚΚΚ Const LEDoff As Byte = 1
ΚΚΚΚΚΚΚ Const Pound As Integer = 35
ΚΚΚΚΚΚΚ Const Comma As Integer = 44
ΚΚΚΚΚΚΚ Const OKCode As Integer = 11
ΚΚΚΚΚΚΚ Const ErrorCode As Integer = 15
ΚΚΚΚΚΚΚ Const EStopCode As Integer = 20
ΚΚΚΚΚΚΚ Const DegPerStepJib As Single = 0.12
ΚΚΚΚΚΚΚ Const DegPerStepPan As Single = 0.19
ΚΚΚΚΚΚΚ Const DegPerStepTilt As Single = 0.14
ΚΚΚΚΚΚΚ Private M1ControlStack(1 To 40) As Byte
ΚΚΚΚΚΚΚ Private M2ControlStack(1 To 40) As Byte
ΚΚΚΚ ΚΚΚPrivate M3ControlStack(1 To 40) As Byte
ΚΚΚΚΚΚΚ Private M4ControlStack(1 To 40) As Byte
ΚΚΚΚΚΚΚ Private LEDStack(1 To 20) As Byte
ΚΚΚΚΚΚΚ Dim EStop As Boolean
ΚΚΚΚΚΚΚ Dim Motor(1 To 5) As Integer
ΚΚΚΚΚΚΚ Dim Direction(1 To 5) As Integer
ΚΚΚΚΚΚΚ Dim Arc(1 To 5) As Integer
ΚΚΚΚΚΚΚ Dim Duration(1 To 5) As Integer
ΚΚΚΚΚΚΚ ' line declarations for motor signals
ΚΚΚΚΚΚΚ Const JRA As Byte = 13ΚΚΚΚΚΚΚΚΚ ' jib rotate
ΚΚΚΚΚΚΚ Const JRB As Byte = 14
ΚΚΚΚΚΚΚ Const JEA As Byte = 16ΚΚΚΚΚΚΚΚΚ ' jib elevate
ΚΚΚΚΚΚΚ Const JEB As Byte = 15
ΚΚΚΚΚΚΚ Const PanA As Byte = 17 ' pan
ΚΚΚΚΚΚΚ Const PanB As Byte = 18
ΚΚΚΚΚΚΚ Const TiltA As Byte = 20ΚΚΚΚΚΚΚ ' tilt
ΚΚΚΚΚΚΚ Const TiltB As Byte = 19
ΚΚΚΚΚΚΚ Const DelayLine As Byte = 12ΚΚΚ 'dummy delay line (unused I/O)
'-------------------------------------------------------------------------------
Public Sub Main()
ΚΚΚΚΚΚΚ Call OpenSerialPort
ΚΚΚΚΚΚΚ Call PutStr(CStr(OKCode))
ΚΚΚΚΚΚΚ Call PutPin(GreenLED, LEDon)
ΚΚΚΚΚΚΚ EStop = False
ΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚ Do
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call GetPkt
Κ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚSleep (0)
ΚΚΚΚΚΚΚ Loop
End Sub
'-------------------------------------------------------------------------------
Public Sub PulseEncodeTask1()
ΚΚΚΚΚΚΚ Dim Steps As Integer, Freq As Single,atStep As Integer, QuarterPeriod As Single
ΚΚΚΚΚΚΚ Dim LineA As Byte, LineB As Byte,GoalQP As Single
ΚΚΚΚΚΚΚ If (Direction(1) = 1) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = JRA
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = JRB
ΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = JRB
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = JRA
ΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Steps = FixI(CSng(Arc(1)) /DegPerStepJib)
ΚΚΚΚΚΚΚ Freq = CSng(Steps) / CSng(Duration(1) -1)
ΚΚΚΚΚΚΚ GoalQP = DelayCalc(Freq)
ΚΚΚΚΚΚΚ QuarterPeriod = SlowStartQP
ΚΚΚΚΚΚΚ For atStep = 1 To Steps Step 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚIf (QuarterPeriod > GoalQP) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod =QuarterPeriod / StartScalar
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = GoalQP
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (EStop = True) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoTo Emerg1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Sleep (0)
ΚΚΚΚΚΚΚ Next
Emerg1:
ΚΚΚΚΚΚΚ 'Calltask "RedNote",LEDStack
ΚΚΚΚΚΚΚ Call PutStr(CStr(OKCode)) ' CPR is OK-> Laptop
End Sub
'-------------------------------------------------------------------------------
Public Sub PulseEncodeTask2()
ΚΚΚΚΚΚΚ Dim Steps As Integer, Freq As Single,atStep As Integer, QuarterPeriod As Single
ΚΚΚΚΚΚΚ Dim LineA As Byte, LineB As Byte,GoalQP As Single
ΚΚΚΚΚΚΚ If (Direction(2) = 1) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = JEA
ΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚLineB = JEB
ΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = JEB
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = JEA
ΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Steps = FixI(CSng(Arc(2)) /DegPerStepJib)
ΚΚΚΚΚΚΚ Freq = CSng(Steps) / CSng(Duration(2) -1)
ΚΚΚΚΚΚΚ GoalQP = DelayCalc(Freq)
ΚΚΚΚΚΚΚ QuarterPeriod = SlowStartQP
ΚΚΚΚΚΚΚ For atStep = 1 To Steps Step 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (QuarterPeriod > GoalQP)Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod =QuarterPeriod / StartScalar
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = GoalQP
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (EStop = True) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoTo Emerg2
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Sleep (0)
ΚΚΚΚΚΚΚ Next
ΚΚΚΚΚΚΚ Do Until (QuarterPeriod > SlowStartQP)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚCall PutPin(LineB, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = QuarterPeriod *StartScalar
ΚΚΚΚΚΚΚ Loop
Emerg2:
ΚΚΚΚΚΚΚ 'Calltask "RedNote",LEDStack
ΚΚΚΚΚΚΚ Call PutStr(CStr(OKCode)) ' CPR is OK-> Laptop
End Sub
'-------------------------------------------------------------------------------
Public Sub PulseEncodeTask3()
ΚΚΚΚΚΚΚ Dim Steps As Integer, Freq As Single,atStep As Integer, QuarterPeriod As Single
ΚΚΚΚΚΚΚ Dim LineA As Byte, LineB As Byte,GoalQP As Single
ΚΚΚ ΚΚΚΚIf (Direction(3) = 1) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = PanA
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = PanB
ΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = PanB
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = PanA
ΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Steps = FixI(CSng(Arc(3)) /DegPerStepPan)
ΚΚΚΚΚΚΚ Freq = CSng(Steps) / CSng(Duration(3) -1)
ΚΚΚΚΚΚΚ GoalQP = DelayCalc(Freq)
ΚΚΚΚΚΚΚ QuarterPeriod = SlowStartQP
ΚΚΚΚΚΚΚ For atStep = 1 To Steps Step 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚCall PutPin(LineB, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (QuarterPeriod > GoalQP)Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod =QuarterPeriod / StartScalar
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = GoalQP
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (EStop = True) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoTo Emerg3
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Sleep (0)
ΚΚΚΚΚΚΚ Next
Emerg3:
ΚΚΚΚΚΚΚ 'Calltask "RedNote",LEDStack
ΚΚΚΚΚΚΚ Call PutStr(CStr(OKCode)) ' CPR is OK-> Laptop
End Sub
'-------------------------------------------------------------------------------
Public Sub PulseEncodeTask4()
ΚΚΚΚΚΚΚ Dim Steps As Integer, Freq As Single,atStep As Integer, QuarterPeriod As Single
ΚΚΚΚΚΚΚ Dim LineA As Byte, LineB As Byte,GoalQP As Single
ΚΚΚΚΚΚΚ If (Direction(4) = 1) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = TiltA
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚLineB = TiltB
ΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineA = TiltB
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ LineB = TiltA
ΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Steps = FixI(CSng(Arc(4)) /DegPerStepTilt)
ΚΚΚΚΚΚΚ Freq = CSng(Steps) / CSng(Duration(4) -1)
ΚΚΚΚΚΚΚ GoalQP = DelayCalc(Freq)
ΚΚΚΚΚΚΚ QuarterPeriod = SlowStartQP
ΚΚΚΚΚΚΚ For atStep = 1 To Steps Step 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 1)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(QuarterPeriod)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (QuarterPeriod > GoalQP)Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod =QuarterPeriod / StartScalar
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = GoalQP
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (EStop = True) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoTo Emerg4
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Sleep (0!)
ΚΚΚΚΚΚΚ Next
Emerg4:
ΚΚΚΚΚΚΚ 'Calltask "RedNote",LEDStack
ΚΚΚΚΚΚΚ Call PutStr(CStr(OKCode)) ' CPR is OK-> Laptop
End Sub
'-------------------------------------------------------------------------------
Public Sub GetPkt()
ΚΚΚΚΚΚΚ 'get 6 bytes from buffer with"g" as start char
ΚΚΚΚΚΚΚ Dim bCh As Byte
ΚΚΚΚΚΚΚ Dim byteOK As Boolean
ΚΚΚΚΚΚΚ Dim i As Integer
ΚΚΚΚΚΚΚ For i = 1 To 4 Step 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call TaskVarZero(i)
ΚΚΚΚΚΚΚ Next
ΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚ Do
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ EStop = FalseΚ ' reset emerg stop if necessary
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Arc(5) = 0
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Direction(5) = 0
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Motor(5) = 0
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Duration(5) = 0
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ bCh = 32
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'Do Until (Semaphore(Gate))
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'ΚΚΚΚΚΚ sleep(0.3)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'Loop
ΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call GetByte(bCh,byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If ((bCh =Asc("g")) And (byteOK = True)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'Motor Number
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If ((CInt(bCh)> 47) And (CInt(bCh) < 58)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚMotor(5) = CInt(bCh - 48) 'convert to integer
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'datais messed up - drop packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚGoTo GarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (CInt(bCh)<> Comma) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ'Success = FalseΚ -- expectedcomma, pkt messed up, discard packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoToGarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'DirectionInput
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚIf ((CInt(bCh) > 47) And(CInt(bCh) < 58)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚDirection(5) = CInt(bCh - 48) 'convert to integer
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'datais messed up - drop packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoToGarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (CInt(bCh)<> Comma) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚGoTo GarbledPkt '-- expected comma, pktmessed up, discard packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'Arc Input
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ bCh = 0
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚDo Until (CInt(bCh) = Comma)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If(((CInt(bCh) > 47) And (CInt(bCh) < 58)) Or (CInt(bCh) = Comma)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚIf ((CInt(bCh) <> Comma)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚArc(5) = Arc(5) * 10 + CInt(bCh - 48)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚEnd If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else'the packet is garbled - discard the packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚGoTo GarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Loop
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ 'Duration Input
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Do
ΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCallGetByte(bCh, byteOK)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If(((CInt(bCh) > 47) And (CInt(bCh) < 58)) Or (CInt(bCh) = Pound)) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚIf ((CInt(bCh) <> Pound)) Then
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚDuration(5)= Duration(5) * 10 + CInt(bCh - 48)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚElse
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ'Success = TrueΚ -- we found theend of packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚGoTo EndSuccess
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚEnd If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else'the packet is garbled - discard the packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚGoTo GarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Loop
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ' These labelsare how this loop can end
GarbledPkt:
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallPutStr(CStr(ErrorCode)) ' this is an error code - garbled packet
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoToEndThis
EStopMsg:
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallPutStr(CStr(EStopCode)) ' on an Estop, this is sent to computer
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚGoTo EndThis
EndSuccess:
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallTaskVarMove(Motor(5))
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ SelectCase Motor(5)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCase 1
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚCallTask"PulseEncodeTask1", M1ControlStack
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCase 2
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCallTask "PulseEncodeTask2", M2ControlStack
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚCase 3
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCallTask "PulseEncodeTask3", M3ControlStack
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCase 4
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚCallTask "PulseEncodeTask4", M4ControlStack
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ EndSelect
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ CallSleep(0.01) 'give the task time to startup
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Else
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ If (bCh =Asc("s")) Then
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ'Emergency Stop
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ EStop =True
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Sleep(0.5)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoToEStopMsg
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ΚΚΚΚΚΚΚΚIf (byteOK = True) Then ' case wherethe pkt began with something other than g
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoToGarbledPkt
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
EndThis:
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call Sleep(0!)'give other tasks a chance to run
'ΚΚΚΚΚΚΚΚΚΚΚΚΚΚ End If
ΚΚΚΚΚΚΚ Loop
End Sub
'---------------------------------------------------------------------------
Private Sub TaskVarMove(ByValInMotor As Integer)
ΚΚΚΚΚΚΚ Motor(InMotor) = Motor(5)
ΚΚΚ ΚΚΚΚDirection(InMotor) = Direction(5)
ΚΚΚΚΚΚΚ Arc(InMotor) = Arc(5)
ΚΚΚΚΚΚΚ Duration(InMotor) = Duration(5)
End Sub
'-----------------------------------------------------------------------------
Private Sub TaskVarZero(ByValInMotor As Integer)
ΚΚΚΚΚΚΚ Motor(InMotor) = 0
ΚΚΚΚΚΚΚ Direction(InMotor) = 0
ΚΚΚΚΚΚΚ Arc(InMotor) = 0
ΚΚΚΚΚΚΚ Duration(InMotor) = 0
End Sub
'-------------------------------------------------------------------------------
Option Explicit
' This module is used totransfer data to and from the serial port.
Private Const BaudRate As Long= 19200
Private Const InputBufferSizeAs Integer = 50ΚΚ ' buffer.
Private Const OutputBufferSizeAs Integer = 20Κ ' buffer.
Private InputBuffer(1 ToInputBufferSize) As Byte
Private OutputBuffer(1 ToOutputBufferSize) As Byte
Private Const ASCII_LFΚΚΚΚ As Byte = 10
Private Const ASCII_CRΚΚΚΚ As Byte = 13
Private Const ASCIIplusΚΚΚ As Byte = 43
Private Const ASCIIminusΚΚ As Byte = 45
Private Const ASCIIdecimal AsByte = 46
Private Const ASCIIzeroΚΚΚ As Byte = 48
'-------------------------------------------------------------------------------
Public Sub OpenSerialPort()
' Opens a serial port at thespecified baud rate.
ΚΚΚ Call OpenQueue(InputBuffer,InputBufferSize)
ΚΚΚ Call OpenQueue(OutputBuffer,OutputBufferSize)
ΚΚΚ Call OpenCom(1, BaudRate, InputBuffer,OutputBuffer)
End Sub
'-------------------------------------------------------------------------------
Public Sub PutByte( _
ΚΚΚ ByVal Value As Byte)
' Sends one byte of binarydata to the serial port. The byte is sent
' directly without translatingit to a string.
ΚΚΚ Call PutQueue(OutputBuffer, Value, 1)
End Sub
'-------------------------------------------------------------------------------
Public Sub GetByte( _
ΚΚΚ ByRef Value As Byte, _
ΚΚΚ ByRef Success As Boolean)
' Inputs a byte from theserial port, if available. Returns regardless.ΚThe
' Success flag is setdepending on whether a byte is available.
'
' The byte is in direct binaryformat -- it is not in string format.
ΚΚΚ ' Find out if anything is in the queue.
ΚΚΚ Success = StatusQueue(InputBuffer)
ΚΚΚ ' If data is in the queue, extract it.
ΚΚΚ If (Success) Then
ΚΚΚΚΚΚΚ Call GetQueue(InputBuffer, Value, 1)
ΚΚΚ Else
ΚΚΚΚΚΚΚ Value = 0
ΚΚΚ End If
End Sub
'-------------------------------------------------------------------------------
Public Sub NewLine()
' Outputs a <CR><LF> to the serial port.
ΚΚΚ Call PutByte(ASCII_CR)
ΚΚΚ Call PutByte(ASCII_LF)
End Sub
'-------------------------------------------------------------------------------
Public Sub PutLine( _
ΚΚΚ ByVal Tx As String)
' Outputs a String type,followed by <CR> <LF>. Output is to the serial
' port.
ΚΚΚ
ΚΚΚ Call PutStr(Tx)
ΚΚΚ
ΚΚΚ Call NewLine
End Sub
'-------------------------------------------------------------------------------
Public Sub PutStr( _
ΚΚΚ ByVal Tx As String)
' Outputs a String type to theserial port.
ΚΚΚ Dim Length As Integer, Ch As String * 1,bCh As Byte
ΚΚΚ Dim I As Integer
ΚΚΚ Length = Len(Tx)
ΚΚΚ For I = 1 To Length
ΚΚΚΚ ΚΚΚCh = Mid(Tx, I, 1)
ΚΚΚΚΚΚΚ bCh = Asc(Ch)
ΚΚΚΚΚΚΚ Call PutByte(bCh)
ΚΚΚ Next
End Sub
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Option Explicit
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚ ConstGreenLED As Byte = 26
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚ ConstRedLED As Byte = 25
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚ ConstLEDon As Byte = 0
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚ ConstLEDoff As Byte = 1
'-------------------------------------------------------------------------------
Public Sub JibRotate(ByValSteps as Integer,ByVal Freq as Single)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Const LineA As Byte = 13
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Const LineB As Byte = 14
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Const DelayLine As Byte = 12
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Dim GoalPeriod As Single
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Dim i As Integer
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Dim QuarterPeriod As Single
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ ' convert freq to goalperiod
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ GoalPeriod = DelayCalc(Freq)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ QuarterPeriod = 0.5
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ For i=0 to Steps
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, bxOutputHigh)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PulseOut (DelayLine,QuarterPeriod, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, bxOutputHigh)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PulseOut (DelayLine,QuarterPeriod, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineA, bxOutputLow)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PulseOut (DelayLine,QuarterPeriod, 0)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(LineB, bxOutputLow)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PulseOut (DelayLine,QuarterPeriod, 0)
ΚΚΚ ΚΚΚΚΚΚΚΚΚΚΚ Next
End Sub
'-------------------------------------------------------------------------------
Function DelayCalc(Freq asSingle) As Single
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ DelayCalc = (1.0 / Freq) / 4.0
End Function
'-------------------------------------------------------------------------------
Public Sub RedNote()
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(RedLED,LEDon)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Delay(0.5)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(RedLED,LEDoff)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Delay(0.5)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(RedLED,LEDon)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Delay(0.5)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Call PutPin(RedLED,LEDoff)
ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚ Delay(0.5)
End Sub