Infrared4Arduino 1.2.3
Loading...
Searching...
No Matches
IrWidget.h
Go to the documentation of this file.
1/* IR Widget: capture a raw IR signal and dump the timing of the non-demodulated signal
2
3http://www.piclist.com/images/boards/irwidget/index.htm
4http://www.hifi-remote.com/forums/dload.php?action=file&file_id=2044
5http://www.hifi-remote.com/wiki/index.php?title=IR_Scope_and_IR_Widget_User%27s_Guide
6http://www.compendiumarcana.com/irwidget/
7
8Arduino digital pin numbers for the input capture pin (ICP) and the logic analyzer debugging pin (LA Dbg):
9Board name / MCU | ICP pin | LA Dbg pin
10-------------------------------------------|--------------.-----------|------------------------
11Duemilanove/Uno (ATmega328P / ATmega168) | ICP1/PB0, Arduino pin 8 | PD6, Arduino pin 6
12Leonardo (ATmega32U4) | ICP1/PD4, Arduino pin 4 | PD6, Arduino pin 12
13Arduino Mega 2560 (ATmega2560) | ICP4/PL0, Arduino pin 49 | PL6, Arduino pin 43
14
15see also here:
16http://arduino.cc/en/Hacking/PinMapping168 (also for ATmega328P)
17http://arduino.cc/en/Hacking/PinMapping32u4
18http://arduino.cc/en/Hacking/PinMapping2560
19 */
20
21// Copyright (c) 2012 Michael Dreher <michael(at)5dot1.de>
22// this code may be distributed under the terms of the General Public License V2 (GPL V2)
23
24// Code slighty reorganized by Bengt Martensson
25
26//#define ALTERNATE_PIN
27#pragma once
28
29#include <Arduino.h>
30#include "IrReader.h"
31#include "Board.h"
32
33#define ENABLE_PULL_UP
34//#define DEBUG_PORT D
35//#define DEBUG_PIN 6
36//#define DEBUG_PORT L
37
38#define USE_PRESCALER_FACTOR_8 1
39
44class IrWidget : public IrReader {
45public:
46 static constexpr int16_t defaultMarkExcess = 0;
47
48protected:
50
51 IrWidget(size_t captureLength = defaultCaptureLength,
52 bool pullup = false,
56 virtual ~IrWidget();
57
58public:
63 static const bool invertingSensor = true;
64
65 virtual void capture() = 0;
66
70 void receive() {
71 capture();
72 }
73
74 size_t getDataLength() const { // was: getCaptureCount()
75 return captureCount;
76 }
77
78 bool isReady() const {
79 return timeouted || !isEmpty();
80 }
81
82 void reset() {
83 captureCount = 0;
84 }
85
86 microseconds_t inline getDuration(unsigned int i) const {
87 uint32_t result32 = timerValueToNanoSeconds(unpackTimeVal(captureData[i])) / 1000
88 + (i & 1 ? markExcess : -markExcess);
89 return result32 <= MICROSECONDS_T_MAX ? (microseconds_t) result32 : MICROSECONDS_T_MAX;
90 }
91
98
100
102 return frequency;
103 }
104
105 void dump(Stream &stream) const;
106
107private:
108 void setup(bool setup);
109
111 // Internal defines, don't change
113
114protected:
115#if USE_PRESCALER_FACTOR_8
116#define CAPTURE_PRESCALER_SETTING (_BV(CAT3(CS, CAP_TIM, 1)))
117#define CAPTURE_PRESCALER_BITS (3)
118#else
119#define CAPTURE_PRESCALER_SETTING (_BV(CAT3(CS, CAP_TIM, 0)))
120#define CAPTURE_PRESCALER_BITS (0)
121#endif
122#define CAPTURE_PRESCALER_FACTOR (_BV(CAPTURE_PRESCALER_BITS))
123
124#if RANGE_EXTENSION_BITS > 8
125 typedef uint16_t ovlBitsDataType;
126#else
127 typedef uint8_t ovlBitsDataType;
128#endif
129
130 static constexpr uint8_t RANGE_EXTENSION_BITS = 4; // factor for upper measurement range = 2^(RANGE_EXTENSION_BITS+1)
131
132 ovlBitsDataType endingTimeout; // = _BV(RANGE_EXTENSION_BITS) - 1;
133
134private:
136 // Adaption to different MCUs and clk values
138#if defined(_AVR_IOM32U4_H_)
139#ifndef ALTERNATE_PIN
140 // Digital pin 4, ICP1
141#define CAP_PORT D
142#define CAP_PIN 4
143#define CAP_TIM 1
144#define CAP_TIM_OC A
145#else // Alternate pin
146 // Digital pin 13, ICP3
147#define CAP_PORT C
148#define CAP_PIN 7
149#define CAP_TIM 3
150#define CAP_TIM_OC A
151#endif // ALTERNATE_PIN
152#elif defined(_AVR_IOM2560_H_)
153#ifndef ALTERNATE_PIN
154 // Digital pin 49, ICP4
155#define CAP_PORT L
156#define CAP_PIN 0
157#define CAP_TIM 4
158#define CAP_TIM_OC A
159#else // ALTERNATE_PIN
160 // Digital pin 48, ICP5
161#define CAP_PORT L
162#define CAP_PIN 1
163#define CAP_TIM 5
164#define CAP_TIM_OC A
165#endif // ALTERNATE_PIN
166#else
167 // the default is the setting for the ATmega328P / ATmega168
168 // Digital pin 8, ICP1
169#define CAP_PORT B
170#define CAP_PIN 0
171#define CAP_TIM 1
172#define CAP_TIM_OC A
173#endif
174
176 // Helper macros
178#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // clear bit
179#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // set bit
180#define __CAT2(base, portname) base##portname // internally needed by CAT2
181#define CAT2(prefix, num) __CAT2(prefix, num) // build a define name from 2 params
182#define __CAT3(prefix, num, postfix) prefix##num##postfix // internally needed by CAT3
183#define CAT3(prefix, num, postfix) __CAT3(prefix, num, postfix) // build a define name from 3 params
184
185 // these macros are used to debug the timing with an logic analyzer or oscilloscope on a port pin
186protected:
187 inline void debugPinToggle(void) {
188#if defined(DEBUG_PIN) && defined(DEBUG_PORT)
189 CAT2(PIN, DEBUG_PORT) = _BV(DEBUG_PIN);
190#endif
191 }
192
193 inline void debugPinClear(void) {
194#if defined(DEBUG_PIN) && defined(DEBUG_PORT)
195 cbi(CAT2(PORT, DEBUG_PORT), DEBUG_PIN);
196#endif
197 }
198 uint16_t *captureData; //[bufSize]; // the buffer where the catured data is stored
199 uint16_t captureCount; // number of values stored in captureData
200 static constexpr uint8_t sampleSize = 2;
201
202 virtual uint32_t unpackTimeVal(uint32_t val) const = 0;
203
204 // convert number of clocks to nanoseconds, try to use integer arithmetic and avoid
205 // overflow and too much truncation (double arithmetic costs additional 800 byte of code)
206 static uint32_t inline timerValueToNanoSeconds(uint32_t x) {
207#if (F_CPU % 8000000) == 0
208 return (x * (125UL << CAPTURE_PRESCALER_BITS)) / (F_CPU / 8000000UL);
209#elif (F_CPU % 1000000) == 0
210 return (x * (1000UL << CAPTURE_PRESCALER_BITS)) / (F_CPU / 1000000UL);
211#elif (F_CPU % 115200) == 0 // serial bps rate compatible cpu clocks, e.g. 7372800 or 14745600
212 // TODO: this has to be tested, especially the accuracy
213 return (((x * (1000UL << CAPTURE_PRESCALER_BITS)) / (F_CPU / 115200UL)) * 625UL) / 72UL;
214#else
215 // TODO: this has to be tested
216 return (uint32_t) (((double) x * (1.0E9 * (double) CAPTURE_PRESCALER_FACTOR)) / (double) F_CPU); // use double precision floating point arithmetic
217#endif
218 }
219};
static constexpr microseconds_t MICROSECONDS_T_MAX
Largest microseconds_t number possible.
Definition: InfraredTypes.h:18
uint16_t microseconds_t
Type for durations in micro seconds.
Definition: InfraredTypes.h:15
uint32_t frequency_t
Type for modulation frequency in Hz.
Definition: InfraredTypes.h:31
uint16_t milliseconds_t
Type for durations in milli seconds.
Definition: InfraredTypes.h:24
#define CAPTURE_PRESCALER_BITS
Definition: IrWidget.h:117
#define CAPTURE_PRESCALER_FACTOR
Definition: IrWidget.h:122
#define CAT2(prefix, num)
Definition: IrWidget.h:181
#define cbi(sfr, bit)
Definition: IrWidget.h:178
Abstract base class for all IR readers, capturing or receiving.
Definition: IrReader.h:30
static constexpr size_t defaultCaptureLength
Definition: IrReader.h:35
int16_t markExcess
Microseconds subtracted from pulses and added to gaps.
Definition: IrReader.h:44
milliseconds_t beginningTimeout
Definition: IrReader.h:38
static constexpr milliseconds_t defaultEndingTimeout
Definition: IrReader.h:34
static constexpr milliseconds_t defaultBeginningTimeout
Definition: IrReader.h:33
virtual bool isEmpty() const
Definition: IrReader.h:141
bool timeouted
True if last receive ended with a timeout.
Definition: IrReader.h:47
Base class for classes based upon ICP pins capture.
Definition: IrWidget.h:44
void reset()
Definition: IrWidget.h:82
static constexpr int16_t defaultMarkExcess
Definition: IrWidget.h:46
uint16_t * captureData
Definition: IrWidget.h:198
IrWidget(size_t captureLength=defaultCaptureLength, bool pullup=false, int16_t markExcess=defaultMarkExcess, milliseconds_t beginningTimeout=defaultBeginningTimeout, milliseconds_t endingTimeout=defaultEndingTimeout)
uint16_t captureCount
Definition: IrWidget.h:199
static constexpr uint8_t sampleSize
Definition: IrWidget.h:200
frequency_t getFrequency() const
Returns frequency of received signal.
Definition: IrWidget.h:101
uint8_t ovlBitsDataType
Definition: IrWidget.h:127
frequency_t frequency
Definition: IrWidget.h:49
static const bool invertingSensor
Set true means if sensor signal is inverted (low = signal on) (false has not been tested,...
Definition: IrWidget.h:63
virtual void capture()=0
void debugPinToggle(void)
Definition: IrWidget.h:187
void setEndingTimeout(milliseconds_t timeout)
Sets the ending timeout.
bool isReady() const
Returns true if there is collected data.
Definition: IrWidget.h:78
static uint32_t timerValueToNanoSeconds(uint32_t x)
Definition: IrWidget.h:206
static constexpr uint8_t RANGE_EXTENSION_BITS
Definition: IrWidget.h:130
void dump(Stream &stream) const
Prints a textual representation of the received data to the Stream supplied.
virtual ~IrWidget()
void debugPinClear(void)
Definition: IrWidget.h:193
microseconds_t getDuration(unsigned int i) const
Returns the index-th duration, if possible.
Definition: IrWidget.h:86
virtual uint32_t unpackTimeVal(uint32_t val) const =0
void receive()
For compatibility with the receiver classes, receive is a synonym for capture.
Definition: IrWidget.h:70
ovlBitsDataType endingTimeout
Definition: IrWidget.h:132
milliseconds_t getEndingTimeout() const
size_t getDataLength() const
Returns the number of collected durations.
Definition: IrWidget.h:74