SENG 466: Autonomous and Remote Control Hovercraft

49
SENG 466: Autonomous and Remote Control Hovercraft Doug Cox Department of Computer Science University of Victoria [email protected] Richard Muir Department of Electrical Engineering University of Victoria [email protected] Yaju Jadeja Department of Electrical Engineering University of Victoria [email protected] April 26, 2011

Transcript of SENG 466: Autonomous and Remote Control Hovercraft

Page 1: SENG 466: Autonomous and Remote Control Hovercraft

SENG 466: Autonomous and Remote ControlHovercraft

Doug Cox

Department of Computer ScienceUniversity of Victoria

[email protected]

Richard Muir

Department of Electrical EngineeringUniversity of Victoria

[email protected]

Yaju Jadeja

Department of Electrical EngineeringUniversity of Victoria

[email protected]

April 26, 2011

Page 2: SENG 466: Autonomous and Remote Control Hovercraft

Table of Contents

Table of Contents

List of Figures

List of Tables

1 Introduction 1

2 Materials 2

3 Development 33.1 Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33.2 MotioninJoy Gamepad Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

4 Hovercraft Design 44.1 Body . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44.2 Skirt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.3 Alternate Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

5 Hardware Design 125.1 Circuit Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135.2 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

6 Software Design 176.1 I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176.2 HM55B Compass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206.3 RTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206.4 Remote Station . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

6.4.1 Transceiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216.4.2 Remote Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246.4.3 Autonomous Control . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

7 Results 29

8 Conclusion 30

References 31

A Base Station 32A.1 Radio Transmitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32A.2 Radio Receiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Page 3: SENG 466: Autonomous and Remote Control Hovercraft

B Remote Station 34B.1 Radio Transceiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34B.2 Hovercraft Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36B.3 Autonomous Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

List of Figures1 MotioninJoy Gamepad Tool interface . . . . . . . . . . . . . . . . . . . . . . 32 Final Hovercraft Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Hovercraft skirt construction . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Craft base with rounded corners and additional square air pocket area . . . . 95 Sewing the elastic band strip along the sides of the bag . . . . . . . . . . . . 106 Craft with a single horizontally placed lift motor . . . . . . . . . . . . . . . . 117 Block diagram of power and switching circuit . . . . . . . . . . . . . . . . . 128 Power/Signal Circuit Schematic . . . . . . . . . . . . . . . . . . . . . . . . . 139 Fan Static Pressure Comparison . . . . . . . . . . . . . . . . . . . . . . . . . 1510 Alternative code structure to delay() . . . . . . . . . . . . . . . . . . . . . . 1711 Serial communication from first project . . . . . . . . . . . . . . . . . . . . . 1812 I2Cmastersendingdatatoslave . . . . . . . . . . . . . . . . . . . . . . . . . . 1813 I2C Receive handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1914 Request issuing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1915 Request handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2016 RTOS scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2117 RTOS sonar handling with pulseIn . . . . . . . . . . . . . . . . . . . . . . . 2218 Arduino Uno remote station transceiver . . . . . . . . . . . . . . . . . . . . . 2319 The drive DC motor function . . . . . . . . . . . . . . . . . . . . . . . . . . 2420 Remote Control code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2521 Obstacle detection code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2622 Compass RTOS tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2723 Autonomous motor control . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2824 Power Consumption Measurements . . . . . . . . . . . . . . . . . . . . . . . 29

List of Tables1 Breakdown of equipment and materials . . . . . . . . . . . . . . . . . . . . . 2

Page 4: SENG 466: Autonomous and Remote Control Hovercraft

1 IntroductionThe purpose of this project was to develop a remote controlled hovercraft. This projectwas completed in fulfillment of the requirements fo SENG 466: Software for Embedded andMechatronics Systems. This project builds on the work completed in Project 1: PrototypeBase Station and Remote Station and is the second milestone towards the course goal ofbuilding an autonomous hovercraft.

The final deliverable must be capable of handling a payload of 1.5kg and must consumeno more than 35W of power for its lifting system. Using the airflow generated by propellors,the hovercraft will be lifted by the air captured inside a skirt underneath. The project con-sists of a base station and a remote station, and the hovercraft is controlled by a Playstion 3gamepad connected to the base station that wirelessly communicates with the remote stationonboard the hovercraft.

We will now outline the format for the remainder of the report. Section 1, Materials, willoutline the various components used throughout the project. Section 2, development, wilhighlight the development environment and special tools used. Section 3, Hovercraft Design,will deal with the design of the hovercraft, in particular the physical design of the hover-craft’s body as well as its skirt. Section 5, Hardware Design, will deal with the hardwarecomponents onboard the hovercraft and how they work together to reach the goals set outin the project specification. Section 6, Software Design will discuss the software driving thehovercraft. Section 7, Testing, will outline the testing that was conducted for the hovercraft.Section 8, Results, will discuss the results from our testing. Finally, Section 9 will concludethis report.

1

Page 5: SENG 466: Autonomous and Remote Control Hovercraft

2 MaterialsThe following list of equipment and materials was used in the development of the autonomoushovercraft:

Quantity Item1 Seeeduino Mega (Atmel ATmega 1280 chipset)3 Arduino Uno (Atmel ATmega 328P chipset)2 Solarbotics L298 Motor Driver Kit3 Devantech SRF04 Ultrasonic Range Finder3 Nordic Semiconductor nRF24L01+ MiRF -v2 2.4GHz Radio1 Playstation 3 Wireless Gamepad1 Scythe Ultra Kaze 3000 brushless DC fan1 8HH3-1C-C 5V DC Relay1 Hitachi HM55B Digital Compass Module2 Sparkfun RM1A Motors with Propellers1 DC Brushed Motor (unknown model) with Propeller1 1N4004 Diode2 IRFZ40 N-Channel MOSFETs1 Modified Canon BP-827 Li-Ion Battery Pack1 LM7805 3-Terminal +5V DV regulator

Mylar SkirtVarious resistors, capacitors and lengths of solid wire

Table 1: Breakdown of equipment and materials

2

Page 6: SENG 466: Autonomous and Remote Control Hovercraft

3 Development

3.1 Development Environment

For development of the project we used the Eclipse integrated development environment,available at http://www.eclipse.org. Eclipse provided the ability to compile cross-targetapplications for the AVR-based Arduino microcontrollers. The Eclipse plugin AVR-Pluginwas used as it allowes for simple building and flashing of the .HEX machine code to theArduino microcontrollers. The Eclipse plugin Subclipse was also used as it provided ac-cess to to our Project 2 Subversion version control repository hosted at http://code.

google.com/p/rnmuir-hovercraft/. and the Final Project’s repository located at http:

//code.google.com/p/dacoxhovercraft/.

The program RealTerm was used to monitor serial data passed between the radios onthe base and remote stations. This was useful in debugging radio problems, and was alsoused to receive information from the hovercraft itself.

3.2 MotioninJoy Gamepad Tool

For this project we used a standard Playstation 3 wireless controller to control the hovercraftinstead of the Logitech USB gamepad from the first project. The MotioninJoy GamepadTool[10] is a Windows driver for the Playstation 3 Bluetooth controller. The tool allowed usto connect, disconnect, and test the controller connection.

Figure 1: MotioninJoy Gamepad Tool interface

3

Page 7: SENG 466: Autonomous and Remote Control Hovercraft

4 Hovercraft DesignThe process of selecting the final hovercraft design for this phase in the project involvedseveral different attempts at reaching the goals set out for our team. A trial and error basedapproach to determining an optimal design was used initially, but eventually the realizationwas made that a more refined approach would be required. After researching previousattempts at building a craft meeting similar specifications to ours and the theory involvedin successfully reaching these guidelines, a functional prototype was built and tested.

4.1 Body

Deciding how the hovercrafts body would be designed was an involved process that requiredforesight into how the other components of the craft would come together; the body sup-ports the entire system and there was a fine balance between selecting a size and shapethat was conducive to containing the various sensors, actuators and control systems placedon-board while remaining feasibly supported by the lifting system, responsive to propulsionand appealing to the eye. The material used for the construction of the crafts body alsowent through a few different iterations until a tradeoff between weight and stability wasreached. Careful attention to the weight impact of various modifications to the body wererequired to remain within the project guidelines which stated that the vehicle must remainunder 1500 grams. This was not a trivial goal to meet and attests to the difficulties faced inthe design of any project in general as a weight requirement is almost always a design concern.

The body of the prototype demonstrated for this stage of the project was constructed witha mixture of 1” and ” Pink Panther FOAMULAR C-200 and generic white Styrofoam. Theedges between the panels cut out to build the housing for the lifting system as well as aroundthe perimeter of the craft were sealed with duct tape, as this acted as an easily alterableadhesive which remained airtight, at the expense of added weight.

The dimensions of the crafts upper base deck were 24” long by 14” wide; this was builtof the 1” variety of the FOAMULAR C-200. The thicker 1” material was selected for itsrigidity and weight holding ability; the thinner ” variety was found to bow inwards due tothe weight of the lifting fan and other components placed in the geometric center of the base.

