Go to the documentation of this file.00001 #include "receiver.h"
00002 #include "pins_arduino.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00032
00053
00054
00055 #define MINONWIDTH 950
00056 #define MAXONWIDTH 2075
00057 #define MINOFFWIDTH 12000
00058 #define MAXOFFWIDTH 24000
00059 #define CENTER 1500
00060 #define THROTTLEZERO 1000
00061 #define MAX_ERRORS 50
00062
00063
00064 #define MAX_PCINT_CHANNELS 2
00065 #define EIGHTBITS 8
00066 #define NOT_A_CHANNEL 127
00067
00068 #if RECEIVER_CHANNELS > 6
00069 #error You cannot have more than 6 channels
00070 #endif
00071
00072
00073 static volatile uint8_t* channel2PCMSK[MAX_PCINT_CHANNELS] = {&PCMSK0,&PCMSK2};
00074 static volatile uint8_t* channel2Input[MAX_PCINT_CHANNELS] = {&PINB,&PINK};
00075 static const byte channel2PCIR[MAX_PCINT_CHANNELS]={1,4};
00076 static const byte port2Channel[]=
00077 {
00078 NOT_A_CHANNEL,
00079 NOT_A_CHANNEL,
00080 0,
00081 NOT_A_CHANNEL,
00082 NOT_A_CHANNEL,
00083 NOT_A_CHANNEL,
00084 NOT_A_CHANNEL,
00085 NOT_A_CHANNEL,
00086 NOT_A_CHANNEL,
00087 NOT_A_CHANNEL,
00088 NOT_A_CHANNEL,
00089 1,
00090 NOT_A_CHANNEL,
00091 };
00092
00093
00094
00095 typedef struct
00096 {
00097 char ok;
00098 unsigned long riseTime;
00099 unsigned long fallTime;
00100 unsigned long lastGoodWidth;
00101 } pinTimingData;
00102
00103
00104 byte pwmReceiverErr;
00105 byte pwmChannel2Data[RECEIVER_CHANNELS];
00106 volatile pinTimingData pwmPinData[MAX_PCINT_CHANNELS][EIGHTBITS];
00107 volatile pinTimingData* pwmReceiverChannelData[RECEIVER_CHANNELS];
00108
00109
00110
00111 class PWMReceiver : public Receiver
00112 {
00113 DECLARE_MODULE(PWMReceiver, Receiver)
00114
00115
00116
00117 PWMReceiver()
00118 {
00119 AddSocket("PWMReceiver.ThrottleOffset", &m_offsets[THROTTLE]);
00120 AddSocket("PWMReceiver.YawOffset", &m_offsets[YAW]);
00121 AddSocket("PWMReceiver.PitchOffset", &m_offsets[PITCH]);
00122 AddSocket("PWMReceiver.RollOffset", &m_offsets[ROLL]);
00123 AddSocket("PWMReceiver.Aux1Offset", &m_offsets[AUX1]);
00124 AddSocket("PWMReceiver.Aux2Offset", &m_offsets[AUX2]);
00125 AddSocket("PWMReceiver.ThrottleGain", &m_gains[THROTTLE]);
00126 AddSocket("PWMReceiver.YawGain", &m_gains[YAW]);
00127 AddSocket("PWMReceiver.PitchGain", &m_gains[PITCH]);
00128 AddSocket("PWMReceiver.RollGain", &m_gains[ROLL]);
00129 AddSocket("PWMReceiver.Aux1Gain", &m_gains[AUX1]);
00130 AddSocket("PWMReceiver.Aux2Gain", &m_gains[AUX2]);
00131 for (int ct=0; ct< RECEIVER_CHANNELS; ct++)
00132 {
00133 m_offsets[ct] = CENTER;
00134 m_gains[ct] = 1;
00135 }
00136 m_offsets[THROTTLE] = THROTTLEZERO;
00137 m_gains[THROTTLE] = 0.5;
00138 }
00139
00140
00141
00142
00143 virtual void ParamChanged(Socket * param)
00144 {
00145 };
00146
00147
00148
00149 virtual void Init()
00150 {
00151
00152 byte pcicrMask = 0;
00153 memset((void *)pwmPinData,0,sizeof(pwmPinData));
00154
00155 for (int ct = 0; ct < RECEIVER_CHANNELS; ct++)
00156 {
00157 pinMode(receiverChannel[ct], INPUT);
00158 pwmReceiverChannelData[ct] = NULL;
00159 int pin = receiverChannel[ct];
00160 int port = digitalPinToPort(pin);
00161 byte mask = digitalPinToBitMask(pin);
00162 if (port == NOT_A_PORT)
00163 {
00164 Error("Invalid receiver pin number ");
00165 Errorln(pin);
00166 continue;
00167 }
00168 int channel = port2Channel[port];
00169 if (channel == NOT_A_CHANNEL)
00170 {
00171 Error("Reciever cannot use this pin: ");
00172 Errorln(pin);
00173 continue;
00174 }
00175
00176 int maskBit = 0;
00177 for (;maskBit < EIGHTBITS; maskBit++)
00178 {
00179 if ((mask >> maskBit) == 1)
00180 {
00181 break;
00182 }
00183 }
00184 if (maskBit >= EIGHTBITS)
00185 {
00186 Errorln("Invalid mask");
00187 continue;
00188 }
00189 *channel2PCMSK[channel] |= mask;
00190 pcicrMask |= channel2PCIR[channel];
00191 pwmReceiverChannelData[ct] = &pwmPinData[channel][maskBit];
00192 pwmReceiverChannelData[ct]->lastGoodWidth = CENTER;
00193 }
00194
00195 PCICR |= pcicrMask;
00196 pwmReceiverErr = MAX_ERRORS;
00197
00198 SetInterval(20);
00199 SetPriority(30);
00200 }
00201
00202 virtual void Loop(const unsigned long& interval)
00203 {
00204 for (byte ct=0; ct < RECEIVER_CHANNELS; ct++)
00205 {
00206 volatile pinTimingData* data = pwmReceiverChannelData[ct];
00207 if (data)
00208 {
00209 int pos = data->lastGoodWidth - m_offsets[ct];
00210 m_channels[ct] = (pos * 2) * m_gains[ct] / 1000;
00211 if (ct >= AUX1)
00212 {
00213 if (pos < -300)
00214 {
00215 m_switches[ct - AUX1] = 0;
00216 }
00217 else if (pos > 300)
00218 {
00219 m_switches[ct - AUX1] = 2;
00220 }
00221 else
00222 {
00223 m_switches[ct - AUX1] = 1;
00224 }
00225 }
00226 }
00227 }
00228 }
00229
00230 private:
00231
00232 Parameter16 m_offsets[RECEIVER_CHANNELS];
00233 ParameterF m_gains[RECEIVER_CHANNELS];
00234
00235 public:
00236
00237 };
00238
00239
00240 void PWMReceiverISR(uint8_t pins, uint8_t channel)
00241 {
00242 static byte intLast[MAX_PCINT_CHANNELS] = {0,0};
00243 uint8_t bit;
00244 uint8_t changedPins;
00245 uint32_t time;
00246 uint32_t currentTime = micros();
00247 changedPins = pins ^ intLast[channel];
00248 intLast[channel] = pins;
00249
00250 changedPins &= *channel2PCMSK[channel];
00251 for (uint8_t i=0; i < 8; i++)
00252 {
00253 bit = 0x01 << i;
00254 if (bit & changedPins)
00255 {
00256 volatile pinTimingData& data = pwmPinData[channel][i];
00257
00258 if (bit & pins)
00259 {
00260
00261 time = currentTime - data.fallTime;
00262 data.riseTime = currentTime;
00263 data.ok &= (time >= MINOFFWIDTH) && (time <= MAXOFFWIDTH);
00264 }
00265 else
00266 {
00267 time = currentTime - data.riseTime;
00268 data.fallTime = currentTime;
00269 if ((time >= MINONWIDTH) && (time <= MAXONWIDTH))
00270 {
00271 if (data.ok)
00272 {
00273 data.lastGoodWidth = time;
00274 }
00275 else
00276 {
00277 data.ok = true;
00278 if (pwmReceiverErr)
00279 {
00280 pwmReceiverErr --;
00281 }
00282 }
00283 }
00284 }
00285 }
00286 }
00287 }
00288
00289 SIGNAL(PCINT0_vect)
00290 {
00291 PWMReceiverISR(*channel2Input[0] ,0);
00292 }
00293
00294 SIGNAL(PCINT2_vect)
00295 {
00296 PWMReceiverISR(*channel2Input[1] ,1);
00297 }
00298
00299
00300 PWMReceiver g_PWMReceiver;
00301