66
Team JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook

Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

Team JMR Ballistic Ball Biathlon: Final Report

June Park Minhwan Lee Ross Venook

Page 2: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

2

TABLE OF CONTENTS Table of Contents 2 Project Overview 3 Mechanical Design Turret 5 Drive 7 Load and Shoot 9 Electrical Design Sensors EMF Sensor 10 IR Beacon Sensor 12 Strobe Sensor 12 Tape Sensors 13

Navigation/Tracking Control 13 Power 16

Software Design State Machine 17 Modular Description 17 Pseudo-code 19 Conclusions What Went Wrong 23 How We Could Have Avoided This 23 Appendix A Source Code Index 24 Source Code 25 Appendix B Pin Assignments 66

Page 3: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

3

Project Overview Design Goals The Balli stic Ball Biathlon specifications, as initially published, guided our group to several design goal conclusions. It was clear to us, after a few simple calculations, that the size of the goals would make aiming and shooting by far the most diff icult aspect of this project. We initially identified three design goals as mission-critical:

1. Follow the track smoothly and quickly: Without this abilit y, our droid would be incapable of accomplishing the rest of its tasks.

2. Aim with better than 1 degree accuracy: With a target 4 inches wide, and a ball 1.75 inches wide, the effective target width is 2.25 inches. From 7 feet away, this gives a total viable angle of 1.52 degrees, requiring .7 degrees of aiming accuracy.

3. Shoot, with great precision, at targets on either side of the current track: Precision is most important here because of the opportunity to “ train” the droid and overcome accuracy issues via aiming accommodations.

We also identified several secondary design goals to be met insofar as they did not conflict with the first three:

1. Maximize the effective target area by shooting balls such that their arrival angle is nearly normal to the plane of the hole.

2. Avoid other droid blocking schemes by lofting the ball over the standard height of a droid on the neighboring track.

3. Carry as many balls as possible, with a minimum of ten, to prevent the need to reload during competition.

Basic Design Key features:

1. Shooting mechanism mounted on a turret with > 200 degrees of turning capabilit y

2. Lofting ball l auncher for high-trajectory shots (adjustable speed, not trajectory)

3. Spiral ball l oader to accommodate launch out the top of our droid.

Implementation The final droid bears a significant resemblance to the initial design, and is a testament to our commitment to follow our well -thought-out plan from beginning to end. Indeed, this commitment turned out to be our undoing as we continued to pursue our ambitious design despite a considerable specification simpli fication that required shooting in only one direction from each track.

Figure 1.1. Finished droid on the track.

Page 4: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

4

In the end we were unable to integrate the functional subsystems of our droid into a completely successful device. We attribute this failure to the familiar pair of over-design and insufficient time-resource allocation. Additionally, by dividing the tasks among team members based upon how much we could each learn from the project, we managed to decrease the time-feasibility of our effort. However, we maintain that our design was solid, and attainable given better planning, and were glad to see each subsystem working successfully before our integration debacle.

Page 5: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

5

Mechanical Design Turret

Design Goals: 1. Facilit ate aiming and shooting over a range of 200°. 2. Maintain < 1° resolution on rotation. 3. Enable suff icient central passage area for wires between rotating levels.

Goal 1 was set because of the initial problem of shooting targets on either side of the inner and

outer tracks. In order to facilit ate a seamless drive-shoot-drive routine quickly, it seemed important to decouple the shooting and driving directions. This required an independently rotating turret atop a driving base.

Goal 2 was set by the minimum dimension of the effective target area (its width), which necessitated greater than 1° of aiming resolution. Though an analog, closed-loop feedback scheme with DC motors (e.g. the driving motors) could potentially do this, the PWM control does not approximate linearity well for small starts and stops. Without specifically testing this, the possibilit y of ending up without the abilit y to resolve our target represented a “show-stopper,” and the option of a stepper motor became appealing.

Initial concerns about suff icient torque with a stepper motor were overshadowed by the potential for complete aiming failure, and by the clear lack of controllabilit y of DC motors. Additionally, 200-step steppers with a good deal of torque were freely available and within size constraints. And the desire to use a gear ratio of at least 2:1 to improve on its 1.8° resolution per step also lessened concerns about torque by a similar factor.

Goal 3 acknowledged that there would be multiple power and communication module wires running between the turret and the base, and that independent movement between the levels of the design would require a central path to avoid serious tangling. Specifically, due to space constraints on the base, it was clear that the turret would have to carry much of the control circuitry, including the Adapt board.

Turret Connector

Turret Pulley

Turret Stepper Motor

Figure 1.2. Bottom of droid base, turret parts labeled.

Page 6: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

6

Because of this, a 1” diameter, unobstructed hole was set to pass through the center of the base-turret interface. Implementation: Freedom

The turret’s rotational freedom came from one 6” lazy susan bearing set, placed on the center axis, and sandwiched between, the base and turret structures. This put a marginally-strict, though non-negligible restriction on structural features of the base and turret. It is mentioned here because it is a good example of a purchased, straight-forward part that might seem to provide its functionality “ for free,” but always has some integration cost. In the end, the limitation on bolt placement due to the lazy susan bearing was easily avoided through careful planning. Connection

Goal 3, above, along with the space constraint on the base that prohibited putting a stepper motor directly next to the through-hole, led to the design and construction of the “ turret connector” (Fig. 1.3).

Salient features of this structure are its abilit y to remain rigid under torque, its easily-adjustable height to accommodate clearance either way, and its ½”-acrylic, Lasercammed timing belt pulley. ¼” bolts provide the bulk of the support, with variable length and a stable connection to the turret structure. Compression strengthens the #6 bolts that fasten the pulley to the ¼” bolt structure. The pulley has ~ 2” diameter, with 68 .08” -pitch MXL type timing belt pulley teeth. Though greater diameter would serve both turning resolution and torque constraints, the designed minimum separation of the driving motor shafts required this pulley not to exceed its 2” diameter. Discussion:

Careful design of the mechanical parts of the turret yielded a robust, functional turret to spin independently of the base, with ~ ½° per step resolution using a Minebea 200 step/revolution stepper motor. This was tested successfully with the full shooting mechanism aboard the turret, but previous to the addition of some controlli ng circuitry. Unfortunately, the initial worry about torque from the stepper motor became a reality during the final stage of integration. The added rotational inertia of the three additional circuit boards on the turret during full capacity caused the turret to exceed the torque limit for the stepper motor. Though any relief whatsoever would enable the turret to rotate reliably, this relief was impossible due to the space constraints of our shooter turret. An attempt to provide more voltage to the stepper was not suff icient to solve this problem, and was limited by excessive heating of the L293B H-bridge stepper driver. To date, this problem is unresolved. The next step (no pun intended) is to acquire and test a smaller belt pulley on the stepper shaft to help relieve its torque load. Additionally, another H-bridge in parallel with the existing will halve the current and heating issues of the L293B, and could improve performance suff iciently.

Figure 1.3. SolidEdge turret-connector.

Page 7: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

7

Drive Design Goal: Create a drive system that allows for coaxial, centered wheels to be independently driven by two motors. Implementation: Motors

The freely-distributed Pittman motors were chosen as the driving motors because they eased budget constraints while simultaneously allowing us to use a set of motors and motor controllers with which the team was already experienced.

Unfortunately, the Pittmans were too wide to enable a direct-drive system with coaxial wheels while still allowing for a central turret axis with its necessary through-hole for connection wires. This led to several indirect drive schemes, including the possibilit y of a gear-drive system, and finally settling on a timing belt pulley system. Indirection

The implementation of the indirect driving system required two custom-made parts: the wheel pulley and the bracket. The rest of the design allowed the engineers at Rollerblade to take responsibilit y for the wheels that freely spin about a 5/16” bolts via bearings within the wheels, and the weight capacity to hold the droid (far over-spec.).

The wheel pulleys were chosen to have the same pitch as the turret pulley (for use with a standard 0.08”-pitch MXL timing belt). They were connected to the Rollerblade wheels via five #6-32 bolts that fit snugly within pre-existing holes in the Rollerblade wheels. They were Lasercammed from ½” acrylic (Fig. 1.4,5).

Though pulleys for the motor shafts were also designed in SolidEdge and made on the Lasercamm, these were not used in the final construction because of the availabilit y of more robust, MXL timing belt pulleys with set screws and ¼” bores (McMaster-Carr).

Figure 1.4. Driving system.

Motor Shaft Pulley

Wheel Pulley

Free Pulley (Tensions belt)

Bracket

Figure 1.5. Wheel assembly in SolidEdge.

Page 8: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

8

The brackets were designed in SolidEdge: Sheet Metal, and were machined from 1/16” steel in the Product Realization Lab. Of note are the unused vertical slots in each bracket that were designed to hold bi-directional, tensioning free pulleys. This design was unable to provide suff icient tension, however, so a unidirectional tension arm was instead fastened to the base of each bracket to hold a free pulley to tension the timing belts. Though it represents a compromise in the original design, reverse motion of the droid was still possible at low speeds, and was entirely unnecessary for the completion of the assigned task. Discussion:

Happily, the driving mechanisms worked completely, meriting no discussion. Of note is that machining inexperience, and general enjoyment of the machine shop prevented these parts from being completed as early as they should have been for the integration process to begin.

Page 9: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

9