A rectangular piece of the generic white Styrofoam was cut to match the dimensions ofthe upper deck, and four ” spacer blocks were cut from the C-200 board to support each ofthe four corners of the upper deck upon this lower deck of white Styrofoam. The four cor-ners between the upper and lower decks were selected as the supporting points as opposed toplacing an entire perimeter of material between the two decks in order to reduce the weightof the vehicle, as it was determined that the air pressure from the lifting system was morethan adequate to fill the gap. Duct tape was used to seal the open gap on the hovercraftsperimeter between the upper and lower decks.

The housing for the lifting system was 6” long, 9” wide and 5.5” high, and constructedof the ” C-200 board. The housing consisted of four individual panels assembled to form abox with the seams between panels sealed with duct tape. Careful attention was used to

4

Page 8: SENG 466: Autonomous and Remote Control Hovercraft

minimize the amount of duct tape adhering the panels as its weight was certainly significant.One edge of the housing was left open to accommodate the 120mm x 120mm x 30mm ScytheUltra Kaze 3000 brushless DC fan providing the lift for the craft.

The remaining area of the upper deck underneath the housing was cut out and the edgesrounded to act as the entrance for the air being forced under the vehicle. Two 1” x 6” andtwo 1” x 16” evenly spaced rectangular holes were cut out from the lower deck to allow theair to enter the plenum chamber evenly. This design was selected due to its symmetry andperformed much better than other attempted solutions such as a single hole in the centeror several holes spaced evenly across the bottom deck; some attempts seemed to limit theairflow into the air cushion forming underneath the craft due to being slightly too smallwhile others were not entirely symmetric and resulted in uneven air dispersion.

5

Page 9: SENG 466: Autonomous and Remote Control Hovercraft

Figure 2: Final Hovercraft Design

6

Page 10: SENG 466: Autonomous and Remote Control Hovercraft

4.2 Skirt

The design of the hovercrafts skirt was one of the more troublesome aspects in the processof building our vehicle. The air pressure created from the lifting system was more thanadequate to provide a suitable air cushion for the hovercraft to glide upon, but optimizingthe crafts skirt was critical to minimize the friction between the craft and the ground andallow the vehicle to glide over top of small obstacles in its path, such as a divider between alinoleum floor and carpet.

Ultimately, Mylar was chosen as the material used for the skirts construction in the fi-nal iteration of the project prototype. Mylar was chosen mainly for its low friction and easeof use with respect to sealing to the crafts base and making alterations; it proved to be quitedelicate in terms of damage resistance, however. Slight tears in the Mylar skirt could quicklyresult in disaster as snags from the floor could catch upon such tears, leading to larger lateralrips and thus uneven airflow from underneath the hovercrafts base.

Mylar was chosen over the nylon material available to us in our lab due to its lighter weightand smoother surface, resulting in less friction when moving on the ground. The nylon ma-terial may have proved to be more damage-resistant but the benefit of using Mylar for itslower friction and higher ease of use far outweighed that of using the nylon material whichtended to produce a higher drag force on both the carpet and smooth linoleum, as well asbeing much more difficult to seal and attach to the prototypes body.

Several iterations of the skirts physical design itself were tested, with the final design being,conveniently enough, the simplest. (As is often the case). A sheet of Mylar was cut intoa rectangle slightly larger than the crafts base; a smaller rectangle was removed from theMylar sheets inner region to allow for the air escaping from the slits in the lower deck toflow uniformly from the crafts perimeter.

Worth noting is the fact that smoothed, curved corners may have proved to have beenbetter, as this would reduce the perimeter from which the air under the craft would escape.The benefit of the reduced perimeter of using elliptical corners, as opposed to the squaredcorners shown in the pictures below, was thought to be minimal at the scale of this projectbut would likely prove significant on a larger vehicle.

7

Page 11: SENG 466: Autonomous and Remote Control Hovercraft

Figure 3: Hovercraft skirt construction

8

Page 12: SENG 466: Autonomous and Remote Control Hovercraft

4.3 Alternate Design

We designed several other prototypes of the hovercraft for testing various ideas. We triedcrafts with a single duct, dual ducts and also tried several variations of duct placementsaround the base of the craft. We found the rear lift duct system performed much better incomparison. It was discovered that having more air cushion at the front of the craft causedthe system to be more stable. The more the skirt touched the surface, the more it depressedand the skirt flattened out more along the surface.

Figure 4: Craft base with rounded corners and additional square air pocket area

Making the right skirt for the craft was the most time consuming and also the most crit-ical part of the mechanical design. Attempts were made to alter the shape of the craft baseto create an easier fitting bag skirt. We attempted sewing an elastic band strip along thesides of the bag to create an easier fit and help maintain a uniform amount of folds aroundthe corners. Unfortunately, this did not seem to provide a tight enough seal and allowed toomuch air to escape from the edges of the craft’s base.

9

Page 13: SENG 466: Autonomous and Remote Control Hovercraft

Figure 5: Sewing the elastic band strip along the sides of the bag

We also verified the amount of rotational torque added from to a horizontally placed liftmotor was significantly high. Even though the craft lift appeared to be sufficient with nospin on carpet, on smoother surfaces, the craft rotated uncontrollably. This problem waseasily rectified by using two similar motors spinning in opposite directions or placing a singlemotor vertically on the craft. This not only helped prevent the lift but also caused the craftto have a natural tendency to move in a forward direction.

10

Page 14: SENG 466: Autonomous and Remote Control Hovercraft

Figure 6: Craft with a single horizontally placed lift motor

From the above design we learned that having an additional height with more air pocketarea and sufficient volume and pressure of air, the craft lifted very easily without a skirt.With dual horizontal fans, the hover-height was measured to be around 0.3cm with no skirtand a smooth flat bottom surface. Even though the above design was successful, the craftdid not provide a stable lift when additional 1.5 kg of weight was added and placed on acarpet floor. More surface area was required to provide the sufficient lift at that weight.

11

Page 15: SENG 466: Autonomous and Remote Control Hovercraft

5 Hardware DesignThe hardware components chosen in the design of the autonomous hovercraft were carefullyselected to ensure our vehicle was able to meet the specifications set forth in our projectgoals. Careful attention was again needed to remain under the specified weight limit, as wellas provide the steering, lifting and thrusting capabilities of the craft in addition to detect-ing its surroundings and compass heading. The following block diagram outlines the maincomponents used in the hovercraft’s final design and their interconnection.

Figure 7: Block diagram of power and switching circuit

12

Page 16: SENG 466: Autonomous and Remote Control Hovercraft

Outlined in this section are the new additions to our design from the first project mile-stone; in order to avoid redundancy, no further detail is specified with respect to the SRF-04Ultrasonic Rangefinders or the L298D Motor Controller Kits. In addition to this, the circuitdesign and the components chosen will be discussed.

5.1 Circuit Design

Below is a schematic of the circuit implemented for the hovercraft’s power and signal lines.

Figure 8: Power/Signal Circuit Schematic

From the schematic, it can be seen that the entire prototype was powered by a single16V DC power pack. This power pack was constructed from two Canon BP-827 Li-Ioncamcorder batteries; each battery possessed a 3400mAH capacity and provided a potentialof approximately 8V when fully charged. The two batteries were connected in series and usedas a single 16V power source; this provided more than the required voltage for the lifting,propulsion and logic systems. Slightly more than the required voltage was desirable dueto the expected voltage drop under an increasing current due to the battery packs internalresistance.

13

Page 17: SENG 466: Autonomous and Remote Control Hovercraft

A LM7805 5V voltage regulator was used to step-down the voltage from the power packto the vehicle’s 5V logic system. A 0.1 microFarad capacitor was placed in parallel betweenthe regulator and ground and a 0.47 capacitor was placed between the regulator and the16V power source to help filter the regulator’s input and output voltages.

An on/off switch was placed in series with the battery and the rest of the circuit; fromthe switch, the 16V power source provided potential through the 833H-1C-C 5V relay tothe high-current loop consisting of the lifting and propulsion motors. The relay was wiredthrough its normally closed position; when the appropriate signal was sent from the Seee-duino to the IRFZ40 N-Channel MOSFET switching the relay, the relay’s throw wouldswitch to the normally opened position and thus break the high-current loop by preventingthe circuit from grounding at the battery’s ground terminal. A pulldown resistor was placedin parallel with the relay-switching MOSFET and the microcontroller to keep the signalfrom the microcontroller low when not explicitly set high via software and thus keeping thehigh-current loop closed. The relay allowed for the isolation of the high current loop fromthe logic circuit; if the relay were triggered, the 5V output from the LM7805 was unaffectedand the microcontrollers were still powered.

The Scythe Ultra Kaze 3000 brushless DC fan was switched with another IRFZ40 MOS-FET; the MOSFET acted as a switch allowing the path for the electricity drawn by thefan to reach the ground when the appropriate signal was set by the microcontroller; morespecifically, when pin 12 on the Seeeduino was brought high, the MOSFET closed the circuitand turned on the lifting fan, suspending the craft above a cushion of air approximately 2”from the ground. Again, if the relay were activated, the lifting motor would immediatelylose power and the craft would sink back to the floor. Also, another pulldown resistor wasplaced in parallel with the lifting system’s IRFZ40 and the Seeeduino to ensure the signalwas kept low when not explicitly set high. This circumvents the problem of a ”floating”value for the pin controlling the lifting motor.

