Joseph Roberts / PPM

Dependents:   PPM_Test QuadCopter Quadcopter_mk2

Committer:
joe4465
Date:
Tue Aug 26 15:54:34 2014 +0000
Revision:
0:083ed8cea5ff
Child:
1:fb0ab71eb0ea
First version of my PPM library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joe4465 0:083ed8cea5ff 1 #include "PPM.h"
joe4465 0:083ed8cea5ff 2
joe4465 0:083ed8cea5ff 3 //PPM reader by Joe Roberts, based on work by John Wolter
joe4465 0:083ed8cea5ff 4 //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
joe4465 0:083ed8cea5ff 5 //See
joe4465 0:083ed8cea5ff 6 PPM::PPM(InterruptIn *ppmPin, float minimumOutput, float maximumOutput, int minimumPulseTime, int maximumPulseTime, int numberOfChannels, int throttleChannel)
joe4465 0:083ed8cea5ff 7 {
joe4465 0:083ed8cea5ff 8 //Assign local variables passed into constructor
joe4465 0:083ed8cea5ff 9 _ppmPin = ppmPin;
joe4465 0:083ed8cea5ff 10 _minimumOutput = minimumOutput;
joe4465 0:083ed8cea5ff 11 _maximumOutput = maximumOutput;
joe4465 0:083ed8cea5ff 12 _minimumPulseTime = minimumPulseTime;
joe4465 0:083ed8cea5ff 13 _maximumPulseTime = maximumPulseTime;
joe4465 0:083ed8cea5ff 14 _numberOfChannels = numberOfChannels;
joe4465 0:083ed8cea5ff 15 _throttleChannel = throttleChannel;
joe4465 0:083ed8cea5ff 16
joe4465 0:083ed8cea5ff 17 //Set other variables
joe4465 0:083ed8cea5ff 18 _currentChannel = 0;
joe4465 0:083ed8cea5ff 19 _timeElapsed = 0;
joe4465 0:083ed8cea5ff 20 _minFrameTime = 6000;
joe4465 0:083ed8cea5ff 21 _shortTime = 800;
joe4465 0:083ed8cea5ff 22
joe4465 0:083ed8cea5ff 23 //Initialise arrays
joe4465 0:083ed8cea5ff 24 for(int i = 0; i < _numberOfChannels; i++)
joe4465 0:083ed8cea5ff 25 {
joe4465 0:083ed8cea5ff 26 _times[i] = 0;
joe4465 0:083ed8cea5ff 27 _completeTimes[i] = 0;
joe4465 0:083ed8cea5ff 28 }
joe4465 0:083ed8cea5ff 29
joe4465 0:083ed8cea5ff 30 //Assign interrupt
joe4465 0:083ed8cea5ff 31 _ppmPin->mode (PullUp);
joe4465 0:083ed8cea5ff 32 _ppmPin->rise (this, &PPM::SignalRise);
joe4465 0:083ed8cea5ff 33
joe4465 0:083ed8cea5ff 34 //Start timer
joe4465 0:083ed8cea5ff 35 _timer.start();
joe4465 0:083ed8cea5ff 36 }
joe4465 0:083ed8cea5ff 37
joe4465 0:083ed8cea5ff 38 //Here is where all the work decoding the PPM signal takes place
joe4465 0:083ed8cea5ff 39 void PPM::SignalRise()
joe4465 0:083ed8cea5ff 40 {
joe4465 0:083ed8cea5ff 41 //Get the time taken since the last interrupt
joe4465 0:083ed8cea5ff 42 _timeElapsed = _timer.read_us();
joe4465 0:083ed8cea5ff 43
joe4465 0:083ed8cea5ff 44 //If time is less than _shortTime then the channel timing is too short - ignore
joe4465 0:083ed8cea5ff 45 if (_timeElapsed < _shortTime) return;
joe4465 0:083ed8cea5ff 46
joe4465 0:083ed8cea5ff 47 //Disable the interrupt
joe4465 0:083ed8cea5ff 48 _ppmPin->rise(NULL);
joe4465 0:083ed8cea5ff 49
joe4465 0:083ed8cea5ff 50 //Reset the timer
joe4465 0:083ed8cea5ff 51 _timer.reset();
joe4465 0:083ed8cea5ff 52
joe4465 0:083ed8cea5ff 53 //Check for a new frame signal, if before start of new frame then its a glitch - start a new frame
joe4465 0:083ed8cea5ff 54 if ((_timeElapsed > _minFrameTime) && (_currentChannel != 0)) _currentChannel = 0;
joe4465 0:083ed8cea5ff 55
joe4465 0:083ed8cea5ff 56 //Check for a new frame signal, if it is the start of a new frame then start new frame
joe4465 0:083ed8cea5ff 57 if ((_timeElapsed > _minFrameTime ) && (_currentChannel == 0))
joe4465 0:083ed8cea5ff 58 {
joe4465 0:083ed8cea5ff 59 //Assign interrupt
joe4465 0:083ed8cea5ff 60 _ppmPin->rise (this, &PPM::SignalRise);
joe4465 0:083ed8cea5ff 61 return;
joe4465 0:083ed8cea5ff 62 }
joe4465 0:083ed8cea5ff 63
joe4465 0:083ed8cea5ff 64 //Save the time to the times array
joe4465 0:083ed8cea5ff 65 _times[_currentChannel] = _timeElapsed;
joe4465 0:083ed8cea5ff 66 _currentChannel++;
joe4465 0:083ed8cea5ff 67
joe4465 0:083ed8cea5ff 68 //Check for a complete frame
joe4465 0:083ed8cea5ff 69 if (_currentChannel == _numberOfChannels)
joe4465 0:083ed8cea5ff 70 {
joe4465 0:083ed8cea5ff 71 //Set channel iterator to 0
joe4465 0:083ed8cea5ff 72 _currentChannel = 0;
joe4465 0:083ed8cea5ff 73 //Copy times array to complete times array
joe4465 0:083ed8cea5ff 74 memcpy(_completeTimes, _times, sizeof(_times));
joe4465 0:083ed8cea5ff 75 }
joe4465 0:083ed8cea5ff 76
joe4465 0:083ed8cea5ff 77 //Assign interrupt
joe4465 0:083ed8cea5ff 78 _ppmPin->rise(this, &PPM::SignalRise);
joe4465 0:083ed8cea5ff 79 return;
joe4465 0:083ed8cea5ff 80 }
joe4465 0:083ed8cea5ff 81
joe4465 0:083ed8cea5ff 82 //Place mapped channel data into the passed in array
joe4465 0:083ed8cea5ff 83 void PPM::GetChannelData(float * channelData)
joe4465 0:083ed8cea5ff 84 {
joe4465 0:083ed8cea5ff 85 //Iterate over the channel times array
joe4465 0:083ed8cea5ff 86 for(int i = 0; i < _numberOfChannels; i++)
joe4465 0:083ed8cea5ff 87 {
joe4465 0:083ed8cea5ff 88 //Check the transmitter is still connected by checking the thottle
joe4465 0:083ed8cea5ff 89 if((i == _throttleChannel - 1) && (_completeTimes[i] < _minimumPulseTime)) channelData[i] = -1;
joe4465 0:083ed8cea5ff 90 else
joe4465 0:083ed8cea5ff 91 {
joe4465 0:083ed8cea5ff 92 //Map the channel times to value between the channel min and channel max
joe4465 0:083ed8cea5ff 93 channelData[i] = (_completeTimes[i] - _minimumPulseTime) * (_maximumOutput - _minimumOutput) / (_maximumPulseTime - _minimumPulseTime) + _minimumOutput;
joe4465 0:083ed8cea5ff 94 }
joe4465 0:083ed8cea5ff 95 }
joe4465 0:083ed8cea5ff 96
joe4465 0:083ed8cea5ff 97 return;
joe4465 0:083ed8cea5ff 98 }