First version of my PPM library.
Dependents: PPM_Test QuadCopter Quadcopter_mk2
Have a look at PPM_Test to see how this library is used.
Import programPPM_Test
Test program for my PPM library.
Ppm.cpp
- Committer:
- joe4465
- Date:
- 2015-04-01
- Revision:
- 3:d13b9e50312f
- Parent:
- 2:b67f18c84c05
File content as of revision 3:d13b9e50312f:
#include "Ppm.h" //Ppm reader by Joe Roberts, based on work by John Wolter //This program takes the Ppm Signal (Pulse Position Modulation) from your RC transmitter and outputs the data between the min/max outputs passed into the constructor //See Ppm::Ppm(PinName pin, int minimumOutput, int maximumOutput, int minimumPulseTime, int maximumPulseTime, int numberOfChannels, int throttleChannel) { //Assign local variables passed into constructor _ppmPin = new InterruptIn(pin); _minimumOutput = minimumOutput; _maximumOutput = maximumOutput; _minimumPulseTime = minimumPulseTime; _maximumPulseTime = maximumPulseTime; _numberOfChannels = numberOfChannels; _throttleChannel = throttleChannel; //Set other variables _currentChannel = 0; _timeElapsed = 0; _minFrameTime = 6000; _shortTime = 800; //Initialise arrays for(int i = 0; i < _numberOfChannels; i++) { _times[i] = 0; _completeTimes[i] = 0; } //Assign interrupt _ppmPin->mode (PullUp); _ppmPin->rise (this, &Ppm::SignalRise); //Start timer _timer.start(); } //Here is where all the work decoding the Ppm signal takes place void Ppm::SignalRise() { //Get the time taken since the last interrupt _timeElapsed = _timer.read_us(); //If time is less than _shortTime then the channel timing is too short - ignore if (_timeElapsed < _shortTime) return; //Disable the interrupt _ppmPin->rise(NULL); //Reset the timer _timer.reset(); //Check for a new frame signal, if before start of new frame then its a glitch - start a new frame if ((_timeElapsed > _minFrameTime) && (_currentChannel != 0)) _currentChannel = 0; //Check for a new frame signal, if it is the start of a new frame then start new frame if ((_timeElapsed > _minFrameTime ) && (_currentChannel == 0)) { //Assign interrupt _ppmPin->rise (this, &Ppm::SignalRise); return; } //Save the time to the times array _times[_currentChannel] = _timeElapsed; _currentChannel++; //Check for a complete frame if (_currentChannel == _numberOfChannels) { //Set channel iterator to 0 _currentChannel = 0; //Copy times array to complete times array memcpy(_completeTimes, _times, sizeof(_times)); } //Assign interrupt _ppmPin->rise(this, &Ppm::SignalRise); return; } //Place mapped channel data into the passed in array void Ppm::GetChannelData(double* channelData) { //Iterate over the channel times array for(int i = 0; i < _numberOfChannels; i++) { //Check the transmitter is still connected by checking the thottle if((i == _throttleChannel - 1) && (_completeTimes[i] < _minimumPulseTime)) channelData[i] = -1; else { //Map the channel times to value between the channel min and channel max channelData[i] = Map(_completeTimes[i] , _minimumPulseTime, _maximumPulseTime, _minimumOutput, _maximumOutput); } } return; } double Ppm::Map(double input, double inputMin, double inputMax, double outputMin, double outputMax) { return (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin; }