Each of the two L298D motor controllers were powered from the 16V higher voltageline while their logic lines were at a potential of 5V from the LM7805. Their operationceased when the relay was triggered via the Seeeduino as well because the power and groundterminals were in line with the high voltage loop which would be broken when the relay wastripped.

14

Page 18: SENG 466: Autonomous and Remote Control Hovercraft

5.2 Components

The components utilised in the final design solution were carefully selected for an optimumbalance of performance and weight. Clearly, as the thrust or pressure generated by a partic-ular motor and fan combination increases, the energy cost as well as the weight of the motorrequired to exert such force increases as well. The lifting system was designed with a ScytheUltra Kaze 3000 DC 120mm brushless computer fan as its driving motor.

The Scythe was chosen due to its relatively low current requirement, easily researchedspecifications and cost; the Scythe fan was purchased for under six dollars and was foundto consume only 1.00A at roughly 14.5V upon measurement, corresponding to a power con-sumption of roughly 15W. Other brushed DC fans tested drew in excess of two or three ampsunder the lifting conditions, while actually providing less static pressure than the Scythe fan.Based upon the findings in a report found on Martin’s Liquid Lab[11], the Scythe fan chosenin this design is the clear winner in terms of static pressure performance:

Figure 9: Fan Static Pressure Comparison

15

Page 19: SENG 466: Autonomous and Remote Control Hovercraft

Using a lift calculator found on HoverHawk.com[12], the required static pressure for ahovercraft with a base surface area similar to that of our selected bases dimensions was ap-proximately 0.30” of water at room temperature. As shown on the previous fan comparison,the Scythe is just capable of providing this pressure at 12V, so it can be assumed that thestatic pressure provided at the slightly higher voltage of around 14.5V is only slightly higherthan the 0.32” of water determined by Martin.

The two Sparkfun RM1A steering motors placed at opposite ends of the craft for steeringwere selected for their low weight and high torque; their current consumption at 12V wasapproximately 375mA each while still providing plenty of thrust for rotating the craft aboutits center of gravity.

The brushed DC motor chosen for providing the forward thrust was fitted with a three-bladed, plastic propeller with their blades trimmed by approximately 0.5”; it was determinedthrough testing that the blades provided much more thrust when chopped to 2.5” as opposedto their full-length of 3”.

All signal and power wires were twisted together to shield the main signal wires from themicrocontroller to the various components from any crosstalk. The main thrust fan’s powerand ground wires were twisted with an additional strand of solid wire which was groundedon one end as the thrust fan’s power and ground wires were in close proximity to the wiresused for the I2C communication between the remote Uno and the Seeeduino and before thiswas completed, it was observed that the RTOS on the Seeeduino would occasionally ceasefunctioning and the system would be locked in a certain state, namely the thrust fan beingstuck on and no input into the system was recognized.

Decoupling capacitors were placed across the terminals of all motors and from eachterminal to the motor’s chassis. This technique was suggested in an Arduino tutorial[13].

16

Page 20: SENG 466: Autonomous and Remote Control Hovercraft

6 Software DesignFor the remote and autonomous hovercraft projects we used a variety of different compo-nents and design ideas than we did in the first project. In this project we used I2C, theHM55B electronic compass module, and a real time operating system for the timing of ourautonomous hovercraft. One of the major design changes we made was the the lack of delaysin the code. In the first project we often used commands like delay(), which delays the codefor a number of milliseconds for timing purposes. However, in timing critical applicationsthis is very bad practice. When a delay method is called, the program simply cycles theprocessor, creating a busy wait in which no additional computation can be done. To getaround this, we decided to write code like this:

1 int cur r ent t ime = 0 ;int prev ious t ime = 0 ;

3 int i n t e r v a l = 1000 ; //Mi l l i s e c ond s

