View on GitHub

Vintage 2D Plane Wars

Pingchuan Ma (pm555) & Jiajun Sun (js2969)

start.jpg Introduction

There was a very popular game named "Plane Wars", a more popular version is the 1945 Air Force. The game was very simple and entertaining. You are operating an aircraft to dodge the planes flying towards you and you can also shoot them to eliminate them. The one we are to accomplish is a more vintage and 2D version of the old game. The plane can only move along one axis and shoot the planes.

System Diagram

start.jpg

System Overview

We only took advantage of the FRDM-KL64z board's functions. A program in C is uploaded into the board so that the board is capable of sending touch sensor and button press information form the COM port to other systems. The information is sent to a python program, received by using the Pyserial Library, which is used for controlling the movement along x-axis of our own plane. In order to distinguish difference control methods, buttons are used for faster moves (in case of the emergency, or to say a enemy is approaching!); the touch sensor is used for more accurate moves, in order to aim for the enemies. At last, the python GUI is drawn using Pygame.

Project Video Demo

Detailed Technical Description

Touch Slider

We use the touch slider function of the FRDM-KL64z board to control the slow movement of the plane. KL46 Sub-Family has the TSI (Touch Sensing Input) module, which provides capacitive touch sensing detection with high sensitivity and enhanced robustness to help us deal with the finger touch control. There are several TSI pins measuring the external electrode capacitance by current source scans, which charge and discharge the electrode once or several times. And the result of scan time would be stored in a 16-bit register (TSI DATA Register). The electrode capacitance is proportional to the scan time just measured, so we can use this value to know how large the current capacitance of the electrodes are. When the finger doesn't touch the slider, the scan time is tested to be roughly around 520, which is the minimum time corresponding to the minimum capacitance. When the finger touches the slider, the value will grow. Hence, we set an offset of 540, and let the result be subtracted by the offset. Then since we set the datatype as uint_16, any value below the threshold will appear as above 60000, and we can eliminate them when dealing with the input data. And after adding this offset, we found that when touching the left part of the slider, the output value is generally under 500, and the right part of the slider is the opposite (above 500). Therefore, we can set 500 as the boundary to distinguish between whether users touch the left part or right part of the slider, then decide which direction we should move the plane.

Button Control

And we use the two buttons SW1 and SW3 to control the dash (quick movement) of the plane. The corresponding pins of SW1 and SW3 are portC-12 and portC-3. SW3 is for dashing left and SW1 is for dashing right. Once either one of these two buttons is pressed, the register (PTC->PDIR) will have 1 at the corresponding bit (bit 12 for SW1, bit 3 for SW3). Then we can use this value to know whether the button is pressed and control the dash of the plane.

UART Communication

We use UART communication functions to let the board communicate with our computer. We Initialize the UART for TX (115200, 8N1). And we send a string with “\n” at the end once a time and use the function “readline” in the module pyserial in python to decode. For the touch slider, we only send the value under 60000, and for the button control, we send “1\n” for SW1 and “-1\n” for SW3. And when nothing happens, we send “-2\n”, which is not included in any situation mentioned above. We set a short delay after each while loop, to avoid too much string stacked in the buffer.

PyGame GUI

At last, for the PyGame GUI part, we found some interesting drawing online such as the plane, the bullets, and the background. The GUI refreshed every 0.05s to have the animation effect. The enemies are randomly generated from the top, with higher and higher speed. The bullets are shoot every 1s starting from the from x-axis position as the current plane position. The collision functions in PyGame are used for detecting whether the bullets hit the enemies. whether the enemies destroys your own plane. In order to save the memory, when an object is detected to be out of the screen, the object would be deleted.

Additional Resources Used

For UART communication, we made use of the files provided by the instructor, and made small modifications to make it fit in with our program. We also use the two reference files as KL46 Sub-Family Reference Manual and FRDM-KL46Z User's Manual (FRDM-KL46Z-UM, rev. 2) to know the basic function and implementation of used modules. Also, we refer to the description and methods posted here https://forum.digikey.com/t/using-the-capacitive-touch-sensor-on-the-frdm-kl46z/13246 to get a better understanding of the TSI module.

For PyGame GUI, the images are downloaded from https://findicons.com.

Testing scheme

We first tested the functionality of the button SW1 and SW3 by using the in-built serial terminal in MCUXpresso IDE. And at the very first scene, we successfully saw the smooth outputs of either “1” or “-1” appearing at the terminal. And finally, we wrote a simple program by pygame and pyserial, and used the two buttons to control one rectangle quickly moving left and right, and the performance was smooth and good.

And secondly, we also used the in-built serial terminal in MCUXpresso IDE to test the functionality of the touch slider. In order to choose the subtle value of the data offset we tried various values like 520, 530, 540, 550, to see the data result output. And finally we chose 540 as the offset, which is not too high to eliminate the normal touching cases and enough to eliminate the no-touch case. And also, we noticed that, when pressing the button of SW1 and SW3, the finger may occasionally rub the slider's surface slightly. And the offset 540 can also well eliminate this case as well. Then to determine the boundary between the left and the right part, we sampled 100 data points when using one finger to touch the left part of the touch slider and took the average of it, which is 314.7. Also, we did the same thing for the right part of the touch slider, which is 734.2. Hence, we decided to use 500 as the boundary. And finally, we wrote a simple program by pygame and pyserial, and used the touch slider to control one rectangle moving left and right, and the performance was smooth and good.

Finally, we connected the C-part and the pygame part together to test the functionality. And we found that the frame rate of the pygame part should be adaptive to the signal transmission rate by the board. If the signal transmission rate is too high, then a lot of characters the board transmitted can't be implemented as the plane's behavior in time, leading to the lagging problem. And if the signal transmission rate is too low, then the pygame part needs to wait until the signal is received to turn to the next frame, resulting in the freezing problem. Hence, we carefully tried multiple pairs of the frame rate and the delay time between each data reading in the C part. And finally we chose 10ms and 29000 loops as the frame rate and the delay time respectively, which performs relatively the best among all pairs we chose.

Work Distribution

Pingchuan implemented the C part and Jiajun implemented the pygame GUI part. And we worked together to connect the communication between two parts, the board and the computer, to finally complete the whole program.