Load and Shoot Load Loading mechanism is simply implemented by a cup as the following figure. By making a revolution in the direction shown below, the cup loads exactly one ball onto the shooting wheel. At the first design with this concept, JMR placed the tube a little steeply so that balls easily roll down to the cup. But, there was a large friction between the ball coming out of the tube and the wall inside the tube when the stepper motor rotated. In that reason, the stepper motor could not overcome that sometimes. So, JMR just gave a gentle slope somewhat sacrificing the chance of balls stalling inside the tube, which turned out not to be a big problem. Shoot

Shooting was done by rolling balls into the entrance between a shooting wheel and a curved PVC ball path. JMR spent lots of time to make a shooting mechanism so that it can give a consistent and reasonably distant shooting. At the primitive stage of designing this shooting mechanism, there came two ways for shooting at variously located targets. First one is to give a constant but high duty cycle for shooting motor. If it shoots strong and straight enough, the strategy would be successful. The second one is varying the PWM for shooting motor according to the distance. JMR took the second way, because in this way, we though we could get the chance to avoid blocking by giving a high angle.

For the first several days after implementing the prototype for this mechanism, JMR could not get a sufficiently distant shooting, and thought the reason to be the shortage of DC motor power or some kind of material problem. But it turned out to be due to the loose connection between the driving axis and the shooting motor axle.

Once two axles were coupled strongly and co-axially with a coupler, JMR could get a consistent and distant shooting. When about 90% duty-cycle was given, the motor shot the ball at the 75 inches-apart goal successfully, which is the most distant among four pre-fixed goal distances. From then on, shooting distance could be easily modified just by applying different PWM dutycycles.

Due to the large inertia of the shooting wheel, it took about 1 second to get to the desired angular velocity. JMR later took this factor into account when designing the software for shooting.

JMR employed turret mechanism for aiming with an intention of separating the driving and the shooting modules. We thought by the separation, the driving orientation would not be affected by shooting.

Figure 1.7. Down the barrel of a loaded gun

Figure 1.6. Ball loader in action.

Page 10: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

10

Electrical Design Sensors EMF sensor 2 EMF sensors were used to sense the electro-magnetic field generated from the 20kHz AC sine wave signal running through a wire embedded in the track. Each sensor was placed in the opposite side of the wire in horizontal direction 4 cm from the ground and 5.5 cm from each other. This sensor is simply a solenoid coil with ferrite core material making it more sensitive to the change of magnetic flux. A simple RLC resonant circuit resonating at the frequency of about 20 kHz was used to detect the change in magnetic flux through the cross-section of each coil. The difference between the strength of the left and right sensor signals was then interpreted as the relative position of the robot with respect to the current running wire. Sensors were placed in horizontal position since this configuration can eliminate the dead spot in EMF sensing which happens when a vertically set up coil is directly located above the wire. Also 4 cm clearance from the ground provided more linearity in the sensor response whereas signal strength deteriorated as the sensors moves up. The particularly chosen value of 4 cm was the result of the trade-off between linearity and signal strength.

Output+

22uF

+47uF

5V

6144

61448.2mH

7.7nF 6144DIODE

0.01uF6144

61440.01uF

DIODE61447.7nF

8.2mH

1k

1k

2k

100k

100k

2k

1k

1k

100k

10k

100k1M

1M

10k

Fig 2.1. EMF Sensor Circuit

In the parallel RLC resonant circuit shown in the circuit diagram, the desired resonant frequency is at 20kHz. We know the inductance of the inductor thus can find a proper capacitor value for the resonant circuit.

][2021

0 HzkLC

×== πω where L = 8.2mH

][72.7][2.8])[202(

12

FnHmHzk

C =××

Take Vin as the induced voltage across the inductor and Vout as the voltage across the output node. The transfer function between Vout and Vin can be calculated as the following.

Page 11: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

11

LCRC

ss

C

s

V

V

in

out

12 ++= where L = 8.2mH, C = 7.72nF

Choose an appropriate value for R such that the response can become flatter in the vicinity of the resonant frequency, 20kHz. However, we needed to keep in mind that huge R value could kill the resonant characteristic of the circuit. Thus, we selected R = 10k[ohm] as the value for our Q killer resistor. Bode plot for the resonant circuit with the calculated values was provided below and we can easily see that the magnitude response peaks at the frequency of 125k[rad/sec] or 20kHz but decreases fast in both directions as we move far away from the resonant frequency.

Fig 2.2. Frequency Response of Resonant Circuit

In the sensing circuit, output of the resonant circuit goes through an x100 amplification stage first. Here, non-inverting amplifier with the gain of about 100 was chosen over the inverting configuration so that the minimum amount of current is drawn out of the resonant circuit. Then a simple peak detector was implemented to measure the strength of the incoming signal. In this part of the circuit, incoming ac signal is rectified as it goes through the diode and the capacitor bridging the diode output to the ground hold the peak value of the signal. The 1M[ohm] resistor provides a path to the ground so that the capacitor can slowly discharge when the signal falls below the previously detected peak. A buffer sitting next separates the output of the peak detector and the difference amplifier. Without this buffer, most of the peak detector output current will be drawn to the difference amplifier since the input impedance for the difference amplifier is much lower than the 1M[ohm] resistor connected to the ground, and thus will cause unexpected changes in voltage at the peak detector output. The outputs from the two buffers go through a difference amplifier with the gain of 50 and the center voltage of 2.5[V] so that the output of the amplifier is centered

Page 12: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

12

around 2.5[V] and moves up when the left sensor signal is stronger than the right sensor signal and moves down when the right sensor signal is stronger than the left sensor signal. IR Beacon Sensor A single IR sensor was used to detect the beacon and locate the target. An IR phototransistor and a trans-resistive circuit were used to detect the signal and ampli fy it in the first stage. The positive input terminal of the op-amp was connected to the 2.5[V] so that we can detect the voltage drop at the output terminal proportional to the strength of the incoming IR signal. The buffer connected to the output separates the sensor output from the rest of the circuit composed of a difference ampli fier, two active filters and two peak detectors. The positive input terminal of the difference ampli fier was connected to the 2.5[V] via a 1k resistor and to the ground via a 100k resistor, whereas the negative input terminal was connected to the output of the trans-resistive circuit via a 1k resistor and to the output via a 100k feedback resistor. In such a way, the trans-resistive circuit output is subtracted from 2.5[V] and then ampli fied 100 times to appear at the output terminal yielding an output signal ranging from 0 to 5[V] proportional to the strength of the detected IR signal. The output of the difference ampli fier was split and fed into 2 different filters. One is a low-pass filter with corner frequency at 482[Hz] used to detect the beacon signal pulsing at the frequency of 450[Hz] and the other is also a low-pass filter but with corner frequency at 2341[Hz] used to locate the target pulsing at the frequency of either 1200[Hz] or 1930[Hz]. Then a simple peak detector with a 1M[ohm] resistor giving a path to the ground was used in both circuits to roughly measure the amplitude of the output signals. These signals then went through Schmidt triggers to provide digital inputs to the HC12.

LED1

LM32474LS14LM324LM324

0.1uF

1N4935LM324LM324

5V

0.1uFLM324

0.1uF 0.1uF5V

LED174LS244

74LS14LM324LM324

0.1uF

1N4935LM324LM324

5V

0.1uFLM324LM324

0.1uF 0.1uF

LM324

+

22uF

LM324

5V

LM324

5V

LM324

1M

1M

100

33k

1k

33k

1k

10k

10k680 680

10k 1k

100

33k

1k

33k

1k

10k

10k3.3k 3.3k

10k 1k100k

100k

1k

1k

100k

1.5k

1.5k

Fig. 2.3. Circuit Schematic for IR Beacon Sensor Strobe Sensor A strobe sensor circuit is fundamentally the same as the beacon sensor circuit without the filters. This is due to the fact that a flash emits a fair amount of infrared light in addition to the visible light and thus it is possible to detect the flash even in a lighted environment. As in the beacon sensor case, a trans-resistive configuration with 2.5 [V] positive input voltage was implemented with a buffer following the output. A difference ampli fier with a gain of 10 was good enough to make a decent distinguishable output without being disturbed by the ambient light. The monostable 555 wasn’ t a necessary element to detect a flash signal but it was put in a circuit to provide a consistent 1 [mS] short pulse to the flip-flop. The toggling flip-flop was there to provide a way to visually see the status of the flash detector through an LED. The LED toggles when a flash signal is detected.

Page 13: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

13

LED1

I0I1I2I3

O0O1O2O3

OE

74LS244

5V

0.1uF

SD

CPR

Q_Q

74LS74

0.1uF

5V5V

GndTrgOutRst Ctl

ThrDisVcc

5556144

LM3245V

LM324

5V

LM324

100100k

10M1k

10k

1k

10k

1k

10k

10k

100k

Fig 2.4. Strobe Sensor Circuit Tape Sensor A tape sensor is simply a pair of an IR emitter and a phototransistor wrapped up together. The collector node of the phototransistor was connected to the ground via a potentiometer to allow any future gain adjustment. The output then went through a Schmidt trigger to provide a clean on/off signal to the HC12.

LM324 74LS14

+5V

20k 50%1k

Fig 2.5. Tape Sensor Circuit Navigation/Tracking Control Controller A simple lead controller was implemented to control the posture of the robot. The main objective of the controller was to keep the difference between the 2 EMF sensor signals close to 0 so that the moving direction of the robot is tangential to the direction of the wire embedded in the track. As the robot moves along its intended path, various internal/external disturbances come into the system and force the robot to deviate from the desired path. The amount of deviation is then sensed through the EMF sensors and the controller eventually acts on the actuator (i.e., motor) based on this error signal to rotate the plant (i.e., our robot) so that the error goes to 0. Thus, it was a natural conclusion that the controller was considered to be a regulator rather than a tracking device.

PlantController

GK+

-0

Fig. 2.6. Block Diagram for the System

Page 14: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

14

The robot was considered to be a simple 1/s2 plant with actuator torque acting on the plant to maintain its orientation. The damping and the stiffness terms were omitted because damping was provided through the friction among the mechanical components and the back emf of the motor, and the effect of this term on the overall behavior of the system was considered to be rather small compared to that of the mass term. To speak of the stiffness term, there is no or very little stiffness related to the response of the system. The motor shaft might act as a torsional spring but we are not going to worry about that. Thus, the equation of motion of the system was given as:

Θ= ��MT where T: Torque applied to the system Applied motor torque is proportional to the current going through the motor and thus proportional to the PWM duty cycle.

M: Mass of the system θ: Rotational angle of the system And the transfer function from T to Θ is:

2

1

sΜ=

ΤΘ

A lead controller is a variation of a proportional-derivative controller. Since a pure derivative controller was not easy to be implemented in hardware, a pole about 3-20 times farther from the origin than a zero was added to form a lead controller. Proportional control was to respond to the size of the error signal and derivative control was to respond to the rate of change of the error signal. Integral control was not considered here since we were not worrying about the steady state error very much. Because the system was not identified accurately, several controllers were tested in a trial-and-error way. A few tryouts gave an acceptable controller with a pole at about 5 and a zero at about 1 with the gain of 3.3. Thus, the controller transfer function was given as:

5

13.3

++=

s

sK

A root locus plot and an impulse response plot for the plant/controller closed loop system was given below to roughly describe the system behavior.

Fig 2.7. Root locus / impulse response plot for the plant and controller

Page 15: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

15

To transfer the controller transfer function into a circuit, the transfer function was first broken into several terms using partial fraction expansion. Each term was converted to a corresponding block diagram and each block was converted to a matching circuit.

5

)15(3.33.3

5

13.3

+−−=

++==

ss

suK

ε

where u: controller output e: controller input (error)

εε

21 uu −=

where u1 / e: 3.3 u2 / e: 3.3(5-1) / (s+5) Here the second term can be written as

εεε

××+−=××=+××=+

43.35

43.35

43.3)5(

22

22

2

uu

uu

su

In a functional block diagram form, the controller transfer function K can be decomposed such as the one shown below.

uu2u2'u1-

+

+

+

e

5

43.3

Fig 2.8. Functional Block Diagram for the Controller Corresponding controller circuit schematics is as following.

Controller output

Error Signal

6144

1uF

6144

6144 1k

1k

1k

200k

240k

3.3k

1k

Fig 2.9. Circuit Schematics for the Controller Originally, all of the motor control was done in hardware using an astable 555 to generate short clock pulses and a monostable 555 to modulate the outgoing pulse width utilizing CONT input, i.e. pulse width

Page 16: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

16

being proportional to the input voltage at the CONT terminal. If this voltage rises above 2.5[V], outgoing pulse duty cycle increases above 50%, whereas it decreases below 50% when the voltage falls below 2.5[V] providing a neat way to interface between the controller output voltage and the PWM driver duty cycle.

Left Motor

Right Motor

EMFSensor

Astable Monostable

0.1uF0.1uF5V5V5V5V5V5V

100k 60%GndTrgOutRst Ctl

ThrDisVcc

555

GndTrgOutRst Ctl

ThrDisVcc

555 1k1k

2k

100k

Fig 2.10. Circuit Schematics for Hardware PWM Although we had fairly successful test result, software pulse width modulation was implemented eventually in order to take advantage of the more flexible nature of the software control. Basic structure for the software control was to take the EMF sensor output through an A/D port and adjust the outgoing pulse width of HC12 PWM subsystem accordingly. For example, 2.5 [V] corresponded to 50% duty cycle for both motors and the voltage below 2.5 [V] yielded higher duty cycle for the left motor and lower duty cycle for the right motor proportional to the deviation from the 2.5 [V]. Power We chose to use two 7.2V NiCad, rechargable RC car batteries in series as our power source. This was connected directly as the high voltage rail for our DC motor drivers. We used an LM2825 Simple Switcher to provide the 5V source for our electronics. It was used in the standard datasheet configuration. Our Adapt board was separately powered off of an LM2941 Adjustable Voltage Regulator, providing a stepped-down 8.5 volts to its on-board regulator.

Page 17: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

17

Software Design State Machine

1) STATE_INTACT Waiting for an switch input for deciding which track it will take. This state is the initial state. After this machine go through the whole state, it returns to this state again. 2) STATE_WAIT_OUTER Ready for running the outer track. When it recognizes flash input, it starts to run the outer track. 3) STATE_WAIT_OUTER Ready for running the inner track. When it recognizes flash input, it starts to run the inner track. 4) STATE_GO_OUTER Execute the running and shooting process in the outer track. There are basically 4 repeated sub process in this state, which also are in the state "STATE_GO_INNER". This basic process is as follows.