5 for ( ; ; ){

7 cur r en t t ime = m i l l i s ( ) ;i f ( cu r r ent t ime > prev ious t ime − i n t e r v a l )

9 {prev ious t ime = cur r ent t ime ;

11 //Do schedu l ed work}

13 //Do other work}

Figure 10: Alternative code structure to delay()

This project consists of a base station connected to the computer which relays datafrom a Playstaition 3 bluetooth gamepad, which itself consists of two Arduino Unos and aradio, and the remote station onboard the vehicle, which consists of an Arduino Uno and aSeeedunio Mega. Another big change was a full duplex radio link between the base stationand the rmeote station for debugging. The dual Arduino Unos in the base station act as atransmitter and a receiver. This unusual formation is due to the fact that the virtual COMport reacted very poorly to having a single bidurectional Arduino Uno as the Python scriptwe rely on for gamepad use was blocking the port. To get around this, we simply used anadditional Arduino Uno to interface with the same radio and allow us to debug receivedmessages on another virtual COM port. The full source code for our duplex radio solutioncan be found in the Appendix.

The remote station onboard the actual hovercraft uses the Arduino Uno as a radiotransceiver to communicate with the base station, and the Seeeduino Mega as the “brain”that interprets packets and handles all of the digital I/O to drive the hovercraft.

6.1 I2C

In the previous project, Serial communiation was used for having the Arduino Uno on theremote station communicate with the Seeeduino Mega. For example, if the Uno issued aSerial.write() command the Mega would accept the information thusly:

17

Page 21: SENG 466: Autonomous and Remote Control Hovercraft

u i n t 8 t data [PACKETLENGTH]2 S e r i a l . Begin (BAUDRATE) ;

4 for ( ; ; ){

6 While ( S e r i a l . a v a i l a b l e ( ) < PACKETLENGTH) ;While ( S e r i a l . a v a i l a b l e ( ) != START BYTE) ;

8 for ( int i = 0 ; i < PACKETLENGTH; i++){

10 data [ i ] = S e r i a l . read ( ) ;}

12 //Do work}

Figure 11: Serial communication from first project

This kind of solution to inter-controller communication is costly and inneffective. It re-quires that the receiving microcontroller busy wait each iteration of the program on datafrom the sending microcontroller, during which time nothing else can be done. Serial com-munication on the Arduinos is also somewhat unreliable.

Our solution for inter controller communication this time around was to use I2C. I2C isa two wire interface with one data line and one enable line. The interface has a seven bitaddress space with 16 reserved addresses, so a total of 112 devices can be used on one I2Cbus. I2C can be setup in a master-slave hierarchy as well as a master-master hierarchy. I2Cis extremely efficient and useful as it is asynchronous and event-driven, so no busy-waitingon packets is necessary. In a master-slave hierarchy, a master may send data to the slavecompletely asynchronously as follows:

1 void setup ( ){

3 Wire . begin ( ) //Begin as master. . .

5 }

7 void loop ( ){

9 . . .Wire . beg inTransmiss ion (ADDRESS) ;

11 Wire . send ( data ) ;Wire . send ( ”a s t r i n g ” ) ;

13 . . .Wire . endTransmission (ADDRESS) ;

15 . . .}

Figure 12: I2Cmastersendingdatatoslave

By wrapping Wire.send() statements in calls to Wire.beginTransmission() and Wire.endTransmission(),the master queues all of the data in those send statements and the sends it out. For a slave

18

Page 22: SENG 466: Autonomous and Remote Control Hovercraft

in this configuration to receive a message, it must have a receive handler. We received datafrom the Seeeduino at the Uno as follows:

u i n t 8 t data [PACKETLENGTH] ;2 RECV FLAG = f a l s e ;

4 void setup ( ){

6 Wire . begin (ADDRESS) ; // Join bus as s l a v eWire . onReceive ( rece iveEvent ) ; // Reg i s t e r r e c e i v e hand ler f unc t i on

8 . . .}

10void rece iveEvent ( int numBytes )

12 {int i = 0 ;

14 while (Wire . a v a i l a b l e ( ) && i < numBytes ){

16 data [ i ] = Wire . r e c e i v e ( ) ;i++;

18 }}

Figure 13: I2C Receive handling

A slave can also send data back to the master in this configuration if the master issuesa request for data. To do this, the slave must also have a request handler. An example ofhow a master might request data follows:

1 void po l l ( ){

3 int i = 0 ;Wire . requestFrom (SLAVE ADDRESS, PACKETLENGTH) ;

5 while (Wire . a v a i l a b l e ( ) && i < PACKETLENGTH){

7 but [ i ] = Wire . r e c e i v e ( ) ;i++;

9 }}

Figure 14: Request issuing

The slave would deal with these requests by having a request handler, just like it had areceive handler. For example:

In this project we used I2C to communicate gamepad packets from the radio Uno to theSeeeduino for evaluation, as well as for communcicating asynchronous debugging informationback to the PC over the radio.

19

Page 23: SENG 466: Autonomous and Remote Control Hovercraft

u i n t 8 t data [PACKETLENGTH]2

void setup ( )4 {

Wire . begin (ADDRESS) // Join bus as s l a v e6 Wire . onRequest ( requestHandler ) // Reg i s t e r r e que s t hand ler f unc t i on}

8void requestHandler ( )

10 {Wire . send (gamepad , 1 8 ) ;

12 }

Figure 15: Request handling

6.2 HM55B Compass

Another new technology we used for this project was the HM55B digital compass. We decidedto use this compass to help our autonomous hovercraft hold a straight line by evaluating itscurrent position in relation to the compass. To interface with the compass, we used somecode found on the Arduino playground. By shifting bits in and out of the compass, we areable to gain the X and Y components of the angle at which the compass is relative to north.

6.3 RTOS

For this project we decided to use the Real Time Operating System (RTOS) provided to uson the lab USB stick. The RTOS was suprising easy to handle and made writing timingsensitive code a streamlined, intuitive process.

The RTOS works by having all time divided into “ticks” that are 5 milliseconds in length.Tasks are then created for the operating system to handle. Tasks are broken up into threecategories:

• Periodic tasks

• System tasks

• Round-Robin Tasks

Periodic tasks are run periodically and are not allowed to busy-wait. They are initiallyassigned a gnerous number of ticks that they must finish within. However, if a task finishesearly the next scheduled task can be started with a call to TaskNext(). System tasks are thelowest level task and they cannot be preempted by any process. As such, System level tasksshould be used sparingly. Finally, Round-Robin tasks are run one tick at a time, sharing theremaining clock cycles fairly.

In the RTOS, all tasks are given a unique id and are defined in the main section of thecode via calls to TaskStart(). For periodic tasks, the task id and expected length in ticks

20

Page 24: SENG 466: Autonomous and Remote Control Hovercraft

\\Unique task Id ’ s2 #de f i n e T SONAR 1#de f i n e TMOTOR 2

4 #de f i n e T COMPASS START 3#de f i n e T COMPASS READ 4

6 #de f i n e T READ 5#de f i n e T PRINT 6

8 const unsigned char PPP [ ] = { T SONAR, 25 , T SONAR, 25 , TMOTOR, 10 } ;

10 void r main ( ){

12 i n i t ( ) ;setup ( ) ;

14 snrInEvent = Event In i t ( ) ; // I n i t i a l i z e eventsTask Create ( sonar task , 0 , PERIODIC, T SONAR) ; // I n i t i a l i z e p e r i o d i c ta sk s

16 Task Create ( motor task , 0 , PERIODIC, TMOTOR) ;Task Create ( compass s ta r t ta sk , 0 , RR, T COMPASS START) ;// I n i t i a l i z e round

rob in18 //Tasks not s to r ed in the PPP array

Task Create ( compass read task , 0 , RR, T COMPASS READ) ;20 Task Create ( read task , 0 , RR, T READ) ;

Task Create ( p r i n t t a sk , 0 , RR, T PRINT) ;22 }

Figure 16: RTOS scheduling

must be put in an array which defines the control flow of the periodic tasks.

Given these types of tasks, it is possible to take code that would normally be blockingand break it up into different kinds of tasks to make it work. For example, in our lastassignment we used calls to pulseIn() to measure the amount of time that the return linegoes HIGH. However, this code busy-waits and as such cannot be called in a Periodic task.We got around this by having a Periodic task that initiates the sonar read, and a roundrobing task that actually reads the sonar data. For example:

By splitting this blocking code into blocking and non-blocking components, the blockingcode can now be time shared in a round-robin fashion while other Periodic tasks occur.

6.4 Remote Station

The remote station onboard the hovercraft consists of a Seeeduino Mega as the “brain” andan Arduino Uno for the radio transceiver. The two microcontrollers communicate over I2C.

6.4.1 Transceiver

The transceiver on the Uno is a slave in the I2C bus. As such, the code for the transceiverfeatures a receive handler and a request handler. When the transceiver receives an asyn-chronous data packet from the Seeeduino, it packages it up and sends it back to the basestation receiver. When the transceiver recieves a packet from the base station transmitter, itholds that data in a buffer. The Seeeduino Mega systematicaly polls the Uno when it wantsmore gamepad data via a request call, which the Uno handles with its request handler.

21

Page 25: SENG 466: Autonomous and Remote Control Hovercraft

void s ona r ta sk ( ) //This i s a PERIODIC Task2 {

for ( ; ; )4 {

for ( int i = 0 ; i < NUMSONARS; i++)6 {

cur r ent t ime = m i l l i s ( ) ;8 i f ( cu r r en t t ime − prev ious t ime > i n t e r v a l )

{10 //Trigger the sonar module

prev ious t ime = cur r ent t ime ;12 d i g i t a lWr i t e (TRIG[ i ] , HIGH) ;

de layMicroseconds (11) ;14 d i g i t a lWr i t e (TRIG[ i ] , LOW) ;

} ;16 Task Next ( ) ;

}18 }}

20void s ona r r e ad ta sk ( )

22 {for ( ; ; )

24 {for ( int i = 0 ; i < NUMSONARS; i++)

26 {DUR[ i ] = pu l s e In (ECHO[ i ] , HIGH) ;

28 Task Next ( ) ;}

30 }}

Figure 17: RTOS sonar handling with pulseIn

22

Page 26: SENG 466: Autonomous and Remote Control Hovercraft

1 void rece iveEvent ( int numBytes ){

3 int i = 0 ;while (Wire . a v a i l a b l e ( ) && i < 18)

5 {data [ i ] = Wire . r e c e i v e ( ) ;

7 i++;}

9 s n r f l a g = 1 ;}

11void sendGamepadToRemote ( )

13 {Wire . send (gamepad , 1 8 ) ;

15 }

17 void loop ( ){

19 i n i t ( ) ;de lay (2000) ;

21 setup ( ) ;

23 void loop ( ){

25 Wire . onRequest ( sendGamepadToRemote ) ; // I n i t i a l i z e r e que s t hand leri f ( r x f l a g )

27 {c l i ( ) ; // d i s a b l e i n t e r r u p t s to prevent race cond i t i on

29 i f ( Radio Receive(&packet ) != RADIO RXMORE PACKETS){

31 //Handle incoming rad io packe t sr x f l a g = 0 ;

33 }s e i ( ) ; //re−enab l e i n t e r r u p t s

35for ( int i = 0 ; i < 18 ; i++)

37 gamepad [ i ] = ( int ) packet . payload . message . messagecontent [ i ] ;

39 //Send packe t s back to basei f ( s n r f l a g )

41 {s n r f l a g = 0 ;

43 packet . type = MESSAGE;memcpy( packet . payload . message . address , remote addr ,

RADIO ADDRESS LENGTH) ;45 packet . payload . message . messageid = 42 ;

memcpy( packet . payload . message . messagecontent , data , 18) ;47 Radio Transmit(&packet , RADIO WAIT FOR TX) ;

}49 }}

Figure 18: Arduino Uno remote station transceiver

23

Page 27: SENG 466: Autonomous and Remote Control Hovercraft

6.4.2 Remote Control

The remote control hovercraft did not use the RTOS, that was included in the autonomoushovercraft. The control flow of the remote hovercraft was for the Seeeduino Mega to pollfor gamepad data by issuing an I2C request to the Arduino Uno. The functions drive() andMap() were implemented to make the code that interprets the gamepad packets easier toread. The drive() function allows one to have a motor drive at a certain PWM duty cyclein either direction with one function call.

void dr ive ( int en , int l1 , int l2 , int dir , int power )2 {

i f ( d i r == FORWARD)4 {

analogWrite ( en , Map( power ) ) ;6 d i g i t a lWr i t e ( l1 , LOW) ;

d i g i t a lWr i t e ( l2 , HIGH) ;8 }

else i f ( d i r == BACKWARD)10 {

analogWrite ( en , Map( power ) ) ;12 d i g i t a lWr i t e ( l1 , HIGH) ;

d i g i t a lWr i t e ( l2 , LOW) ;14 }

else i f ( d i r == STOP)16 {

analogWrite ( en , 0) ;18 d i g i t a lWr i t e ( l1 , LOW) ;

d i g i t a lWr i t e ( l2 , LOW) ;20 }}

Figure 19: The drive DC motor function

The Map() function simply reduces the complexity of the call to map(), part of theArduino library. An invocation of Map(50) will provide a 50% duty cycle by calling thefunction map(50,0,100,0,255), which maps an integer in the range of 0 to 100 (a percent) toan integer in the range of 0 to 255, which is the range used for the analogWrite() functionthat handles PWM control for our DC motors.

The basic control flow is very similar to that of our first project. The program continu-ously polls for new gamepad data and then acts on it at every iteration of the program.

24

Page 28: SENG 466: Autonomous and Remote Control Hovercraft

1 void loop ( ){

3 p o l l ( ) ;

5 //THRUSTi f ( but [CROSS] == 1)

7 {dr ive (THRUST, THRUST L1, THRUST L2, FORWARD, 100) ;

9 }else i f ( but [CIRCLE] == 1)

11 {dr ive (THRUST, THRUST L1, THRUST L2, BACKWARD, 100) ;

13 }else

15 {dr ive (THRUST, THRUST L1, THRUST L2, STOP, 0) ;

17 }//LEFT

19 i f ( but [LONE] == 1){

21 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , FORWARD, 90) ;}

23 else i f ( but [LTWO] == 1){

25 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , BACKWARD, 90) ;}

27 else i f ( but [LONE] == 0 | | but [LTWO] == 0){

29 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , STOP, 0) ;}

31//RIGHT

33 . . .

35 //LIFTi f ( but [SQUARE] == 1)

37 {i f (LIFTED == true )

39 {d i g i t a lWr i t e (LIFT , LOW) ;

41 LIFTED = f a l s e ;}

43 else{

45 d i g i t a lWr i t e (LIFT , HIGH) ;LIFTED = true ;

47 }}

49 }

Figure 20: Remote Control code

25

Page 29: SENG 466: Autonomous and Remote Control Hovercraft

6.4.3 Autonomous Control

For the autonomous control we originally planned to just use sonars to measure the distanceon either side and keep the vehicle moving in a straight line down the middle of the hall-way, avoiding obstacles. However, we decided to also use the HM55B compass module as well.

If the right sonar detects an obstacle within a certain range, it means that the hovercraftis veering towards the right. We want it to compensate left, so we turn off the left motor.This in turn lets the right motor torque the vehicle back to the left. We did this by settingup a periodic sonar task in the RTOS that triggers the sonar, and a round robin task thatreads in the distance. There is then another periodic task, a motor task, which evaluates thesonar data and makes changes accordingly. The results of each sonar are stored in a globalarray called DUR.

1 void motor task ( ){

3 for ( ; ; ){

5 wai t t ime = m i l l i s ( ) ;i f ( wa i t t ime > l i f t w a i t )

7 d i g i t a lWr i t e (LIFT , HIGH) ;i f ( wa i t t ime > th ru s t wa i t )

9 d r iv e (THRUST, THRUST L1, THRUST L2, FORWARD, 100) ;

11 i f (DUR[ 0 ] < DELTA){

13 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , STOP, 0) ;}

15 else{

17 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , FORWARD, 75) ;}

19i f (DUR[ 1 ] < DELTA)

21 {dr ive (LEFT EN, LEFT L1 , LEFT L2 , STOP, 0) ;

23 }else

25 {dr ive (LEFT EN, LEFT L1 , LEFT L2 , FORWARD, 75) ;

27 }

29 Task Next ( ) ;}

