First version of my PPM library.
Dependents: PPM_Test QuadCopter Quadcopter_mk2
Ppm.cpp
00001 #include "Ppm.h" 00002 00003 //Ppm reader by Joe Roberts, based on work by John Wolter 00004 //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 00005 //See 00006 Ppm::Ppm(PinName pin, int minimumOutput, int maximumOutput, int minimumPulseTime, int maximumPulseTime, int numberOfChannels, int throttleChannel) 00007 { 00008 //Assign local variables passed into constructor 00009 _ppmPin = new InterruptIn(pin); 00010 _minimumOutput = minimumOutput; 00011 _maximumOutput = maximumOutput; 00012 _minimumPulseTime = minimumPulseTime; 00013 _maximumPulseTime = maximumPulseTime; 00014 _numberOfChannels = numberOfChannels; 00015 _throttleChannel = throttleChannel; 00016 00017 //Set other variables 00018 _currentChannel = 0; 00019 _timeElapsed = 0; 00020 _minFrameTime = 6000; 00021 _shortTime = 800; 00022 00023 //Initialise arrays 00024 for(int i = 0; i < _numberOfChannels; i++) 00025 { 00026 _times[i] = 0; 00027 _completeTimes[i] = 0; 00028 } 00029 00030 //Assign interrupt 00031 _ppmPin->mode (PullUp); 00032 _ppmPin->rise (this, &Ppm::SignalRise); 00033 00034 //Start timer 00035 _timer.start(); 00036 } 00037 00038 //Here is where all the work decoding the Ppm signal takes place 00039 void Ppm::SignalRise() 00040 { 00041 //Get the time taken since the last interrupt 00042 _timeElapsed = _timer.read_us(); 00043 00044 //If time is less than _shortTime then the channel timing is too short - ignore 00045 if (_timeElapsed < _shortTime) return; 00046 00047 //Disable the interrupt 00048 _ppmPin->rise(NULL); 00049 00050 //Reset the timer 00051 _timer.reset(); 00052 00053 //Check for a new frame signal, if before start of new frame then its a glitch - start a new frame 00054 if ((_timeElapsed > _minFrameTime) && (_currentChannel != 0)) _currentChannel = 0; 00055 00056 //Check for a new frame signal, if it is the start of a new frame then start new frame 00057 if ((_timeElapsed > _minFrameTime ) && (_currentChannel == 0)) 00058 { 00059 //Assign interrupt 00060 _ppmPin->rise (this, &Ppm::SignalRise); 00061 return; 00062 } 00063 00064 //Save the time to the times array 00065 _times[_currentChannel] = _timeElapsed; 00066 _currentChannel++; 00067 00068 //Check for a complete frame 00069 if (_currentChannel == _numberOfChannels) 00070 { 00071 //Set channel iterator to 0 00072 _currentChannel = 0; 00073 //Copy times array to complete times array 00074 memcpy(_completeTimes, _times, sizeof(_times)); 00075 } 00076 00077 //Assign interrupt 00078 _ppmPin->rise(this, &Ppm::SignalRise); 00079 return; 00080 } 00081 00082 //Place mapped channel data into the passed in array 00083 void Ppm::GetChannelData(double* channelData) 00084 { 00085 //Iterate over the channel times array 00086 for(int i = 0; i < _numberOfChannels; i++) 00087 { 00088 //Check the transmitter is still connected by checking the thottle 00089 if((i == _throttleChannel - 1) && (_completeTimes[i] < _minimumPulseTime)) channelData[i] = -1; 00090 else 00091 { 00092 //Map the channel times to value between the channel min and channel max 00093 channelData[i] = Map(_completeTimes[i] , _minimumPulseTime, _maximumPulseTime, _minimumOutput, _maximumOutput); 00094 } 00095 } 00096 00097 return; 00098 } 00099 00100 double Ppm::Map(double input, double inputMin, double inputMax, double outputMin, double outputMax) 00101 { 00102 return (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin; 00103 }
Generated on Thu Jul 14 2022 10:01:40 by 1.7.2