a. Follow the tape until it hits tape line and stop. b. apply the next dutycycle for the shooting motor. b. aim. (By rotating turret back and forth). c. Shoot. (By dropping a ball from ball holder to shooting wheel) d. Iterate process b. and c. until it gets success signal(450Hz).

Since there are 4 goals to shoot in each track, you just need to repeat the above sequence 4 times. 5) STATE_GO_INNER Execute the running and shooting process in the inner track. The only difference between the "STATE_GO_OUTER" and the "STATE_GO_INNER" is the sequence of shooting distances. Modular Description 1) Driving JMR used current sensing for driving. As stated in the circuit part, we placed 2 inductors by which the software can know how much the vehicle deviate from the center of tape. We are using a value from the circuitry output which goes higher when it deviates more to the right from the center. The software reads this value by AD conversion. The neutral value of it is 0x80 and varies from 0 to 0xFF according to the degree the vehicle deviates from the tape center.

Start switch For outer track

INTACT WAIT_OUTER

WAIT_INNER

GO_OUTER

GO_INNER

Start switch For inner track

Flash

Flash

Page 18: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

18

2) Aiming We employed turret mechanism for aiming. Actually we could have used driving wheel to steer for aiming, but wanted to separate the aiming and the shooting modules. For aiming, the turret rotates back a littl e (about 10 degrees) then rotate in the opposite direction until it gets the signal. (IR sensor is aligned in the same direction with shooting path.) 3) Shooting Shooting is basically accomplished by feeding a ball i nto the shooting motor. Shooting motor is always rotating just varying the angular velocity a littl e bit. To feed a ball , we used a cup holder which is attached to a stepper motor. During a turn, it feeds exactly one ball i nto the shooting motor. Therefore, in the software sense, shooting means just giving the (loading) stepper motor a rotation.

To shoot at targets located in different distances, we varied the PWM for shooting motor. Since, it takes a while for the actual shooting motor to come up to the desired velocity, we should take this into account. The usual sequence is go-stop-aim-and-shoot. So, before it starts to "go", we set the PWM which is needed in the "shoot" stage so that it can get the desired velocity in the meantime. 4) Stepper motor driving We are using 2 stepper motors, one of which is for ball l oading and another is for turret rotating. Basically, to drive a stepper motor, 4 signals are needed to define a state. But we didn’ t want to use as many as 8 pins (2 stepper * 4 pins) for driving two stepper motors, we used a simple logic to reduce the necessary pins coming out of the HC12, by which we could drive a stepper motor with just 2 output pins. - The sequence of signal for driving a stepper motor.

Step Signal 4 Signal 3 Signal 2 Signal 1 Step 1 OFF ON OFF ON Step 2 ON OFF OFF ON Step 3 ON OFF ON OFF Step 4 OFF ON ON OFF

HC293

HC12

4

3

2

1

1

0

1

23

3 4

1 2

By coming through the logic above, we can simply manipulate the stepper motor with just two pin, which has the sequence as follows

Step Port 1 Port 0 Step 1 OFF OFF Step 2 OFF ON Step 3 ON OFF Step 4 ON ON

Page 19: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

19

Pseudo-code 1. state_machine.c void init_proc(void) stop the droid clear time-out flag reset the remaining ball count Initialize PWM, timer, ADC and input/output port. current_state = STATE_INTACT void check_generic_event(void) IF stop switch is pressed init_proc() IF 2min time-out happens init_proc() void aim(void) rotate the turret back a little in counter-clockwise DO UNTIL IR signal detection turret_spin_one_step(CLOCKWISE) check_events() void get_distance_for_shooting(int round, int track) IF(track == OUTER_TRACK) switch (round) case ROUND_ONE: return DISTANCE_ONE case ROUND_TWO: return DISTANCE_TWO case ROUND_THREE: return DISTANCE_THREE case ROUND_FOUR: return DISTANCE_FOUR default: return ERROR ELSE switch (round) case ROUND_ONE: return DISTANCE_FOUR case ROUND_TWO: return DISTANCE_TWO case ROUND_THREE: return DISTANCE_ONE case ROUND_FOUR: return DISTANCE_THREE default: return ERROR void aim_and_shoot(void) enable_stepper()