31 }

Figure 21: Obstacle detection code

For navigation with the compass, we also set up two tasks: a compass start task anda compass read task. This is because the compass needs 40 milliseconds between the twooperations and we can not busy-wait with the RTOS. The compass read task reads in the X

26

Page 30: SENG 466: Autonomous and Remote Control Hovercraft

and Y vector components from the components and converts them to a floating point degreerepresentation of the direction. It also takes an initial reading when the program is startingup which sets the HEADING. This is the direction the hovercraft is facing at startup, andthe direction that it will try to hold.

1 void compas s s t a r t t a sk ( ){

3 for ( ; ; ){

5 cur t ime [ 0 ] = m i l l i s ( ) ;i f ( cur t ime [ 0 ] − prev t ime [ 0 ] > 250)

7 {prev t ime [ 0 ] = cur t ime [ 0 ] ;

9 HM55B StartMeasurementCommand ( ) ;}

11 Task Next ( ) ;}

13 }

15 void compass read task ( ){

17 for ( ; ; ){

19 cur t ime [ 1 ] = m i l l i s ( ) ;i f ( cur t ime [ 1 ] − prev t ime [ 1 ] > (250+40) )

21 {HM55B ReadCommand( ) ;

23 X Data = Sh i f t I n (11) ;Y Data = Sh i f t I n (11) ;

25 d i g i t a lWr i t e (EN pin , HIGH) ;double x = (double ) (X Data ) ;

27 double y = (double ) (Y Data ) ;double r e s u l t ;

29 r e s u l t = (double ) ( ( atan2 (y , x ) ∗ 180 .0 ) /M PI) ;DEGREE = r e s u l t ;

31 i f ( prev t ime [ 1 ] > 5000 && prev t ime [ 1 ] < 7000){

33 HEADING = r e s u l t ;}

35 i f (DEV){

37 S e r i a l . p r i n t l n ( r e s u l t ) ;}

39 prev t ime [ 1 ] = cur t ime [ 1 ] ;}

41 Task Next ( ) ;}

43 }

Figure 22: Compass RTOS tasks

To attempt to hold this heading, the hovercraft continuously compares the degree re-

27

Page 31: SENG 466: Autonomous and Remote Control Hovercraft

turned by the compass to the heading. It then uses information about what quadrant of theunit circle the angle resides in to determine which action to take.

1 void motor task ( ){

3 for ( ; ; ){

5 //CALC NEW DEGREES −− USING HEADING AS REFERENCEi f (DEGREE >= HEADING)

7 {DEGREE = DEGREE − HEADING;

9 }else

11 {DEGREE = (double ) (360 . 0 + DEGREE − HEADING) ;

13 }

15 //THRUST CALCSi f (DEGREE > 270 .0 | | DEGREE < 90 . 0 ) //GOOD

17 {double temp = DEGREE;

19 i f (DEGREE > 90 . 0 )temp = DEGREE − 9 0 . 0 ;

21 dr i v e (THRUST, THRUST L1, THRUST L2, FORWARD, map( ( int ) ( c e i l ( temp) ), 0 , 90 ,0 , 255) ) ; //GO FORWARD

}23

//TURNING CALCS25 i f (DEGREE > 270 .0 ) //VEERING LEFT

{27 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , FORWARD, map( ( int ) ( c e i l (DEGREE) )

,360 ,270 ,0 ,255) ) ;}

29i f (DEGREE < 90 . 0 ) //VEERING RIGHT

31 {dr ive (RIGHT EN, RIGHT L1 , RIGHT L2 , FORWARD, map( ( int ) ( c e i l (DEGREE) )

,0 , 90 ,0 , 255) ) ;33 }

}35 }

Figure 23: Autonomous motor control

28

Page 32: SENG 466: Autonomous and Remote Control Hovercraft

7 ResultsVarious measurements were taken regarding the final hovercraft designs power consumption,speed and weight. As shown in the following section, the results were within the project’sspecifications.

Relay operation and the power MOSFET drivers were initially tested using a dummyloads for correct operation. Several IRFZ40 MOSFETs were found around the lab that hadthe drain-source terminals conducting regardless of the applied gate voltage. To test thepower input to the craft we performed the following measurements under various conditions:

Figure 24: Power Consumption Measurements

As we can see from the above results, the thrusting motor running at full speed consumedthe most amount of power. At approximately 23W, it consumed 47 percent of the total sup-plied power. From the 2.1V voltage drop under the full current of 3.45A from 16.10V idleto 14.0V under full load, the internal resistance of the battery pack was determined to beapproximately 0.61 Ohms. This would suggest that as more current is drawn from the bat-tery pack, the voltage will continue to sag due to its internal resistance, leading to decreasedperformance as the power requirements increase.

The weight of the craft was measured as approximately 1372g. Adding additional weightto the craft did not increase the current draw significantly, nor decrease its measured topspeed of approximately 0.2 m/s until the total craft weight exceeded 2000g. At this point,the craft was unable to propel itself along a smooth surface, such as the linoleum in the 3rdfloor hallway of the Engineering Lab Wing.

29

Page 33: SENG 466: Autonomous and Remote Control Hovercraft

8 ConclusionIn summary, the project was deemed a success. The remote control function of the hover-craft designed by our team performed excellently; the craft was easy to control, was veryresponsive and clearly met all of the prescribed specifications with respect to power con-sumption, weight and robustness. An RTOS was selected to schedule the tasks requiredduring the automation of the vehicle. While the degree of automation was limited, the hov-ercraft was capable of following a compass bearing and avoiding collisions, albeit somewhatloosely. With further tuning, the craft would likely have been fully capable of smoothlymoving forward in a controlled manner as opposed to ”zig-zagging” down a hallway.

The most significant lesson learned throughout this project was that a great amount oftime can be saved by putting in place proper debugging processes at an early stage in de-velopment; the ability to remotely debug the hovercraft designed here proved invaluable indetermining the various bugs in our project’s software and hardware components. In addi-tion, the notion that simpler is better has become a clear design philosophy after attempts tocreate complex solutions to the various problems encountered along the way almost alwaysled to going back to a more elegant and simple conclusion.

Advice that could be offered to future students participating in a similar project wouldbe to leave several weeks before the project is due for tuning the final design, as this wasoverlooked and led to undue stress that could have easily been avoided. Nevertheless, thisproject was undeniably the most involved and rewarding challenge this team has encounteredto date.

30

Page 34: SENG 466: Autonomous and Remote Control Hovercraft

References

[1] Neil MacMillan, SENG 466 Laboratory Guide.http://nrqm.ca/mechatronics-lab-guide/

