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.

Committer:
joe4465
Date:
Wed Apr 01 11:18:23 2015 +0000
Revision:
3:d13b9e50312f
Parent:
2:b67f18c84c05
...

Who changed what in which revision?

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