Page 20: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

20

DO UNTIL 450Hz IR signal detection aim() IF(get_remaining_ball_count() > 0) shoot() delay for 1 sec disable_stepper() void proc_one_round(int round, int track) shotr_distance = get_distance_for_shooting(round, track) set_shoot_distance(shoot_distance) DO UNTIL both tapes are on proceed droid check_events stop the droid void proc_intact(void) WHILE until Inner or Outer switch pressed check_generic_event() // check generic event IF switch for outer track run is pressed current_state = STATE_WAIT_OUTER If switch for outer track run is pressed current_state = STATE_WAIT_INNER clear all flags set by switches void proc_wait(int track) WHILE flash detection flag isn't set check_events() clear flash detection flag IF track == OUTER_TRACK current_state = STATE_GO_OUTER ELSE current_state = STATE_GO_INNER void proc_go(int track) FOR round = 1 to 4 proc_one_round(round, track) check_events() DO UNTIL both tape is on follow the tape check_events()

Page 21: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

21

stp the droid current_state = STATE_INTACT void machine_proc(void) init_proc() // initialize the procedure WHILE stop button is not pressed check_events() switch (current_state) case STATE_INTACT proc_intact() case STATE_WAIT_OUTER proc_wait(OUTER_TRACK) case STATE_WAIT_INNER proc_wait(INNER_TRACK) case STATE_GO_OUTER proc_go(OUTER_TRACK) case STATE_GO_INNER proc_go(INNER_TRACK) 2. motor_controller.c unsigned int mt_read_controller(void) return AD converted control value void mt_get_dutycycle(unsigned int *l_dutycycle, unsigned int *r_dutycycle) atd_value = mt_read_controller() signal= (atd_value - NEUTRAL_CONTROL_VAL) *l_dutycycle= -signal + BASE_DUTYCYCLE) *r_dutycycle= signal + BASE_DUTYCYCLE) void mt_drive(unsigned int l_dutycycle, unsigned int r_dutycycle) apply dutycycle to the PWM for driving motors void mt_stop(void) mt_drive(0, 0) 3. shooter.c void shoot(void) FOR k=0 to STEP_FOR_DROPPING spin_one_step(0, CCLOCKWISE) /* delay for 0.3 seconds to make sure the ball drop into the cup holder */ delay(300); FOR k=0 to STEP_FOR_HOLDING spin_one_step(0, CCLOCKWISE)

Page 22: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

22

IF count_remaining_balls > 0 count_remaining_balls = count_remaining_balls - 1 void set_shoot_distance(int distance) switch (distance) case DISTANCE_ONE: _H12PWDTY2 = duty_one case DISTANCE_TWO: _H12PWDTY2 = duty_two case DISTANCE_THREE: _H12PWDTY2 = duty_three case DISTANCE_FOUR: _H12PWDTY2 = duty_four

Page 23: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

23

Conclusions What went wrong It didn’ t work. We started too late. We began integration too late. We used a prototype platform for too long. We over-designed. We tested the electrical systems on the breadboard, but not on the solder board until it was too late. We required too much torque of a stepper motor. We spent too much time in the machine shop. We tried to hold ourselves to a strict budget, and traded our time for our money. We did not budget time for unexpected delays/problems. We presumed that things that had worked in the past would work again. We didn’ t bring enough food to lab. We did not map out our circuit placement well . We were too willi ng to spend the entire last week in the lab. Mistakes were made. What we could have done to avoid this We could have scheduled our tasks individually and together in a more strict way. We could have worried less about the budget. We could have opted for the simplest solution to every problem, ignoring elegance. We could have spent more time with our coach. We could have rigorously tested our stepper motor earlier in the design process. We could have budgeted extra time to integrate our project beyond the extra time we had budgeted…everything took longer than we thought it would. We could have taken ME218B before and known all of this.

Page 24: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

24

Appendix A: Source Code Source Code Index

Basic.c Initialization functions (PWM, timer, ADC, etc) and delay function.

Ir_detector.c IR detection interrupt functions and functions for letting other modules to know the current states of tape detections.

Tape_sensor.c Interrupt functions for tape detections and functions for letting other modules to know the current states of tape detections.

Flash_detector.c Flash detection interrupt functions and functions for letting other modules to know the current states of tape detections.

Switch_detector.c Interrupt functions for switch detection and functions for letting other modules to know the current status of flag set by the switches.

Timer.c Interrupt functions for 2min time-out and functions for letting other modules to know the current status of flag set by the timer.

Stepper_motor.c Basic functions for rotating stepper motor. Shooter.c Functions for loading and shooting mechanism. Turret.c Functions for turret rotation. Motor_controller.c Functions for driving vehicle. State_machine.c State machine for this application.

C files

Main.c main procedure Basic.h Header file for basic.c Ir_detector.h Header file for Ir_detector.c Tape_sensor.h Header file for Tape_sensor.c Flash_detector.h Header file for Flash_detector.c Switch_detector.h Header file for Switch_detector.c Timer.h Header file for Timer.c Stepper_motor.h Header file for Stepper_motor.c Shooter.h Header file for Shooter.c Turret.h Header file for Turret.c Motor_controller.h Header file for Motor_controller.c

Header files

State_machine.h Header file for State_machine.c

Page 25: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

25

/************************************************************************** Module basic.h Description Header file for basic.c Notes None ****************************************************************************/ #ifndef BASIC_H #define BASIC_H /*----------------------------- Include Files -----------------------------*/ #include <me218_912.h> #include <dbprintf.h> /*---------------------------- Module Variables ---------------------------*/ #define OFF 0 #define ON 1 #define ERROR -1 #define CCLOCKWISE 0 #define CLOCKWISE 1 /* for register bit setting */ #define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 /*-------------------------- Module declaration ---------------------------*/ void delay(int msec); void initialize(void); #endif /*------------------------------ End of File ------------------------------*/

Page 26: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

26

/************************************************************************** Module basic.c Description Initialization functions(PWM, timer, ADC, etc) and delay function. Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" /*---------------------------- Module Variables ---------------------------*/ #define COUNT_FOR_1MS_DELAY 660 /* for 1khz generation. */ /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function init_pwm Parameters None Returns None Description Initializes PWM. Usage of PWM: Port P0: PWM for left driving motor Port P1: PWM for right driving motor Port P2: PWM for shooting motor Notes None ****************************************************************************/ void init_pwm(void) { /* not concatenated. */ _H12PWCLK = _H12_PCKA2 | _H12_PCKB2; /* choose clock S0 and S1 as the source. */ _H12PWPOL = _H12_PCLK2 | _H12_PCLK1 | _H12_PCLK0 | _H12_PPOL2 | _H12_PPOL1 | _H12_PPOL0; /* Set the period of PWM channel 0, 1 and 2 to be $FF */ _H12PWPER0 = BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0; _H12PWPER1 = BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0; _H12PWPER2 = BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0; /* center-aligned */ _H12PWCTL = _H12_CENTR; /* Enables both channel 0, 1 and 2 */ _H12PWEN = _H12_PWEN0 | _H12_PWEN1 | _H12_PWEN2; /* Initializing duty cycles are 0 */ _H12PWDTY0= OFF; _H12PWDTY1= OFF; _H12PWDTY2= OFF; } /**************************************************************************** Function init_atd Parameters None Returns None Description Initializes ADC for driving motor control. Notes None ****************************************************************************/ void init_atd(void) { _H12ATDCTL2 = _H12_ADPU;

Page 27: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

27

_H12ATDCTL5 = _H12_SCAN | _H12_MULT | _H12_CC | _H12_CB | _H12_CA; } /**************************************************************************** Function init_in_out Parameters None Returns None Description Initializes input/output for port DLC. Notes All port T will be used only for input capture. ****************************************************************************/ void init_in_out(void) { /* Set Port DLC to be output */ _H12DDRDLC = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7; } /**************************************************************************** Function init_timer Parameters None Returns None Description Initializes timer for input capture. Notes Usage of Port T: Port T0; left tape sensor. (rising/falling) Port T1; right tape sensor. (rising/falling) Port T2; flash sensor. (rising) Port T3; Switch for stopping procedure. (rising) Port T4; Below 1.5kHz IR signal. (rising/falling) Port T5; Below 450Hz IR signal. (rising/falling) Port T6; Switch for starting inner line. (rising) Port T7; Switch for starting outer line. (rising) Usage of Overflow: 2 minute-timer ****************************************************************************/ void init_timer(void) { /* set all channels for input capture */ _H12TIOS = OFF; /* turn the timer system on */ _H12TSCR = _H12_TEN; /* Input Capture on both rising and falling edges of Port T 0~1, and on rising edge of Port 2, 3 */ _H12TCTL4 = _H12_EDG0A | _H12_EDG0B | _H12_EDG1A | _H12_EDG1B | _H12_EDG2A | _H12_EDG3A; /* Input Capture on both rising and falling edges of Port T 4~5, and on rising edge of Port 6, 7 */ _H12TCTL3 = _H12_EDG4A |_H12_EDG4B |_H12_EDG5A |_H12_EDG5B |_H12_EDG6A | _H12_EDG7A; /* Reset bit 0 ~ 7 */ _H12TFLG1 = _H12_C0F | _H12_C1F | _H12_C2F | _H12_C3F | _H12_C4F | _H12_C5F | _H12_C6F | _H12_C7F; /* Enable bit 0~7 */ _H12TMSK1 = _H12_C0I | _H12_C1I | _H12_C2I | _H12_C3I | _H12_C4I | _H12_C5I | _H12_C6I | _H12_C7I; /* Enable overflow interrupt and set the prescaler factor to be 32 */

Page 28: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

28

_H12TMSK2 = _H12_TOI | _H12_PR2 | _H12_PR0; } /**************************************************************************** Function delay Parameters msec: time to delay in miliseconds. Returns None Description Delay for the time given. Notes The value of COUNT_FOR_1MS_DELAY was given by experiment. ****************************************************************************/ void delay(int msec) { unsigned int j, k; for(j=0; j < msec; j++) { for(k=0; k < COUNT_FOR_1MS_DELAY; k++) ; } } /**************************************************************************** Function initialize Parameters None Returns None Description Initializes timer, port input/output, PWM and ADC altogether. Notes None ****************************************************************************/ void initialize(void) { init_timer(); init_in_out(); init_pwm(); init_atd(); } /*------------------------------ End of File ------------------------------*/