[2] Arduino Language Reference.http://arduino.cc/en/Reference/HomePage/

[3] Steven F. Barrett, Daniel J. Park,ATMEL AVR Microcontroller Primer.

[4] avr-libc Documentation.http://download.savannah.gnu.org/releases/avr-libc/

avr-libc-user-manual-1.4.7.pdf.bz2

[5] Stan Gibilisco,Teach Yourself Electricity and Electronics.

[6] 2N3904 NPN Transistor Datasheet.http://www.datasheetcatalog.com/datasheets_pdf/2/N/3/9/2N3904.shtml

[7] 7805 5V DC Regulator.http://www.electrokits.com/downloads/pdf/7805-datasheet-fairchild.pdf

[8] 833H-1C-C 5V DC Relay.http://www.datasheetdir.com/833H-1C-C+Solid-State-Relays

[9] Dally, Calabro, Fourney, Pertmer, and Zhang, Engineering Skills and Hovercraft Mis-sions.

[10] MotionInJoy PS3 Driver for Windows,http://www.motioninjoy.com 3

[11] Martin’s Liquid Lab, Martin’s 120mm Fan Static Pressure Testing,http://martinsliquidlab.i4memory.com/FanTesting.html 15

[12] Hoverhawk.com, Hoverhawk Lift Calculator,http://www.hoverhawk.com/lcalc.html 16

[13] GrumpyMike, De-coupling Tutorial,http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html 16

31

Page 35: SENG 466: Autonomous and Remote Control Hovercraft

A Base Station

A.1 Radio Transmitter

1 #include ” rad io . h”#include ”packet . h”

3 #include ” l i b \WProgram . h”

5 /∗ BASE TRANSMIT ∗/

7 u i n t 8 t base addr [RADIO ADDRESS LENGTH] = { 0xE5 , 0xE5 , 0xE5 , 0xE5 , 0xE5 } ;u i n t 8 t remote addr [RADIO ADDRESS LENGTH] = {0xE6 , 0xE6 , 0xE6 , 0xE6 , 0xE6 } ;

9r ad i opacke t t packet ;

11 volat i le u i n t 8 t r x f l a g = 0 ;

13 void r ad i o rxhand l e r ( u i n t 8 t pipenumber ){

15 //This one doesn ’ t r e c e i v e anyth ingr x f l a g = 0 ;

17 }

19 extern ”C” void c x a pu r e v i r t u a l ( ){

21 // c l i ( ) ; // d i s a b l e i n t e r r u p t sfor ( ; ; ) ; // do noth ing u n t i l hard r e s e t

23 }

25 void setup ( ){

27 s e i ( ) ;S e r i a l . begin (38400) ;

29 pinMode (13 , OUTPUT) ;Rad io In i t ( ) ;

31 Radio Configure Rx (RADIO PIPE 0 , base addr , ENABLE) ;Radio Conf igure (RADIO 2MBPS, RADIO HIGHEST POWER) ;

33 Radio Set Tx Addr ( remote addr ) ;}

35int main ( )

37 {i n i t ( ) ;

39 de lay (2000) ;setup ( ) ;

41u i n t 8 t data [ 1 8 ] ;

43for ( ; ; ) {

45 while ( S e r i a l . a v a i l a b l e ( ) < 18) ;for ( int i = 0 ; i < 18 ; i++)

47 data [ i ] = S e r i a l . read ( ) ;

49 packet . type = MESSAGE;

32

Page 36: SENG 466: Autonomous and Remote Control Hovercraft

memcpy( packet . payload . message . address , base addr , RADIO ADDRESS LENGTH) ;51 packet . payload . message . messageid = 42 ;

memcpy( packet . payload . message . messagecontent , data , 18) ;53 Radio Transmit(&packet , RADIO WAIT FOR TX) ;

55 }

57 return 0 ;}

A.2 Radio Receiver

#include ” rad io . h”2 #include ”packet . h”#include ” l i b \WProgram . h”

4/∗ BASE RECEIVE ∗/

6u i n t 8 t remote addr [ 5 ] = { 0xE6 , 0xE6 , 0xE6 , 0xE6 , 0xE6 } ;

8 u i n t 8 t base addr [ 5 ] = { 0xE4 , 0xE4 , 0xE4 , 0xE4 , 0xE4 } ;u i n t 8 t data [ 1 8 ] ;

10volat i le u i n t 8 t r x f l a g = 0 ;

12 r ad i opacke t t packet ;

14 extern ”C” void c x a pu r e v i r t u a l ( ){

16 c l i ( ) ;for ( ; ; ) ;

18 }

20 void r ad i o rxhand l e r ( u i n t 8 t pipenumber ){

22 // j u s t s e t a f l a g and t o g g l e an LED. The f l a g i s p o l l e d in the mainfunc t i on .

r x f l a g = 1 ;24 }

26 void setup ( ){

28 s e i ( ) ;S e r i a l . begin (38400) ;

30 pinMode (13 , OUTPUT) ;Rad io In i t ( ) ;

32 Radio Configure Rx (RADIO PIPE 0 , base addr , ENABLE) ;Radio Conf igure (RADIO 2MBPS, RADIO HIGHEST POWER) ;

34 Radio Set Tx Addr ( remote addr ) ;}

36int main ( )

38 {i n i t ( ) ;

40 de lay (2000) ;

33

Page 37: SENG 466: Autonomous and Remote Control Hovercraft

setup ( ) ;42

S e r i a l . p r i n t l n ( ” I n i t i a l i z i n g . . . ” ) ;44

for ( ; ; )46 {

i f ( r x f l a g )48 {

c l i ( ) ;50 i f ( Radio Receive(&packet ) != RADIO RXMORE PACKETS)

{52 // i f t h e r e are no more packe t s on the radio , c l e a r the

r e c e i v e f l a g ;// otherwise , we want to handle the next packe t on the next

loop i t e r a t i o n .54 r x f l a g = 0 ;

}56 s e i ( ) ;

58 // This s t a t i o n i s on ly e xpec t i n g to r e c e i v e MESSAGE packe t s .i f ( packet . type != MESSAGE)

60 {continue ;

62 }

64 for ( int i = 0 ; i < 18 ; i++) {S e r i a l . p r i n t ( ( char ) packet . payload . message . messagecontent [ i ] ) ;

66 }S e r i a l . p r i n t l n ( ) ;

68 S e r i a l . f l u s h ( ) ;

70 }

72 }

74 return 0 ;

76 }

B Remote Station

B.1 Radio Transceiver

#include ” rad io . h”2 #include ”packet . h”#include ” l i b \WProgram . h”

4 #include ”Wire . h”

6 /∗ REMOTE UNO ∗/

8 u i n t 8 t remote addr [ 5 ] = { 0xE6 , 0xE6 , 0xE6 , 0xE6 , 0xE6 } ;u i n t 8 t base addr [ 5 ] = { 0xE4 , 0xE4 , 0xE4 , 0xE4 , 0xE4 } ; //BASE RECV NOT BASE

TRANS

34

Page 38: SENG 466: Autonomous and Remote Control Hovercraft

10u i n t 8 t gamepad [ 1 8 ] ;

12 u i n t 8 t data [ 1 8 ] ;

14 volat i le u i n t 8 t r x f l a g = 0 ;r ad i opacke t t packet ;

16 volat i le u i n t 8 t s n r f l a g = 0 ;

18 void rece iveEvent ( int numBytes ) ;extern ”C” void c x a pu r e v i r t u a l ( ) { c l i ( ) ; for ( ; ; ) ;}

20 void r ad i o rxhand l e r ( u i n t 8 t pipenumber ) { r x f l a g = 1 ;}

22 void setup ( ){

24 s e i ( ) ;S e r i a l . begin (38400) ;

26 Wire . begin (42) ;Wire . onReceive ( rece iveEvent ) ;

28 pinMode (13 , OUTPUT) ;Rad io In i t ( ) ;

30 Radio Configure Rx (RADIO PIPE 0 , remote addr , ENABLE) ;Radio Conf igure (RADIO 2MBPS, RADIO HIGHEST POWER) ;

32 Radio Set Tx Addr ( base addr ) ;for ( int i = 0 ; i < 18 ; i++)

34 data [ i ] = 0 ;}

36void rece iveEvent ( int numBytes )

38 {int i = 0 ;

40 while (Wire . a v a i l a b l e ( ) && i < 18){

42 data [ i ] = Wire . r e c e i v e ( ) ;i++;

44 }s n r f l a g = 1 ;

46 }

48 void sendGamepadToRemote ( ){

50 Wire . send (gamepad , 1 8 ) ;}

52int main ( )

