Auto-hovering Helicopter

Base Station

For our project, we elected to use an MPC823-based (PowerPC) development kit, a Xilinx FPGA development kit, and a custom expansion board. We chose this setup mainly because we had become familiar with it after using it in lab. We were thinking about using a much smaller board that could fit on the actual helicopter, but we eventually decided against it because the helicopter we used couldn't support much weight.

Helicopter

We chose a Spider-Man 3 BladeRunner Indoor RC Rescue Helicopter as the base platform for our helicopter. We chose this product because it was available at local Radio Shacks at a low cost and because the design was already inherently stable. Ironically, this product was discontinued during the time we were working on the project.

The remote interface for this helicopter consisted of a two-channel remote control allowing for the adjustment of throttle and yaw. In order to control the helicopter, it was necessary to interface these channels to the National Semiconductor ADC0808 on the MPC823 kit and use the digital to analog conversion to adjust the controls.

Altitude Sensor

A Devantech SRF05 Ultrasonic Distance Sensor was used to detect the helicopter's height. It was affixed to the helicopter's landing gear pointing down using a small piece of cardboard and some hot glue from a glue gun. The interface was implemented exclusively in the FPGA using Verilog. This Verilog module was also connected to the PowerPC bus. A trigger pulse was generated every 50ms and sent to the sensor. The Verilog module would then count how long the response pulse from the distance sensor lasted and store this value to a register. The register could then be accessed via the PowerPC bus using a simple load instruction.

Rotation Sensor

An InvenSense IDG-300 Integrated Dual-Axis Gyroscope was used to detect rotation of the helicopter. The sensor represented rotational velocity by outputting an analog voltage. Thus, it was necessary to interface this sensor to the National Semiconductor ADC0808 on the MPC823 kit.

Nintendo Controller

A Nintendo controller was interfaced to the expansion board. The button descriptions are given in the following tables below:

Automatic ModeManual Mode
ButtonFunctionality
UPIncrease desired altitude by 100 (Min: 5000 Max: 100,000)
DOWNDecrease desired altitude by 100 (Min: 5000 Max: 100,000)
LEFTNo effect
RIGHTNo effect
SelectChange mode to Manual
StartStarts the automated control system. Helicopter will attempt to hover steadily at the user specified desired altitude
AIf Simulation data has been logged, LCD will display a simulation of the last helicopter flight
BEmergency Stop, helicopter enters “land safely mode” by slowing blades until safely on the ground and then cuts the engines
ButtonFunctionality
UPIncrease throttle by 1 (Min: 0 Max: 255)
DOWNDecrease throttle by 1 (Min:0 Max: 255)
LEFTIncrease Yaw control by 1 (Min : 0 Max:255 Center: 127) (Bias helicopter toward left turn)
RIGHTDecrease Yaw control by 1 (Min : 0 Max:255 Center: 127) (Bias helicopter toward right turn)
SelectChange mode to Automatic
StartNo effect
AIf Simulation data has been logged, LCD will display a simulation of the last helicopter flight
BEmergency Stop, helicopter enters “land safely mode” by slowing blades until safely on the ground and then cuts the engines

The NES controller was a fairly simple device to interface with.  To read the status of the buttons, a latch signal must be applied to the controller for 120us. Then, eight 60us pulses must be asserted to the controller’s “pulse” input line. During each of these pulses, the controller will send back the status of one of its eight buttons in the following order:  A, B, Select, Start, Up, Down, Left, Right.

We wrote a controller in Verilog which contained a counter that incremented every clock cycle. At the start of the count, the controller would assert the Latch signal to the controller until the counter reached a value associated with 120us. The controller would then assert the pulse signal 8 times, again based on the value of the counter. At the appropriate times, the controller would latch the data coming back from the controller into its own data register.

When a user requests a read from the NES controller, the module simply returns the value currently latched in its data register. This is a zero wait state transaction. The controller module is always reading the value of the NES controller asynchronous of the user read requests.

Numeric Keypad

The Nintendo controller was somewhat cumbersome for the purposes of entering values. Instead, a numeric keypad was interfaced on the expansion board.

The keypad acts as a physical connector between two wires. By asserting a voltage on an input line and measuring the voltage on the appropriate output line, one can tell whether a particular button was pushed. If it was pushed, the electrical connection would be completed and the same voltage would be asserted on the output line. If the button was not pushed, no voltage would be detected on the output line.

We designed a controller module in Verilog that continually read the status of the keypad. We used a counter that incremented every clock cycle to provide the appropriate timing s on the signals to the device. The module asserts a logical 1 (5 volts) to one of the four row ports on the device. At this same time, the module reads the output from all of the column lines coming from the device. The values of these column signals tell us what buttons in this particular row are pushed. This information is then latched into a data register.

When a user requests a read from the keypad, the module simply returns the value currently latched in its data register. This is a zero wait state transaction. The controller module is always reading the value of the keypad asynchronous of the user read requests.

Our hardware was receiving false positives from the device so we used 1k Ohm resistors to ground each of the column outputs. This solved the problem.

LCD Display

In order to know the current state of the helicopter, an Optrex DMF 5005 LCD was interfaced to the expansion board. Information such as altitude and current rotation was visible on the screen, as well as a small graphic of the helicopter which can be seen in the upper-right corner of this webpage.

The Optrex DMF 5005 graphics LCD required an 8bit bi-directional data bus on top of various other control signals. The only ports on the expansion board which allow bi-directional transfers are ports 0 through 7. These ports are also shared with the ADC and DAC so we had to carefully tristate all the devices that were hooked into this bus. Each tristate would only let data flow into the bus from a particular device depending on which I/O device was being accessed.

We designed a controller in Verilog that handled all transaction requests to the LCD. We followed the MPC823 bus timing diagram that was written by a prior student to make sure we were asserting signals with appropriate setup and hold times.

The Optrex DMF 5005 has two different types of write transactions: a data write and a command write. These are differentiated by the C/D signal sent to the actual LCD. We decided to bind each of these transactions to a different memory mapped I/O location. Data write was mapped to address 0x03000000 and a command write was mapped to address 0x03000004. Our controller module would assert the appropriate C/D signal to the LCD based on the address given in the bus transaction.