Infrared4Arduino
IrReceiverSampler.cpp
Go to the documentation of this file.
1 #ifdef ARDUINO_ARCH_AVR
2 
3 #include "IrReceiverSampler.h"
4 #include <IrTimerDefs.h>
5 
6 uint32_t IrReceiverSampler::millisecs2ticks(milliseconds_t ms) {
7  return (1000UL * (uint32_t) ms) / microsPerTick;
8 }
9 
10 milliseconds_t IrReceiverSampler::ticks2millisecs(uint32_t tix) {
11  return (milliseconds_t) ((tix * microsPerTick)/1000UL);
12 }
13 
14 IrReceiverSampler *IrReceiverSampler::instance = NULL;
15 
16 IrReceiverSampler::IrReceiverSampler(size_t captureLength,
17  pin_t pin_,
18  bool pullup,
19  microseconds_t markExcess,
20  milliseconds_t beginningTimeout,
21  milliseconds_t endingTimeout) : IrReceiver(captureLength, pin_, pullup, markExcess) {
24  durationData = new microseconds_t[bufferSize];
25  dataLength = 0;
26  timer = 0;
27  receiverState = STATE_IDLE;
28 }
29 
31  pin_t pin,
32  bool pullup,
33  microseconds_t markExcess,
34  milliseconds_t beginningTimeout,
35  milliseconds_t endingTimeout) {
36  if (instance != NULL || pin == invalidPin)
37  return NULL;
38  instance = new IrReceiverSampler(captureLength, pin, pullup, markExcess, beginningTimeout, endingTimeout);
39  return instance;
40 }
41 
43  delete instance;
44  instance = NULL;
45 }
46 
48  delete [] durationData;
49 }
50 
51 /*
52  * The original IRrecv which uses 50us timer driven interrupts to sample input pin.
53  */
56  dataLength = 0;
57 }
58 
60  reset();
61  noInterrupts();
65  interrupts();
66 }
67 
70 }
71 
73  endingTimeoutInTicks = millisecs2ticks(timeOut);
74 }
75 
77  beginningTimeoutInTicks = millisecs2ticks(timeOut);
78 }
79 
81  return ticks2millisecs(endingTimeoutInTicks);
82 }
83 
85  return ticks2millisecs(beginningTimeoutInTicks);
86 }
87 
89 ISR(TIMER_INTR_NAME) {
91  IrReceiver::irdata_t irdata = recv->readIr();
92  recv->timer++; // One more 50us tick
93  if (recv->dataLength >= recv->getBufferSize()) {
94  // Buffer full
96  }
97  switch (recv->receiverState) {
98  case IrReceiverSampler::STATE_IDLE: // Looking for first mark
99  if (irdata == IrReceiver::IR_MARK) {
100  // Got the first mark, record duration and start recording transmission
101  recv->dataLength = 0;
102  recv->timer = 0;
104  } else {
105  if (recv->timer >= recv->beginningTimeoutInTicks) {
106  recv->durationData[recv->dataLength] = recv->timer;
107  recv->timer = 0;
109  }
110  }
111  break;
113  if (irdata == IrReceiver::IR_SPACE) {
114  // MARK ended, record time
115  recv->durationData[recv->dataLength++] = recv->timer;
116  recv->timer = 0;
118  }
119  break;
121  if (irdata == IrReceiver::IR_MARK) {
122  // SPACE just ended, record it
123  recv->durationData[recv->dataLength++] = recv->timer;
124  recv->timer = 0;
126  } else {
127  // still silence, is it over?
128  if (recv->timer > recv->endingTimeoutInTicks) {
129  // big SPACE, indicates gap between codes
130  recv->durationData[recv->dataLength++] = recv->timer;
131  //recv->timer = 0;
133  }
134  }
135  break;
137  break;
138  default:
139  // should not happen
140  break;
141  }
142 }
143 
144 #endif // ! ARDUINO_ARCH_AVR
void setBeginningTimeout(milliseconds_t timeOut)
off-period, also called gap
Definition: IrReceiver.h:53
Between signals; waiting for first mark.
static const unsigned long microsPerTick
microseconds per clock interrupt
#define TIMER_DISABLE_INTR
Definition: boarddefs.h:225
void setBeginningTimeout(milliseconds_t timeOut)
#define TIMER_RESET
Definition: boarddefs.h:221
uint16_t microseconds_t
Type for durations in micro seconds.
Definition: InfraredTypes.h:15
volatile ReceiverState_t receiverState
State of the state machine.
unsigned int getBufferSize() const
Definition: IrReader.h:146
static IrReceiverSampler * newIrReceiverSampler(size_t captureLength=defaultCaptureLength, pin_t pin=defaultPin, bool pullup=false, microseconds_t markExcess=defaultMarkExcess, milliseconds_t beginningTimeout=defaultBeginningTimeout, milliseconds_t endingTimeout=defaultEndingTimeout)
This factory method replaces public constructors.
#define TIMER_INTR_NAME
Definition: boarddefs.h:226
uint8_t pin_t
Type for GPIO pin, compatible with Arduino libs.
Definition: InfraredTypes.h:37
volatile size_t dataLength
Number of entries in durationData.
irdata_t
Enum for the duration types.
Definition: IrReceiver.h:51
void setEndingTimeout(milliseconds_t timeOut)
This receiving class samples the input pin every 50 microseconds using a timer interrupt.
size_t bufferSize
Definition: IrReader.h:41
#define TIMER_ENABLE_INTR
Definition: boarddefs.h:224
uint16_t milliseconds_t
Type for durations in milli seconds.
Definition: InfraredTypes.h:25
Abstract base class for demodulating IR receivers.
Definition: IrReceiver.h:11
void enable()
Start reception of IR data.
static void deleteInstance()
Deletes the instance, thereby freeing up the resources it occupied, and allowing for another instance...
volatile uint32_t timer
state timer, counts 50uS ticks.
volatile microseconds_t * durationData
Data buffer.
milliseconds_t endingTimeout
Definition: IrReader.h:39
on-period, also called flash
Definition: IrReceiver.h:52
#define TIMER_CONFIG_NORMAL()
Definition: boarddefs.h:247
virtual ~IrReceiverSampler()
void disable()
Stop reception of IR data.
Complete signal has been read.
const pin_t invalidPin
Symbolic name for an invalid pin number.
Definition: InfraredTypes.h:39
milliseconds_t beginningTimeout
Definition: IrReader.h:38
uint32_t beginningTimeoutInTicks
void setEndingTimeout(milliseconds_t timeOut)
Definition of timers etc is encapsulated in this file.
int16_t markExcess
Microseconds subtracted from pulses and added to gaps.
Definition: IrReader.h:44
milliseconds_t getEndingTimeout() const
milliseconds_t getBeginningTimeout() const
uint32_t endingTimeoutInTicks
static IrReceiverSampler * getInstance()
Returns a pointer to the instance, or NULL.