54 {i n i t ( ) ;

56 de lay (2000) ;setup ( ) ;

58for ( ; ; )

60 {

62 Wire . onRequest ( sendGamepadToRemote ) ;

35

Page 39: SENG 466: Autonomous and Remote Control Hovercraft

64 i f ( r x f l a g ){

66 c l i ( ) ;i f ( Radio Receive(&packet ) != RADIO RXMORE PACKETS)

68 {r x f l a g = 0 ;

70 }s e i ( ) ;

72for ( int i = 0 ; i < 18 ; i++)

74 gamepad [ i ] = ( int ) packet . payload . message . messagecontent [ i ] ;

76 i f ( s n r f l a g ){

78 s n r f l a g = 0 ;packet . type = MESSAGE;

80 memcpy( packet . payload . message . address , remote addr ,RADIO ADDRESS LENGTH) ;

packet . payload . message . messageid = 42 ;82 memcpy( packet . payload . message . messagecontent , data , 18) ;

Radio Transmit(&packet , RADIO WAIT FOR TX) ;84 }

86 }

88 }

90 return 0 ;

92 }

B.2 Hovercraft Control

#include ” l i b \WProgram . h”2 #include ”Dig i t a lTogg l e . h”#include ”Wire . h”

4void setup ( ) ;

6 void po l l ( ) ;void dr ive ( int en , int l1 , int l2 , int dir , int power ) ;

8 int Map( int va l ) ;

10 #define FORWARD 1#define BACKWARD 0

12 #define STOP −1

14 #define TRIG1 22#define ECHO1 23

16#define TRIG2 24

18 #define ECHO2 25

20 #define TRIANGLE 0

36

Page 40: SENG 466: Autonomous and Remote Control Hovercraft

#define CIRCLE 122 #define CROSS 2

#define SQUARE 324 #define LONE 4

#define RONE 526 #define LTWO 6

#define RTWO 728 #define SELECT 10

30 const int THRUST = 13 ;const int LIFT = 12 ;

32 const int RELAY = 11 ;const int THRUST L1 = 8 ;

34 const int THRUST L2 = 9 ;const int LEFT EN = 7 ;

36 const int LEFT L1 = 6 ;const int LEFT L2 = 5 ;

38 const int RIGHT EN = 4 ;const int RIGHT L1 = 2 ;

40 const int RIGHT L2 = 3 ;

42 int but [ 1 8 ] ;char bu f f e r [ 1 8 ] ;

44unsigned long cur = 0 ;

46 unsigned long pre = 0 ;long i n t e r v a l = 2000 ;

48int main ( )

50 {i n i t ( ) ;

52 setup ( ) ;

54 unsigned long cur = 0 ;unsigned long pre = 0 ;

56 unsigned long i n t e r v a l = 500 ; // 0.5 seconds in microsbool sonar = f a l s e ;

58bool LIFTED = f a l s e ;

60int dur ;

62for ( ; ; )

64 {

66 p o l l ( ) ;

68 cur = m i l l i s ( ) ;i f ( cur − pre > i n t e r v a l )

70 {pre = cur ;

72memset(&bu f f e r [ 0 ] , 0 , s izeof ( bu f f e r ) ) ;

74

37

Page 41: SENG 466: Autonomous and Remote Control Hovercraft

i f ( sonar == true )76 {

d i g i t a lWr i t e (TRIG1 , HIGH) ;78 de layMicroseconds (11) ;

d i g i t a lWr i t e (TRIG1 , LOW) ;80 dur = pu l s e In (ECHO1, HIGH) ;

s p r i n t f ( bu f f e r , ”R: %d” , dur ) ;82 sonar = f a l s e ;

S e r i a l . p r i n t l n ( dur ) ;84 }

else86 {

d i g i t a lWr i t e (TRIG2 , HIGH) ;88 de layMicroseconds (11) ;

d i g i t a lWr i t e (TRIG2 , LOW) ;90 dur = pu l s e In (ECHO2, HIGH) ;

s p r i n t f ( bu f f e r , ”L : %d” , dur ) ;92 sonar = true ;

S e r i a l . p r i n t l n ( dur ) ;94 }

96

98 Wire . beg inTransmiss ion (42) ;Wire . send ( bu f f e r ) ;

100 Wire . endTransmission ( ) ;

102 }

104//THRUST

106 i f ( but [CROSS] == 1){

108 dr iv e (THRUST, THRUST L1, THRUST L2, FORWARD, 100) ;}

110 else i f ( but [CIRCLE] == 1){

112 dr iv e (THRUST, THRUST L1, THRUST L2, BACKWARD, 100) ;}

114 else{

116 dr iv e (THRUST, THRUST L1, THRUST L2, STOP, 0) ;}

118//LEFT

120 i f ( but [LONE] == 1){

122 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , FORWARD, 90) ;}

124 else i f ( but [LTWO] == 1){

126 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , BACKWARD, 90) ;}

128 else i f ( but [LONE] == 0 | | but [LTWO] == 0)

38

Page 42: SENG 466: Autonomous and Remote Control Hovercraft

{130 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , STOP, 0) ;

}132

//RIGHT134 i f ( but [RONE] == 1)

{136 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , FORWARD, 90) ;

}138 else i f ( but [RTWO] == 1)

{140 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , BACKWARD, 90) ;

}142 else i f ( but [RONE] == 0 | | but [RTWO] == 0)

{144 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , STOP, 0) ;

}146

148 //LIFTi f ( but [SQUARE] == 1)

150 {i f (LIFTED == true )

152 {d i g i t a lWr i t e (LIFT , LOW) ;

154 LIFTED = f a l s e ;}

156 else{

158 d i g i t a lWr i t e (LIFT , HIGH) ;LIFTED = true ;

160 }}

162//RELAY

164 i f ( but [SELECT] == 1){

166 d i g i t a lTogg l e (RELAY) ;}

168}

170}

172void po l l ( )

174 {int i = 0 ;

176 Wire . requestFrom (42 ,18) ;while (Wire . a v a i l a b l e ( ) && i < 18)

178 {but [ i ] = Wire . r e c e i v e ( ) ;

180 i++;}

182 }

39

Page 43: SENG 466: Autonomous and Remote Control Hovercraft

184 void setup ( ){

186 S e r i a l . begin (38400) ;Wire . begin ( ) ;

188pinMode (TRIG1 , OUTPUT) ;

190 pinMode (ECHO1, INPUT) ;

192 pinMode (TRIG2 , OUTPUT) ;pinMode (ECHO2, INPUT) ;

194pinMode (THRUST, OUTPUT) ;

196 pinMode (LIFT , OUTPUT) ;pinMode (RELAY, OUTPUT) ;

198 pinMode (THRUST L1, OUTPUT) ;pinMode (THRUST L2, OUTPUT) ;

200 pinMode (LEFT EN, OUTPUT) ;pinMode (LEFT L1 , OUTPUT) ;

202 pinMode (LEFT L2 , OUTPUT) ;pinMode (RIGHT EN, OUTPUT) ;

204 pinMode (RIGHT L1 , OUTPUT) ;pinMode (RIGHT L2 , OUTPUT) ;

206d i g i t a lWr i t e (LIFT , LOW) ;

208 d i g i t a lWr i t e (RELAY, LOW) ;analogWrite (THRUST, 0) ;

210 analogWrite (LEFT EN, 0) ;analogWrite (RIGHT EN, 0) ;

212TCCR3B |= BV(CS30) ;

214 TCCR3B &= ˜ BV(CS31) ;TCCR3B &= ˜ BV(CS32) ;

216for ( int i = 0 ; i < 18 ; i++)

218 but [ i ] = 0 ;

220 }

222 int Map( int va l ){

224 return map( val , 0 , 100 , 0 , 255) ;}

226void dr ive ( int en , int l1 , int l2 , int dir , int power )

228 {i f ( d i r == FORWARD)

230 {analogWrite ( en , Map( power ) ) ;

232 d i g i t a lWr i t e ( l1 , LOW) ;d i g i t a lWr i t e ( l2 , HIGH) ;

234 }else i f ( d i r == BACKWARD)

236 {

40

Page 44: SENG 466: Autonomous and Remote Control Hovercraft

analogWrite ( en , Map( power ) ) ;238 d i g i t a lWr i t e ( l1 , HIGH) ;

d i g i t a lWr i t e ( l2 , LOW) ;240 }

else i f ( d i r == STOP)242 {

analogWrite ( en , 0) ;244 d i g i t a lWr i t e ( l1 , LOW) ;

d i g i t a lWr i t e ( l2 , LOW) ;246 }

}248

extern ”C” void c x a pu r e v i r t u a l ( )250 {

// c l i ( ) ; // d i s a b l e i n t e r r u p t s252 for ( ; ; ) ; // do noth ing u n t i l hard r e s e t

}

B.3 Autonomous Control

1 #include ” os . h”#include ”common . h”

3 #include ” l i b /WProgram . h”#include <avr / i o . h>

5 #include <avr / i n t e r r up t . h>#include <u t i l / de lay . h>

7 #include <s t d i o . h>#include ”Wire . h”

9 #include ”math . h”#include ”compass . h”

11#define DEV 1

13#define T SONAR 1

15 #define TMOTOR 2#define T COMPASS START 3

17 #define T COMPASS READ 4#define T READ 5

19 #define T PRINT 6

21 #define FORWARD 1#define BACKWARD 0

23 #define STOP −1

25 double TOL = 2 . 0 ;

27 #define NUMSONARS 2

29 extern ”C” void c x a pu r e v i r t u a l ( ) { c l i ( ) ; for ( ; ; ) ;}