Page 29: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

29

/************************************************************************** Module flash_detector.h Description Header file for flash_detector.c Notes None ****************************************************************************/ #ifndef FLASH_DETECTOR_H #define FLASH_DETECTOR_H /*----------------------------- Include Files -----------------------------*/ void clear_flash_flag(void); int get_flash(void); #endif /*------------------------------ End of File ------------------------------*/

Page 30: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

30

/************************************************************************** Module flash_detector.c Description flash detection interrupt functions Notes Port allocation for flash detection port T2 : detect flash singal. (Rising edge only) ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "flash_detector.h" /*---------------------------- Module Variables ---------------------------*/ static int flash_sensor = OFF; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function flash_detect Parameters None Returns None Description If flash light is detected, it switches the variable "flash_sensor" into "ON". Notes Triggered only on the rising edge. ****************************************************************************/ __interrupt void flash_detect(void) { flash_sensor = ON; /* reset the flag for Port T2 */ _H12TFLG1 = _H12_C2F; } /**************************************************************************** Function get_flash Parameters None Returns None Description returns the value of "flash_sensor". Notes Use in order to let other modules know the current value of module variable. ****************************************************************************/ int get_flash(void) { return flash_sensor; } /**************************************************************************** Function clear_flash_flag Parameters None Returns None Description clears the value of "flash_sensor". Notes Use in order to let other modules be able to clear this module variable. ****************************************************************************/ void clear_flash_flag(void) { flash_sensor = OFF; } /*------------------------------ End of File ------------------------------*/

Page 31: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

31

/************************************************************************** Module ir_detecgtor.h Description Header file for ir_detecgtor.c Notes None ****************************************************************************/ #ifndef IR_DETECTOR_H #define IR_DETECTOR_H /*-------------------------- Module declaration ---------------------------*/ int get_ir_one(void); int get_ir_two(void); #endif /*------------------------------ End of File ------------------------------*/

Page 32: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

32

/************************************************************************** Module ir_detector.c Description IR detection interrupt functions Notes Port allocation for IR detection port T5 : sensing signals below 2.4kHz (High during detection) port T3 : sensing signals below 450Hz (High during detection) ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "ir_detector.h" /*---------------------------- Module Variables ---------------------------*/ static int ir_sensor_one = OFF; static int ir_sensor_two = ON; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function ir_detect_one Parameters None Returns None Description If signal below 2.4kHz IR signal is detected, it switches the variable "ir_sensor_one" into "ON". If the signal goes off, it switcheds the variable into "OFF". Notes Triggered both on the rising and falling edges. This function is used to detect any of valid signal from IR beacon. ****************************************************************************/ __interrupt void ir_detect_one(void) { /* signal below 2.4kHz detected */ if(_H12PORTT & BIT5 == BIT5) ir_sensor_one = ON; else ir_sensor_one = OFF; /* reset the flag for Port T5 interrupt */ _H12TFLG1 = _H12_C5F; } /**************************************************************************** Function ir_detect_two Parameters None Returns None Description If signal below 450Hz IR signal is detected, it switches the variable "ir_sensor_two" into "ON". If the signal goes off, it switcheds the variable into "OFF". Notes Triggered both on the rising and falling edges. This function is used to detect only below 450Hz signals from IR beacon whereby the robot recognizes whether shooting succeeded or not. ****************************************************************************/ __interrupt void ir_detect_two(void) { /* when IR signal below 450Hz detected */ if(_H12PORTT & BIT3 == BIT3) ir_sensor_two = ON; else ir_sensor_two = OFF; /* reset the flag for Port T3 interrupt */ _H12TFLG1 = _H12_C3F;

Page 33: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

33

} /**************************************************************************** Function get_ir_one Parameters None Returns None Description returns the value of "ir_sensor_one". Notes Use in order to let other modules know the current value of module variable. ****************************************************************************/ int get_ir_one(void) { return ir_sensor_one; } /**************************************************************************** Function get_ir_two Parameters None Returns None Description returns the value of "ir_sensor_one". Notes Use in order to let other modules know the current value of module variable. ****************************************************************************/ int get_ir_two(void) { return ir_sensor_two; } /*------------------------------ End of File ------------------------------*/

Page 34: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

34

/************************************************************************** Module motor_controller.h Description Header file for motor_controller.c Notes None ****************************************************************************/ #ifndef MOTOR_CONTROLLER_H #define MOTOR_CONTROLLER_H /*-------------------------- Module declaration ---------------------------*/ void mt_drive(unsigned int l_dutycycle, unsigned int r_dutycycle); void mt_stop(void); #endif /*------------------------------ End of File ------------------------------*/

Page 35: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

35

/************************************************************************** Module motor_controller.c Description functions for vehicle-driving motor. Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "motor_controller.h" /*---------------------------- Module Variables ---------------------------*/ #define BASE_DUTYCYCLE 0x80 /* basic motor speed */ #define MAX_ALLOWABLE_DUTYCYCLE 0xF8 /* maximum allowable dutycycle*/ #define NEUTRAL_CONTROL_VAL 0x88 /* neutral value for current detection*/ /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function mt_read_controller Parameters None Returns digitally converted control value. Description returns digitally converted control value. Notes None ****************************************************************************/ unsigned int mt_read_controller(void) { return _H12ADR3H; } /**************************************************************************** Function mt_check_limit Parameters dutycycle: input dutycycle to be checked. Returns None Description If dutycycle value is bigger than maximum allowable value, return the maximum allowable value. Notes None ****************************************************************************/ unsigned int mt_check_limit(int dutycycle) { if (dutycycle > MAX_ALLOWABLE_DUTYCYCLE) return MAX_ALLOWABLE_DUTYCYCLE; else return dutycycle; } /**************************************************************************** Function mt_get_dutycycle Parameters l_dutycycle: returned dutycycle for left wheel motor r_dutycycle: returned dutycycle for right wheel motor Returns None Description get dutycycles for both wheel driving motors based upon control value. Notes None ****************************************************************************/ void mt_get_dutycycle(unsigned int *l_dutycycle, unsigned int *r_dutycycle) { /* This value increases as the vehicle is more deviated to the left (0~255)*/

Page 36: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

36

unsigned int atd_value; /* Positive value of "signal" means that the vehicle is deviated to the left. */ int signal; /* Read digitallized control value which becomes greater as the vehicle is more off to the left from the center line. */ atd_value = mt_read_controller(); signal= (atd_value - NEUTRAL_CONTROL_VAL); *l_dutycycle= mt_check_limit(-signal + BASE_DUTYCYCLE); *r_dutycycle= mt_check_limit(signal + BASE_DUTYCYCLE); } /**************************************************************************** Function mt_drive Parameters l_dutycycle: dutycycle for left wheel motor r_dutycycle: dutycycle for right wheel motor Returns None Description set duty cycle based on the input values. Notes None ****************************************************************************/ void mt_drive(unsigned int l_dutycycle, unsigned int r_dutycycle) { _H12PWDTY0= l_dutycycle; _H12PWDTY1= r_dutycycle; } /**************************************************************************** Function mt_stop Parameters None Returns None Description stop the vehicle. (set both dutycycle to be 0) Notes None ****************************************************************************/ void mt_stop(void) { mt_drive(0, 0); return; } /*------------------------------ End of File ------------------------------*/

Page 37: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

37

/************************************************************************** Module shooter.h Description Header file for shooter.c Notes None ****************************************************************************/ #ifndef SHOOTER_H #define SHOOTER_H /*---------------------------- Module Variables ---------------------------*/ #define FULL_BALLS_COUNT 8 #define DISTANCE_ONE 74 #define DISTANCE_TWO 32 #define DISTANCE_THREE 75 #define DISTANCE_FOUR 64 /*-------------------------- Module declaration ---------------------------*/ void set_shoot_distance(int distance); void shoot(void); int get_remaining_ball_count(void); void set_remaining_ball_count(void); #endif /*------------------------------ End of File ------------------------------*/

Page 38: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

38

