Sheila Balu
Flight Simulator


This flight simulator is designed to resemble a pilot's view using computer-generated graphics. Building one is much cheaper than flying a true airplane due to a lack of fuel and maintenance costs, and flight is not constrained by weather, mechanical failures, or other environmental restrictions. Most importantly, it does not involve risk to property or lives, unlike the high risk involved with true flight.

High-Level Design

Description of architecture

At a high level, the PIC32 microcontroller is used to handle input and output to and from the cockpit controls. These controls include a control column (controlling pitch and roll) driven with an inertial measurement unit, rudder pedals using a potentiometer (controlling yaw), flap increase and decrease buttons, a landing gear switch, a throttle from a slide potentiometer, a kill switch, a pause button, and differential brake button. This is summarized in Table 2 under the hardware section. This information is communicated in real-time to a computer using a serial connection through a cable. A Python program on the computer sets up the serial communication port and reads this data. The graphics for the flight simulator are provided by the Google Earth API, which provides a simple flight simulator. This simulator is flown using several keyboard and mouse functions normally; the Python program will control the mouse and keyboard of the computer as a user usually would on a desktop. This is done using the Python Package PyAutoGUI. The high level design is described below in Figure 1 below.

Figure 1: High-level block diagram of flight simulator.

The project meets all IEEE standards. Although a human will be directly stimulating the elements of the flight simulator, it is safe. No electronics will be in contact with a human at any time, and all wires are organized and insulated. This project was designed for the average healthy adult with a full range of motion and decent eyesight. The software trademarks in this project are described further in the software section below.

Hardware Design

How the project was built

The hardware used in this project is summarized in the table below.

Apart from this, the only other hardware used was the regulator circuit going to the potentiometer. This circuit is described in the schematic outlined in the appendix. Links to all of the hardware used is also available in the appendix.

The rudder pedals, control column, and control board were all made from cardboard. I wanted this project to be as cheap to replicate as possible. I cut the cardboard into parts, cut holes into them to fit the electronics, and mounted the electrical components. The cardboard parts were assembled with hot glue. The control column also used elastic bands to create a spring-loading effect where it would provide resistance when moved from the center position.

Figure 3. Cardboard control column. 

Figure 4. Cardboard rudder pedals, outside and inside. 

Figure 5. Cardboard control board, front and back. 

Software Design

the code behind it all

PIC32: MPLAB X IDE v3.05 was used to code the PIC32 in the C language. It can be downloaded for free online.

The code begins with including config.h, to configure the clock and protoThreads. I then include the graphics libraries and the i2c helper file, which was used from a previous project (linked is in appendix). I enable pull-up macros for ports A and B. I then declare a number of integers that work as state variables, holding the values that are output to the computer. Details are outlined in comments.

The first of two threads is the one second counter, protothread_time. This is not important to the flight simulator, and can be omitted. I used this function to troubleshoot by offering a template to print to the TFT. I yield for 1 second and then use the TFT functions to write the system time, increasing the sys_time_seconds counter each time the thread is run.

The second thread, protothread_serial, performs the bulk of the computation and input-output handling. It reads the status of the flap up, flap down, kill switch, pause button, landing gear, brake left, and brake right buttons. It also uses two channels of the analog-to-digital converter to read the status of the two potentiometers. Next, I read the IMU values using a function defined in the header file i2c_helper.h. A link to this project is provided in the appendix. I modified this header file to send six pieces of data: the x, y, and z values of the gyroscope, and the x, y, and z values of the accelerometer. These values are parsed and then the tilt is calculated using trigonometry. I then average the values over five cycles, and the averaged values are stored in x_avg and y_avg. This simple filter helps to stabilize any spikes in the data, as the accelerometer is not always accurate. Finally, I send all this data through the serial buffer to the computer, separated by spaces. In total, there are 12 parameters being sent serially.

A few helper functions were defined to aid in the set up. The first was my_adc_setup(). This is where the channels of the analog-to-digital converters are set, opened and enabled. The next is my_tft_setup(), which initializes the display. Again, this is unnecessary for the flight simulator, but useful for debugging. The third is my_button_setup(), which initializes each of the buttons and switches, enabling the pull downs and setting the pins to inputs.  The fourth is my_imu_setup(), which opens the I2C channel, takes the IMU out of sleep mode, sets the gyro sensitivity, and calibrates the gyroscope.

In the main(void), I set up protoThreads, set up system-wide interrupts, initialize the threads, call the helper functions mentioned above, and finally, schedule the threads.