31 void setup ( ) ;void dr ive ( int en , int l1 , int l2 , int dir , int power ) ;

33 int Map( int va l ) ;

41

Page 45: SENG 466: Autonomous and Remote Control Hovercraft

35 const unsigned char PPP [ ] = { T SONAR, 25 , T SONAR, 25 , TMOTOR, 10 } ;const unsigned int PT = s izeof (PPP) /2 ;

37const int THRUST = 13 ;

39 const int LIFT = 12 ;const int RELAY = 11 ;

41 const int THRUST L1 = 8 ;const int THRUST L2 = 9 ;

43 const int LEFT EN = 7 ;const int LEFT L1 = 6 ;

45 const int LEFT L2 = 5 ;const int RIGHT EN = 4 ;

47 const int RIGHT L1 = 2 ;const int RIGHT L2 = 3 ;

49int TRIG [ ] = {22 , 24} ;

51 int ECHO[ ] = {23 , 25} ;

53 unsigned long DUR[ ] = {0 , 0} ;

55 long cur r ent t ime = 0 ;long prev ious t ime = 0 ;

57 long cur t ime [ ] = {0 , 0} ;long prev t ime [ ] = {0 , 0} ;

59 long i n t e r v a l = 200 ;

61 long wait t ime = 0 ;long l i f t w a i t = 250 ;

63 long th ru s t wa i t = 1000 ;

65

67 EVENT∗ snrInEvent ;

69 void s ona r ta sk ( ){

71 for ( ; ; ){

73 for ( int i = 0 ; i < NUMSONARS; i++){

75 cur r en t t ime = m i l l i s ( ) ;i f ( cu r r en t t ime − prev ious t ime > i n t e r v a l )

77 {prev ious t ime = cur r ent t ime ;

79 d i g i t a lWr i t e (TRIG[ i ] , HIGH) ;de layMicroseconds (11) ;

81 d i g i t a lWr i t e (TRIG[ i ] , LOW) ;} ;

83 Task Next ( ) ;}

85 }}

87

42

Page 46: SENG 466: Autonomous and Remote Control Hovercraft

void compas s s t a r t t a sk ( )89 {

for ( ; ; )91 {

cur t ime [ 0 ] = m i l l i s ( ) ;93 i f ( cur t ime [ 0 ] − prev t ime [ 0 ] > 250)

{95 prev t ime [ 0 ] = cur t ime [ 0 ] ;

HM55B StartMeasurementCommand ( ) ;97 }

Task Next ( ) ;99 }}

101void compass read task ( )

103 {for ( ; ; )

105 {cur t ime [ 1 ] = m i l l i s ( ) ;

107 i f ( cur t ime [ 1 ] − prev t ime [ 1 ] > (250+40) ){

109 HM55B ReadCommand( ) ;X Data = Sh i f t I n (11) ;

111 Y Data = Sh i f t I n (11) ;d i g i t a lWr i t e (EN pin , HIGH) ;

113 double x = (double ) (X Data ) ;double y = (double ) (Y Data ) ;

115 double r e s u l t ;r e s u l t = (double ) ( ( atan2 (y , x ) ∗ 180 .0 ) /M PI) ;

117 DEGREE = r e s u l t ;i f ( prev t ime [ 1 ] > 5000 && prev t ime [ 1 ] < 7000)

119 {HEADING = r e s u l t ;

121 }i f (DEV)

123 {S e r i a l . p r i n t l n ( r e s u l t ) ;

125 }prev t ime [ 1 ] = cur t ime [ 1 ] ;

127 }Task Next ( ) ;

129 }}

131void r ead ta sk ( )

133 {for ( ; ; )

135 {for ( int i = 0 ; i < NUMSONARS; i++)

137 {DUR[ i ] = pu l s e In (ECHO[ i ] , HIGH) ;

139 Event Broadcast ( snrInEvent ) ;Task Next ( ) ;

141 }

43

Page 47: SENG 466: Autonomous and Remote Control Hovercraft

}143 }

145 void p r i n t t a s k ( ){

147 for ( ; ; ){

149 for ( int i = 0 ; i < NUMSONARS; i++){

151 Event Wait ( snrInEvent ) ;i f (DEV)

153 S e r i a l . p r i n t l n (DUR[ i ] ) ;Task Next ( ) ;

155 }}

157 }

159 void motor task ( ){

161 for ( ; ; ){

163 wai t t ime = m i l l i s ( ) ;i f ( wa i t t ime > 7000+ l i f t w a i t )

165 d i g i t a lWr i t e (LIFT , HIGH) ;i f ( wa i t t ime > 7000+ th ru s t wa i t )

167 {

169 //CALC NEW DEGREES −− USING HEADING AS REFERENCEi f (DEGREE >= HEADING)

171 {DEGREE = DEGREE − HEADING;

173 }else

175 {DEGREE = (double ) (360 . 0 + DEGREE − HEADING) ;

177 }

179 //THRUST CALCSi f (DEGREE > 270 .0 | | DEGREE < 90 . 0 ) //GOOD

181 {double temp = DEGREE;

183 i f (DEGREE > 90 . 0 )temp = DEGREE − 9 0 . 0 ;

185 dr iv e (THRUST, THRUST L1, THRUST L2, FORWARD, map( ( int ) ( c e i l ( temp) ), 0 , 90 ,0 , 255) ) ; //GO FORWARD

}187

//TURNING CALCS189 i f (DEGREE > 270 .0 ) //VEERING LEFT

{191 dr iv e (LEFT EN, LEFT L1 , LEFT L2 , FORWARD, map( ( int ) ( c e i l (DEGREE) )

,360 ,270 ,0 ,255) ) ;}

193

44

Page 48: SENG 466: Autonomous and Remote Control Hovercraft

i f (DEGREE < 90 . 0 ) //VEERING RIGHT195 {

dr ive (RIGHT EN, RIGHT L1 , RIGHT L2 , FORWARD, map( ( int ) ( c e i l (DEGREE) ),0 , 90 ,0 , 255) ) ;

197 }

199 i f (DUR[ 0 ] < 3000){

201 dr iv e (RIGHT EN, RIGHT L1 , RIGHT L2 , STOP, 0) ;}

203i f (DUR[ 1 ] < 3000)

205 {dr ive (LEFT EN, LEFT L1 , LEFT L2 , STOP, 0) ;

207 }

209}

211 Task Next ( ) ;}

213 }

215 void r main ( ){

217 i n i t ( ) ;setup ( ) ;

219 snrInEvent = Event In i t ( ) ;Task Create ( sonar task , 0 , PERIODIC, T SONAR) ;

221 Task Create ( motor task , 0 , PERIODIC, TMOTOR) ;Task Create ( compass s ta r t ta sk , 0 , RR, T COMPASS START) ;

223 Task Create ( compass read task , 0 , RR, T COMPASS READ) ;Task Create ( read task , 0 , RR, T READ) ;

225 Task Create ( p r i n t t a sk , 0 , RR, T PRINT) ;}

227void setup ( )

229 {i f (DEV)

231 {S e r i a l . begin (38400) ;

233 Wire . begin ( ) ;}

235 pinMode (LIFT , OUTPUT) ;

237 pinMode (THRUST, OUTPUT) ;pinMode (THRUST L1, OUTPUT) ;

239 pinMode (THRUST L2, OUTPUT) ;

241 pinMode (LEFT EN, OUTPUT) ;pinMode (LEFT L1 , OUTPUT) ;

243 pinMode (LEFT L2 , OUTPUT) ;

245 pinMode (RIGHT EN, OUTPUT) ;pinMode (RIGHT L1 , OUTPUT) ;

45

Page 49: SENG 466: Autonomous and Remote Control Hovercraft

247 pinMode (RIGHT L2 , OUTPUT) ;

249 pinMode (EN pin , OUTPUT) ;pinMode (CLK pin , OUTPUT) ;

251 pinMode (DIO pin , INPUT) ;

253 HM55B Reset ( ) ;

255 for ( int i = 0 ; i < NUMSONARS; i++){

257 pinMode (TRIG[ i ] , OUTPUT) ;pinMode (ECHO[ i ] , INPUT) ;

259 }

261

263 }

265 int Map( int va l ){

267 return map( val , 0 , 100 , 0 , 255) ;}

269void dr ive ( int en , int l1 , int l2 , int dir , int power )

271 {i f ( d i r == FORWARD)

273 {analogWrite ( en , Map( power ) ) ;

275 d i g i t a lWr i t e ( l1 , HIGH) ;d i g i t a lWr i t e ( l2 , LOW) ;

277 }else i f ( d i r == BACKWARD)

279 {analogWrite ( en , Map( power ) ) ;

281 d i g i t a lWr i t e ( l1 , LOW) ;d i g i t a lWr i t e ( l2 , HIGH) ;

283 }else i f ( d i r == STOP)

285 {analogWrite ( en , 0) ;

287 d i g i t a lWr i t e ( l1 , LOW) ;d i g i t a lWr i t e ( l2 , LOW) ;

289 }}

46