/************************************************************************** Module shooter.c Description functions for loading and shooting mechanism. Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "stepper_motor.h" #include "shooter.h" /*---------------------------- Module Variables ---------------------------*/ /* H12_PIN_OFFSET_TURRET: The smaller pin number of the two Port DLC pins which control the stepper motor for loading. We use Port DLC 0 and 1 for controlling the loader. */ #define H12_PIN_OFFSET_LOADER 0 #define STEP_FOR_FULL_ROTATION 200 #define STEP_FOR_DROPPING 100 #define STEP_FOR_HOLDING STEP_FOR_FULL_ROTATION - STEP_FOR_DROPPING static int count_remaining_balls = FULL_BALLS_COUNT; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function shoot Parameters None Returns None Description Load and drop a ball onto the rolling motor which is designed to shoot balls. Loading and dropping balls are totally done by rotating a stepper motor attached to the loading can. Notes None ****************************************************************************/ void shoot(void) { int k; /* temporary variable for loop count */ /* drop a ball from the cup holder */ for(k=0; k < STEP_FOR_DROPPING; k++) { spin_one_step(H12_PIN_OFFSET_LOADER, CCLOCKWISE); delay(10); /* delay for .01 secs to slow down the physical rotation */ } /* delay for 0.3 seconds to make sure the ball drop into the cup holder */ delay(300); /* load another ball onto the cup holder */ for(k=0; k < STEP_FOR_HOLDING; k++) { spin_one_step(H12_PIN_OFFSET_LOADER, CCLOCKWISE); delay(10); /* delay for .01 secs to slow down the physical rotation */ } /* count down remaining ball */ if(count_remaining_balls > 0) count_remaining_balls--; } /**************************************************************************** Function set_shoot_distance Parameters distance: distance to shoot at. Returns None

Page 39: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

39

Description set the dutycycle for shooting motor based upon the distance to shoot at. This function will be called at lease 1 second before the actual shooting so that the actual rotating speed of shooting wheel can be guaranteed. Notes None ****************************************************************************/ void set_shoot_distance(int distance) { /* dutycycles for different distances given by physical experiments */ static const int duty_one = 0xD0; static const int duty_two = 0x90; static const int duty_three = 0xE0; static const int duty_four = 0xC3; /* set the dutycycle of shooting motor based upon the distance at which the shooting motor shoot. */ switch (distance) { case DISTANCE_ONE: _H12PWDTY2 = (unsigned char)duty_one; break; case DISTANCE_TWO: _H12PWDTY2 = (unsigned char)duty_two; break; case DISTANCE_THREE: _H12PWDTY2 = (unsigned char)duty_three; break; case DISTANCE_FOUR: _H12PWDTY2 = (unsigned char)duty_four; break; default: _H12PWDTY2 = (unsigned char)duty_one; break; } } /**************************************************************************** Function get_remaining_ball_count Parameters None Returns count of remaining balls. Description returns the count of balls which remains on the vehicle. Notes None ****************************************************************************/ int get_remaining_ball_count(void) { return count_remaining_balls; } /**************************************************************************** Function set_remaining_ball_count Parameters None Returns None Description set the count of remaining ball again. (initialize the ball count) Notes None ****************************************************************************/ void set_remaining_ball_count(void) { count_remaining_balls = FULL_BALLS_COUNT; }

Page 40: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

40

/*------------------------------ End of File ------------------------------*/

Page 41: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

41

/************************************************************************** Module state_machine.h Description Header file for state_machine.c Notes None ****************************************************************************/ #ifndef STATE_MACHINE_H #define STATE_MACHINE_H /*-------------------------- Module declaration ---------------------------*/ void machine_proc(void); #endif /*------------------------------ End of File ------------------------------*/

Page 42: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

42

/************************************************************************** Module state_machine.c Description Main procedure for driving the vehicle. Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "turret.h" #include "shooter.h" #include "stepper_motor.h" #include "ir_detector.h" #include "motor_controller.h" #include "switch_detector.h" #include "tape_sensor.h" #include "timer.h" #include "state_machine.h" /*---------------------------- Module Variables ---------------------------*/ #define MAX_STEP_RANGE_FOR_IR_DETECT 10 #define INNER_TRACK 0 #define OUTER_TRACK 1 #define ROUND_ONE 1 #define ROUND_TWO 2 #define ROUND_THREE 3 #define ROUND_FOUR 4 #define TOTAL_ROUND 4 #define STATE_INTACT 0 #define STATE_WAIT_OUTER 1 #define STATE_WAIT_INNER 2 #define STATE_GO_OUTER 3 #define STATE_GO_INNER 4 #define INIT_STEP_FOR_IR_DETECT 20; static int current_state = STATE_INTACT; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function init_proc Parameters None Returns None Description initialize the procedure. clear flags and states. Initialize PWM, ADC, timer and in/out ports. Notes None ****************************************************************************/ void init_proc(void) { /* Just in case the vehicle starts in any reason. */ mt_stop(); /* Disalbe stepper motors to save power and prevent from the 293B getting hot */ disable_stepper(); /* clears 2min time-out */ clear_time_out(); /* Reset the remaining ball count */ set_remaining_ball_count(); /* Initialize PWM, timer, ADC and input/output port. */ initialize(); /* Reset the current state to be "STATE_INTACT" */ current_state = STATE_INTACT; }

Page 43: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

43

/**************************************************************************** Function check_events Parameters None Returns None Description check if stop switch is pressed or time-out happened. If so, initialize the procedure. Notes This function will be called in every loop the main procedure experiences. ****************************************************************************/ void check_events(void) { /* if stop switch is pressed */ if(get_stop_procedure()) { clear_stop_procedure(); init_proc(); } /* if 2min time-out happens */ if(get_time_out()) { init_proc(); } } /**************************************************************************** Function aim Parameters None Returns None Description Position the turret so that the shooting path align with the goal. i.e., rotate the turret until it detects the 1.5kHz beacon. Notes None ****************************************************************************/ void aim(void) { /* spin back a little in counter-clockwise */ turret_spin(-1 * MAX_STEP_RANGE_FOR_IR_DETECT); /* spin until it finds the 1.5kHz IR signal */ while(!(get_ir_one() == ON && get_ir_two() == OFF)) { turret_spin_one_step(CLOCKWISE); check_events(); } } /**************************************************************************** Function get_distance_for_shooting Parameters round: the number of round which you are interested in. There are four go-aim-shoot sequence in each track. track: the track this vehicle is following. (INNER_TRACK / OUTER_TRACK) Returns None Description Get the distance from the vehicle to the goal to be shot. Notes None ****************************************************************************/

Page 44: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

44

