RSeries astromech firmware
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
PPMDecoder.h
Go to the documentation of this file.
1 #ifndef PPMDecoder_h_
2 #define PPMDecoder_h_
3 
4 #include "ReelTwo.h"
5 #include "core/SetupEvent.h"
6 
7 class PPMDecoder: public SetupEvent
8 {
9 public:
10  PPMDecoder(uint8_t pin, unsigned channelCount = 6) :
11  fPin(pin),
12  fChannelCount(channelCount),
13  fChannel(new uint16_t[fChannelCount]),
14  fLastChannel(new uint16_t[fChannelCount])
15  {
16  init();
17  }
18 
20  {
21  delete[] fChannel;
22  delete[] fLastChannel;
23  }
24 
25  void init()
26  {
27  fPass = 0;
28  fPinState = LOW;
29  fCurrent = fChannelCount;
30  memset(fChannel, '\0', sizeof(fChannelCount)*sizeof(uint16_t));
31  memset(fLastChannel, '\0', sizeof(fChannelCount)*sizeof(uint16_t));
32  }
33 
34  virtual void setup() override
35  {
36  pinMode(fPin, INPUT);
37  }
38 
39  bool decode()
40  {
41  uint32_t pulse = readPulse(fPin);
42  if (!pulse)
43  return false;
44  if (fCurrent == fChannelCount)
45  {
46  if (pulse > 3000)
47  fCurrent = 0;
48  }
49  else
50  {
51  fChannel[fCurrent++] = pulse;
52  if (fCurrent == fChannelCount)
53  {
54  for (unsigned i = 0; i < fChannelCount; i++)
55  {
56  if (fChannel[i] > 2000 || fChannel[i] < 100)
57  {
58  fChannel[i] = fLastChannel[i];
59  }
60  else
61  {
62  fChannel[i] = (fLastChannel[i] + fChannel[i]) / 2;
63  fPass++;
64  }
65  }
66  if (fPass > 10)
67  {
68  for (unsigned i = 0; i < fChannelCount; i++)
69  {
70  #ifdef USE_PPM_DEBUG
71  DEBUG_PRINT("CH");
72  DEBUG_PRINT(i+1);
73  DEBUG_PRINT.print(": ");
74  DEBUG_PRINT(fChannel[i]);
75  DEBUG_PRINT(" ");
76  #endif
77  fLastChannel[i] = fChannel[i];
78  }
79  #ifdef USE_PPM_DEBUG
80  DEBUG_PRINT('\r');
81  #endif
82  fPass = 0;
83  return true;
84  }
85  }
86  }
87  return false;
88  }
89 
90  uint16_t channel(unsigned ch, unsigned minvalue, unsigned maxvalue, unsigned neutralvalue)
91  {
92  unsigned pulse = (ch < fChannelCount) ? fChannel[ch] : 0;
93  if (pulse != 0)
94  return map(max(min(pulse, 1600u), 600u), 600u, 1600u, minvalue, maxvalue);
95  return neutralvalue;
96  }
97 
98 private:
99  uint8_t fPin;
100  int fPinState;
101  unsigned fPass;
102  unsigned fCurrent;
103  unsigned fChannelCount;
104  uint32_t fRisingTime;
105  uint16_t* fChannel;
106  uint16_t* fLastChannel;
107 
108  uint32_t readPulse(uint8_t pin)
109  {
110  uint8_t state = digitalRead(pin);
111  uint32_t pulseLength = 0;
112 
113  // On rising edge: record current time.
114  if (fPinState == LOW && state == HIGH)
115  {
116  fRisingTime = micros();
117  }
118 
119  // On falling edge: report pulse length.
120  if (fPinState == HIGH && state == LOW)
121  {
122  unsigned long fallingTime = micros();
123  pulseLength = fallingTime - fRisingTime;
124  }
125 
126  fPinState = state;
127  return pulseLength;
128  }
129 };
130 
131 #endif
DEBUG_PRINT
#define DEBUG_PRINT(s)
Definition: ReelTwo.h:189
ReelTwo.h
SetupEvent.h
SetupEvent
Base class for all devices that require setup that cannot happen in the constructor....
Definition: SetupEvent.h:15
PPMDecoder::setup
virtual void setup() override
Subclasses must implement this function to perform any necessary setup that cannot happen in the cons...
Definition: PPMDecoder.h:34
PPMDecoder::init
void init()
Definition: PPMDecoder.h:25
PPMDecoder::channel
uint16_t channel(unsigned ch, unsigned minvalue, unsigned maxvalue, unsigned neutralvalue)
Definition: PPMDecoder.h:90
PPMDecoder
Definition: PPMDecoder.h:7
PPMDecoder::decode
bool decode()
Definition: PPMDecoder.h:39
PPMDecoder::~PPMDecoder
~PPMDecoder()
Definition: PPMDecoder.h:19
PPMDecoder::PPMDecoder
PPMDecoder(uint8_t pin, unsigned channelCount=6)
Definition: PPMDecoder.h:10