-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIRDecoder.h
More file actions
77 lines (65 loc) · 2.42 KB
/
IRDecoder.h
File metadata and controls
77 lines (65 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <Arduino.h>
#include <Romi32U4.h>
/*
* A class to interpret IR remotes with NEC encoding. NEC encoding sends four bytes:
*
* [device ID, ~divice ID, key code, ~key code]
*
* Sending the inverse allow for easy error checking (and reduces saturation in the receiver).
*
* Codes are send in little endian; this library reverses upon reception, so the first bit received
* is in the LSB of currCode. That means that the key code is found in bits [23..16] of currCode
*
* https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol
*
* This does not interpret the codes into which key was pressed. That needs to be
* mapped on a remote by remote basis.
*/
class IRDecoder
{
private:
uint8_t pin = -1;
enum IR_STATE
{
IR_READY, //idle, returns to this state after you request a code
IR_PREAMBLE, //received the start burst, waiting for first bit
IR_REPEAT, //received repeat code (part of NEC protocol); last code will be returned
IR_ACTIVE, //have some bits, but not yet complete
IR_COMPLETE, //a valid code has been received
IR_ERROR
}; //an error occurred; won't return a valid code
IR_STATE state = IR_READY; //a simple state machine for managing reception
volatile uint32_t lastReceiveTime = 0; //not really used -- could be used to sunset codes
volatile uint32_t currCode = 0; //the most recently received valid code
volatile uint8_t index = 0; //for tracking which bit we're on
volatile uint32_t fallingEdge = 0;
volatile uint32_t risingEdge = 0;
volatile uint32_t lastRisingEdge = 0; //used for tracking spacing between rising edges, i.e., bit value
public:
//volatile uint16_t bits[32]; //I used this for debugging; obsolete
public:
IRDecoder(uint8_t p) : pin(p) {}
void init(void); //call this in the setup()
void handleIRsensor(void); //ISR
uint32_t getCode(void) //returns the most recent valid code; returns zero if there was an error
{
if (state == IR_COMPLETE || state == IR_REPEAT)
{
state = IR_READY;
return currCode;
}
else
return 0;
}
int16_t getKeyCode(bool acceptRepeat = true) //returns the most recent key code; returns -1 on error (not sure if 0 can be a code or not!!!)
{
if (state == IR_COMPLETE || (acceptRepeat == true && state == IR_REPEAT))
{
state = IR_READY;
return (currCode >> 16) & 0x0ff;
}
else
return -1;
}
};
extern IRDecoder decoder;