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;
}
Joseph Roberts