int get_distance_for_shooting(int round, int track) { /* If the vehicle follows the outer track */ if(track == OUTER_TRACK) { switch (round) { case ROUND_ONE: return DISTANCE_ONE; case ROUND_TWO: return DISTANCE_TWO; case ROUND_THREE: return DISTANCE_THREE; case ROUND_FOUR: return DISTANCE_FOUR; default: return ERROR; } } /* If the vehicle follows the inner track */ else { switch (round) { case ROUND_ONE: return DISTANCE_FOUR; case ROUND_TWO: return DISTANCE_TWO; case ROUND_THREE: return DISTANCE_ONE; case ROUND_FOUR: return DISTANCE_THREE; default: return ERROR; } } return ERROR; } /**************************************************************************** Function aim_and_shoot Parameters None Returns None Description aim and shoot until it succeeds in shooting. Notes None ****************************************************************************/ void aim_and_shoot(void) { /* enables stepper motor */ enable_stepper(); /* aim and shoot until it detects 450Hz IR signal */ while(get_ir_two() == OFF) { /* rotate the turret until the canon aligns with the goal */ aim(); /* if there is remaining ball on the vehicle */ if(get_remaining_ball_count() > 0) { shoot(); } /* if there is no remaining ball, exit the "aim and shoot" procedure */ else

Page 45: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

45

{ DB_printf("\r\nno available balls"); break; } /* delay for 1.5 sec to wait for the physical shooting to occur. */ delay(1500); } /* disables stepper motor */ disable_stepper(); } /**************************************************************************** Function proc_one_round Parameters round: the number of round which you are interested in. There are four go-aim-shoot sequence in each track. track: the track this vehicle is following. (INNER_TRACK / OUTER_TRACK) Returns None Description A process of go-aim-shoot sequence. Notes Initially, we must set the direction of turret approximately to be headed toward the target beacon at the position it will stop to shoot. ****************************************************************************/ void proc_one_round(int round, int track) { int shoot_distance; /* shooting distance */ /* duty-cycles for left and right driving motors */ unsigned int l_dutycycle, r_dutycycle; /* get the shooting distance */ shoot_distance = get_distance_for_shooting(round, track); /* apply duty cycle based upon the shooting distance */ set_shoot_distance(shoot_distance); /* proceed the vehicle until both tape sensors hit the tape. */ while( !(get_tape_one() && get_tape_two()) ) { /* follow the tape */ mt_get_dutycycle(&l_dutycycle, &r_dutycycle); mt_drive(l_dutycycle, r_dutycycle); /* check time-out and stop-switch interrupt */ check_events(); } /* stop the vehicle */ mt_stop(); /* aim the goal and shoot until it succeeds */ aim_and_shoot(); } /**************************************************************************** Function proc_go Parameters track: the track this vehicle is following. (INNER_TRACK / OUTER_TRACK) Returns None Description procedure after the flash detection. This procedure includes the followings.

Page 46: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

46

- four go-aim-shoot procedure. - go until the final line. Notes None ****************************************************************************/ void proc_go(int track) { int round; /* round: the number of round. */ /* duty-cycles for left and right driving motors */ unsigned int l_dutycycle, r_dutycycle; /* process four go-aim-shoot procedure in series. */ for(round=1; round<=TOTAL_ROUND; round++) { proc_one_round(round, track); /* check time-out and stop-switch interrupt */ check_events(); } /* proceed the vehicle until both tape sensors hit the final line. */ while( !(get_tape_one() == ON && get_tape_two() == ON) ) { /* follow the tape */ mt_get_dutycycle(&l_dutycycle, &r_dutycycle); mt_drive(l_dutycycle, r_dutycycle); /* check time-out and stop-switch interrupt */ check_events(); } /* stop the vehicle */ mt_stop(); /* reset the current state to be "STATE_INTACT" for another run */ current_state = STATE_INTACT; } /**************************************************************************** Function proc_wait Parameters track: the track this vehicle is following. (INNER_TRACK / OUTER_TRACK) Returns None Description wait for a flash, then set the current status into a new one based upon the previous one. state transition: STATE_WAIT_OUTER -> (flash) -> STATE_GO_OUTER STATE_WAIT_INNER -> (flash) -> STATE_GO_INNER Notes None ****************************************************************************/ void proc_wait(int track) { /* wait for flash detection */ while(get_flash() == OFF) { /* check time-out and stop-switch interrupt */ check_events(); } /* clear flash status flag */ clear_flash_flag(); /* set the current status based upon the previous status */ if(track == OUTER_TRACK) current_state = STATE_GO_OUTER; else

Page 47: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

47

current_state = STATE_GO_INNER; } /**************************************************************************** Function proc_intact Parameters None Returns None Description Wait for a switch input to decide which track it will follow and set the current status into a new one based upon that input. state transition: STATE_INTACT -> (switch-inner) -> STATE_WAIT_OUTER STATE_INTACT -> (switch-outer) -> STATE_WAIT_INNER Notes None ****************************************************************************/ void proc_intact() { int outer, inner; /* wait until a switch input */ while((inner = get_start_inner_line()) == OFF && (outer = get_start_outer_line()) == OFF) { /* check time-out and stop-switch interrupt */ check_events(); } /* if switch for outer track run is pressed */ if(outer == ON) { current_state = STATE_WAIT_OUTER; /* clear all flags set by switches */ clear_all_button_flags(); } /* if switch for outer track run is pressed */ else if(inner == ON) { current_state = STATE_WAIT_INNER; /* clear all flags set by switches */ clear_all_button_flags(); } } /**************************************************************************** Function machine_proc Parameters None Returns None Description state machine for whole procedure. Notes None ****************************************************************************/ void machine_proc(void) { /* initialize the procedure */ init_proc(); /* keep going until a keyboard hit happens. */ while(!kbhit()) { /* check time-out and stop-switch interrupt */ check_events();

Page 48: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

48

/* process the proper procedure based upon the current status */ switch (current_state) { case STATE_INTACT: proc_intact(); break; case STATE_WAIT_OUTER: proc_wait(OUTER_TRACK); break; case STATE_WAIT_INNER: proc_wait(INNER_TRACK); break; case STATE_GO_OUTER: proc_go(OUTER_TRACK); break; case STATE_GO_INNER: proc_go(INNER_TRACK); break; } } } /*------------------------------ End of File ------------------------------*/

Page 49: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

49

/************************************************************************** Module stepper_motor.h Description Header file for stepper_motor.c Notes None ****************************************************************************/ #ifndef STEPPER_MOTOR_H #define STEPPER_MOTOR_H /*-------------------------- Module declaration ---------------------------*/ void spin_one_step(int hc12_pin, int direction); void enable_stepper(void); void disable_stepper(void); #endif /*------------------------------ End of File ------------------------------*/

Page 50: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

50

/************************************************************************** Module stepper_motor.c Description Basic functions for rotating stepper motor. Notes Basically, we use two pins out of HC12 to drive a stepper motor. If we let the two pins to be pin1 and pin2, the sequence for driving a stepper will be like this. (pin2 / pin1) OFF / OFF OFF / ON ON / OFF ON / ON. The actual sequence will be made by coming through logic chips which consists of an AND and a XOR. ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "stepper_motor.h" /*---------------------------- Module Variables ---------------------------*/ static const int base_step1 = 0x00; static const int base_step2 = 0x01; static const int base_step3 = 0x02; static const int base_step4 = 0x03; static const int base_selector = 0x03; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function spin_one_step Parameters hc12_pin: The smaller pin number of the two Port DLC pins which control the corresponding stepper motor. direction: The direction in which the stepper motor rotates CLOCKWISE; clockwise CCLOCKWISE; counter-clockwise Returns None Description Rotates a stepper motor for a step. Notes None ****************************************************************************/ void spin_one_step(int hc12_pin, int direction) { /* current value of HC12 for driving stepper motor */ unsigned int cur_value; /* values of port DLC in each step for driving stepper motor */ int step1 = base_step1 << hc12_pin; int step2 = base_step2 << hc12_pin; int step3 = base_step3 << hc12_pin; int step4 = base_step4 << hc12_pin; /* value for selecting just two digits which is interested */ int selector = base_selector << hc12_pin; /* current value of port DLC which is corresponding to the stepper motor you are driving. */ cur_value = _H12PORTDLC & selector; /* If the direction you want to drive is clockwise the sequence is step1 -> step2 -> step3 -> step4 */ if(direction == CLOCKWISE) { if(cur_value == step1) _H12PORTDLC = (_H12PORTDLC & ~selector) | step2; else if(cur_value == step2) _H12PORTDLC = (_H12PORTDLC & ~selector) | step3; else if(cur_value == step3)

Page 51: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

51

_H12PORTDLC = (_H12PORTDLC & ~selector) | step4; else _H12PORTDLC = (_H12PORTDLC & ~selector) | step1; } /* If the direction you want to drive is counter-clockwise the sequence is step4 -> step3 -> step2 -> step1 */ else { if(cur_value == step1) _H12PORTDLC = (_H12PORTDLC & ~selector) | step4; else if(cur_value == step2) _H12PORTDLC = (_H12PORTDLC & ~selector) | step1; else if(cur_value == step3) _H12PORTDLC = (_H12PORTDLC & ~selector) | step2; else _H12PORTDLC = (_H12PORTDLC & ~selector) | step3; } /* give a delay for .01 sec to wait for the physical moving catch up */ delay(10); } /**************************************************************************** Function enable_stepper Parameters None Returns None Description Enables stepper motor Notes Port DLC4 is used for stepper motor enable bit. You want to turn the stepper motor off when it is not used, since the driver 293B gets hot if turned on for a long while. ****************************************************************************/ void enable_stepper(void) { _H12PORTDLC = _H12PORTDLC | BIT4; } /**************************************************************************** Function disable_stepper Parameters None Returns None Description Disable (turn off) stepper motor Notes Port DLC4 is used for stepper motor enable bit. You want to turn the stepper motor off when it is not used, since the driver 293B gets hot if turned on for a long while. ****************************************************************************/ void disable_stepper(void) { _H12PORTDLC = _H12PORTDLC & ~BIT4; } /*------------------------------ End of File ------------------------------*/

Page 52: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

52

/************************************************************************** Module switch_detector.h Description Header file for switch_detector.c Notes None ****************************************************************************/ #ifndef SWITCH_DETECTOR_H #define SWITCH_DETECTOR_H /*-------------------------- Module declaration ---------------------------*/ int get_start_inner_line(void); int get_start_outer_line(void); int get_stop_procedure(void); void clear_start_inner_line(void); void clear_start_outer_line(void); void clear_stop_procedure(void); void clear_all_button_flags(void); #endif /*------------------------------ End of File ------------------------------*/

Page 53: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

53