The i2c_helper.h header file is from the Self-Balancing Robot project. i2c_write() writes data to a specific register in the slave IMU. i2c_read() reads back data from a specific register. readImuValues() is a helper function that reads back all three axes of both the gyroscope and accelerometer sensors. calibrateGyros() is a function that, when powered on and and the robot is lying still, takes 1000 measurements of the gyroscope to estimate its bias.

Python: Python 3.7 (64 bit) was used, and it is available for download for free online. The pyserial library was used for serial communication. The Python module PyAutoGUI 0.9.38 was also used to control the keyboard. The code is open-sourced and free to edit and download on GitHub, and can be installed using the Python Package Index. It was written by Al Sweigart and has a BSD license. Links are available in the appendix.


First, we import modules for serial communication, keyboard/mouse control, and to use the universal newline mode, and time for delays. We declare the variables that hold the state of the various inputs and outputs. While the kill switch has not been asserted, we read the line of data and parse it by splitting it at each space in the string. For the flaps, we check to see if the value of the button received is different from the previous value, and if so, we write the data using shortcuts for the flight simulator using the PyAutoGUI module. The same works for the kill switch and pause button. With the left and right brakes, I incorporate some delay by pressing and releasing the keys separately. The throttle includes some delay, and only presses it if the difference between the previous throttle and the current throttle values were significantly different to avoid jitter. There are 10 values that the throttle can support. The IMU data is capped by the boundary conditions, scaled, and moved. This only samples every 8 cycles to again avoid jitter. For the rudder, it also samples once every 8 cycles. The data is scaled to one of 25 allowed values. The buttons are pressed (in hotkey format) and released a number of times proportional to the difference in rudder potentiometer values.

Simulation: Google Earth Pro, the desktop version of Google Earth, will be used. It is available for download for free online. Its use is acceptable under principles of fair use, but not for commercial use.

To enter, select Tools -> Enter Flight Simulator. Select the aircraft that you want to fly and the airport you want to fly out of. Press enter, ensure that the Python and microcontrollers are engaged, and you are ready to fly!



The flight simulator was very successful. It was able to incorporate 12 different external parameters to make up a comprehensive flight simulator. The mechanical components were sturdily built and were comfortable to fly. I was able to incorporate a calibrating feature as well to make it more accurate. However, there is definitely a delay. I was able to calibrate the delay such that the movements would overcompensate for the delay and downsampling, making it similar to true aircraft dynamics. I ended up sampling the rudder and control column once every eight cycles, enough for the average human. I tested the flight simulator using different aircraft to ensure that the aircraft dynamics worked well. Safety was enforced by ensuring that no loose wires were left. The product was fun, simple to use, and cheap to make.



What did I learn?

The results definitely met my expectations, and I had a great time developing the flight simulator. If I were to do the project again, I would clean up the wiring and make it all neater, and make the program more responsive. The design conformed to IEEE and other standards. I believe that the project is consistent with the Code of Ethics.  

In terms of intellectual property, I used several modules that were public domain. For example, I had to download pyAutoGUI and pySerial, for which the source code is available online.  Google Earth is also available for download for free online. As well, I used a modified i2c helper header that was written before, and is linked to below.


Appendix A (Permissions)

I approve this report for inclusion on the course website.

I approve the video for inclusion on the course YouTube channel.

Appendix B (Commented Code)

PIC32 Code

PIC32 Code

Python Code

Python Code

i2c helper (modified from ECE 4760 Self-Balancing Robot

Python Code

Appendix C (Schematic)

Appendix D (Budget)

TOTAL: $65.42 USD

Appendix E (References)

MPU 6050 Description

MPU 6050 Datasheet

MPU 6050 Register Maps and Descriptions

PIC32 Microcontroller


Serial Using UART

Self Balancing Robot

Google Earth Download

Appendix F (Vendors)

Appendix G (Python Modules)

About Me

About the Project Designer

Sheila Balu

My name is Sheila, and I'm a junior studying Electrical and Computer Engineering at Cornell University. I've been flying since I was 16 years old, but my passion for aviation has existed long before I became a licensed pilot. I've interned/ externed at companies including the Boeing Company and Moog Inc, and was named an AIAA Diversity Scholar by Airbus at Aviation 2018. I will be interning as an aeronautical engineer at Lockheed Martin's Advanced Development Programs (the Skunk Works) in summer 2019.


Have questions? I'd be happy to answer them!