PPM Output Implementation

Overview

Below is a brief overview of the methods I used to create my PPM output adaptation. In the future, this solution might change, and as a result, this page will need to be updated.

At the time of writing, the code is in a folder labelled ppm_output under the firmware prototypes repository. You can find the body of the code in the main while loop and a function prototype slightly above it. Much of the implementation information has been detailed in the README.txt file provided in the folder. This article will be focused more on the implementation, what worked, what did not, and future revisions.

Note: Please read the PPM protocol page if you are unfamiliar with the protocol

 

Project Specifics
Please read the README.txt file in the ppm_output folder for more information about project specifics. Reading through the said file, as while as the code in main.cpp will help and prevent me from repeating my words too much. Update: I moved the project I used into a separate folder labelled “PPMOutput.” The entire project can be found in the folder, including configurations and an uncommented code version.

 

Operation

When testing, I used the two-timer approach to test my solution. In the photo below, D3 is based on my TIM3 configuration and is meant to be my PWM signal, and D5 is based on TIM5 and is intended to be my PPM signal. Due to the nature of the signal analyzer, the first visible pulse on D3 will always correspond to the second value we set in our struct. However, our PPM wave will not be hindered by this downfall. Below is a screenshot to serve as an example.

 

Code

The following struct contains all of the information necessary for the ppm output. Our pulse values are an array where each value represents the duty cycle (in ticks) of the channel we are sampling. Our pulse difference variable looks at the difference between the current and the following pulse. If the difference is greater than zero, we set it to true and false otherwise. The final variable represents the number of channels we want to set. In our case, this is 16.

Our base_arr variable is configured to correspond to the default period of TIM5. Depending on the difference we compute between pulse values, our period will deviate from this value by said amount. The time_diff variable was used to correct errors experienced when the first pulse value was greater than the second.

Below is a screenshot of the main while loop. Here we iterate through all of our PWM duty cycle values (represented in ticks) and set our PPM signal accordingly. Our first block is called in a different order when the very first value is bigger than the second. This helped remove an error where the first value would not appear - more about this issue in README.txt. HAL_Delay also improves the consistency of our capture. Without it, our code will run too fast for our liking, so we would not set every channel. In the future, this code will be moved into a function called once to set x channels.

 

Unsuccessful Attempts

Much of the time spent on the issue was LOS(t) due to LOS issues. Real progress did not happen until I set up my project and configured all peripherals to handle this problem. If I were to start this project again, I would have start with my project from the start, as this would have given me more time to think about implementing my ideas instead of wrestling with compiler errors.