/************************************************************************** Module switch_detector.c Description Interrupt functions for switch detection and functions for letting other modules to know the current status of flag set by the switches. Notes Port T Usage for switches: T3: stop procedure switch T6: start inner line switch T7: start outer line switch ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "switch_detector.h" /*---------------------------- Module Variables ---------------------------*/ static int start_inner_line = OFF; static int start_outer_line = OFF; static int stop_procedure = OFF; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function switch_start_inner_line Parameters None Returns None Description Set the "start_inner_line" flag when called. Notes Called only on the rising edge. ****************************************************************************/ __interrupt void switch_start_inner_line(void) { start_inner_line = ON; /* reset the flag for Port T6 interrupt */ _H12TFLG1 = _H12_C6F; } /**************************************************************************** Function switch_start_outer_line Parameters None Returns None Description Set the "start_outer_line" flag when called. Notes Called only on the rising edge. ****************************************************************************/ __interrupt void switch_start_outer_line(void) { start_outer_line = ON; /* reset the flag for Port T7 interrupt */ _H12TFLG1 = _H12_C7F; } /**************************************************************************** Function switch_stop_procedure Parameters None Returns None Description Set the "stop_procedure" flag when called. Notes

Page 54: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

54

Called only on the rising edge. ****************************************************************************/ __interrupt void switch_stop_procedure(void) { stop_procedure = ON; /* reset the flag for Port T4 interrupt */ _H12TFLG1 = _H12_C4F; } /**************************************************************************** Function get_start_inner_line Parameters None Returns None Description returns the value of "start_inner_line". Notes Use in order to let other modules know the current value of this module variable. ****************************************************************************/ int get_start_inner_line(void) { return start_inner_line; } /**************************************************************************** Function get_start_outer_line Parameters None Returns None Description returns the value of "start_outer_line". Notes Use in order to let other modules know the current value of this module variable. ****************************************************************************/ int get_start_outer_line(void) { return start_outer_line; } /**************************************************************************** Function get_stop_procedure Parameters None Returns None Description returns the value of "stop_procedure". Notes Use in order to let other modules know the current value of this module variable. ****************************************************************************/ int get_stop_procedure(void) { return stop_procedure; } /**************************************************************************** Function clear_start_inner_line Parameters None Returns

Page 55: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

55

None Description clears the value of "start_inner_line". Notes Use in order to let other modules be able to clear this module variable. ****************************************************************************/ void clear_start_inner_line(void) { start_inner_line = OFF; } /**************************************************************************** Function clear_start_outer_line Parameters None Returns None Description clears the value of "start_outer_line". Notes Use in order to let other modules be able to clear this module variable. ****************************************************************************/ void clear_start_outer_line(void) { start_outer_line = OFF; } /**************************************************************************** Function clear_stop_procedure Parameters None Returns None Description clears the value of "stop_procedure". Notes Use in order to let other modules be able to clear this module variable. ****************************************************************************/ void clear_stop_procedure(void) { stop_procedure = OFF; } /**************************************************************************** Function clear_all_button_flags Parameters None Returns None Description clears all the flags in this module altogether. Notes Use in order to let other modules be able to clear these module variable. ****************************************************************************/ void clear_all_button_flags(void) { clear_start_inner_line(); clear_start_outer_line(); clear_stop_procedure(); } /*------------------------------ End of File ------------------------------*/

Page 56: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

56

/************************************************************************** Module tape_sensor.h Description Header file for tape_sensor.c Notes None ****************************************************************************/ #ifndef TAPE_SENSOR_H #define TAPE_SENSOR_H /*-------------------------- Module declaration ---------------------------*/ int get_tape_one(void); int get_tape_two(void); #endif /*------------------------------ End of File ------------------------------*/

Page 57: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

57

/************************************************************************** Module tape_sensor.c Description Interrupt functions for tape detections and functions for letting other modules to know the current states of tape detections. Notes Port allocation for tape detection port T0 : left tape sensor detection (rising/falling) port T1 : right tape sensor detection (rising/falling) ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "tape_sensor.h" /*---------------------------- Module Variables ---------------------------*/ static int tape_one = OFF; static int tape_two = OFF; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function tape_sensor_one Parameters None Returns None Description interrupt function for tape sensing. The sensor for this one is attached on the left side of vehicle. Notes Triggered both on the rising and falling edge. use Port T0 for this one ****************************************************************************/ __interrupt void tape_sensor_one(void) { /* if port T0 is high */ if(_H12PORTT & BIT0 == BIT0) tape_one = ON; else tape_one = OFF; /* reset the flag for Port T0 interrupt */ _H12TFLG1 = _H12_C0F; } /**************************************************************************** Function tape_sensor_two Parameters None Returns None Description interrupt function for tape sensing. The sensor for this one is attached on the right side of vehicle. Notes Triggered both on the rising and falling edge. use Port T1 for this one ****************************************************************************/ __interrupt void tape_sensor_two(void) { /* if port T1 is high */ if(_H12PORTT & BIT1 == BIT1) tape_two = ON; else tape_two = OFF; /* reset the flag for Port T1 interrupt */ _H12TFLG1 = _H12_C1F; }

Page 58: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

58

/**************************************************************************** Function get_tape_one Parameters None Returns None Description Function for letting other modules know the current state of tape sensor one. Notes None ****************************************************************************/ int get_tape_one(void) { return tape_one; } /**************************************************************************** Function get_tape_two Parameters None Returns None Description Function for letting other modules know the current state of tape sensor two. Notes None ****************************************************************************/ int get_tape_two(void) { return tape_two; } /*------------------------------ End of File ------------------------------*/

Page 59: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

59

/************************************************************************** Module timer.h Description Header file for timer.c Notes None ****************************************************************************/ #ifndef TIMER_H #define TIMER_H /*----------------------------- Include Files -----------------------------*/ int get_time_out(void); void clear_time_out(void); #endif /*------------------------------ End of File ------------------------------*/

Page 60: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

60

/************************************************************************** Module timer.c Description Interrupt functions for 2min time-out and functions for letting other modules to know the current status of flag set by the timer. Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "timer.h" /*---------------------------- Module Variables ---------------------------*/ #define COUNT_FOR_2SEC 452 static int overflow_count = 0; static int time_out = OFF; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function timer_overflow Parameters None Returns None Description Set the "time_out" flag when called. Notes None ****************************************************************************/ __interrupt void timer_overflow(void) { if(overflow_count++ == COUNT_FOR_2SEC) time_out = ON; /* reset the timer flag */ _H12TFLG2 = _H12_TOF; } /**************************************************************************** Function get_time_out Parameters None Returns None Description returns the value of "time_out". Notes Use in order to let other modules know the current value of this module variable. ****************************************************************************/ int get_time_out(void) { return time_out; } /**************************************************************************** Function clear_time_out Parameters None Returns None Description clears the value of "overflow_count" and "time_out". Notes Use in order to let other modules be able to clear timer count. ****************************************************************************/ void clear_time_out(void) {

Page 61: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

61

overflow_count = 0; time_out = OFF; } /*------------------------------ End of File ------------------------------*/

Page 62: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

62

/************************************************************************** Module turret.h Description Header file for turret.c Notes None ****************************************************************************/ #ifndef TURRET_H #define TURRET_H /*-------------------------- Module declaration ---------------------------*/ void turret_spin_one_step(int direction); void turret_spin(int step); #endif /*------------------------------ End of File ------------------------------*/

Page 63: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

63

/************************************************************************** Module turret.c Description Functions for turret rotation Notes Port DLC 2 and 3 are used to drive stepper motor for turret rotating. ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "basic.h" #include "stepper_motor.h" #include "turret.h" /*---------------------------- Module Variables ---------------------------*/ /* H12_PIN_OFFSET_TURRET: The smaller pin number of the two Port DLC pins which control the stepper motor for turret. We use Port DLC 2 and 3 for controlling the turret. */ static const int H12_PIN_OFFSET_TURRET = 2; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function turret_spin_one_step Parameters direction: the direction in which the turret rotates. CLOCKWISE; clockwise CCLOCKWISE; counter-clockwise Returns None Description rotate the turret in the given direction. Notes Port DLC 2 and 3 are used for driving turret stepper motor. The smaller value of these, which is 2, is the first argument for the function "turret_spin_one_step". ****************************************************************************/ void turret_spin_one_step(int direction) { spin_one_step(H12_PIN_OFFSET_TURRET, direction); } /**************************************************************************** Function turret_spin Parameters step: the steps for which the turret rotates. If this value is positive, the turret rotates clockwise, otherwise, it rotates counter-clockwise. Returns None Description rotate the turret for the given steps. Notes Port T 2 and 3 are used for driving turret stepper motor. The smaller value of these, which is 2, is the first argument for the function turret_spin_one_step. ****************************************************************************/ void turret_spin(int step) { int k; /* temporary variable for loop count */ int direction; /* CLOCKWISE/CCLOCKWISE */ int actual_step; /* absolute value of variable "step" */ /* If "step" is positive, it means CLOCKWISE. */ if(step > 0) { actual_step = step; direction = CLOCKWISE; } else { actual_step = -step;

Page 64: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

64

direction = CCLOCKWISE; } /* rotate the turret for the given steps */ for(k=0; k<actual_step; k++) { turret_spin_one_step(direction); /* Delay for .05 seconds for the physical turret to follow */ delay(50); } } /*------------------------------ End of File ------------------------------*/

Page 65: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

65

/************************************************************************** Module main.c Description main procedure Notes None ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ #include "state_machine.h" /*---------------------------- Module Variables ---------------------------*/ /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function main Parameters None Returns None Description main function of this application Notes None ****************************************************************************/ void main(void) { machine_proc(); } /*------------------------------ End of File ------------------------------*/

Page 66: Team JMR Ballistic Ball Biathlon: Final Reportross/mywork/JMRFinalReport.pdfTeam JMR Ballistic Ball Biathlon: Final Report June Park Minhwan Lee Ross Venook 2 TABLE OF CONTENTS Table

66

Appendix B: Pin Assignments Pin Assignments

Port AD 7 Current Sensing Control value Port T 0 Left tape sensor interrupt rising / falling 1 Right tape sensor interrupt rising / falling 2 Flash sensor interrupt rising 3 Switch for stopping procedure interrupt rising 4 IR signal below 1.5kHz interrupt rising / falling 5 IR signal below 450kHz interrupt rising / falling 6 Switch for starting inner line interrupt rising 7 Switch for starting outer line interrupt rising Port DLC 0 Stepper motor control 1 (ball loader) 1 Stepper motor control 2 (ball loader) 2 Stepper motor control 1 (turret) 3 Stepper motor control 2 (turret) 4 Stepper motor enable/disable 5 6 Port P 0 PWM for left driving motor 1 PWM for right driving motor 2 PWM for shooting motor