forked from Arduino-IRremote/Arduino-IRremote
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIRremoteSend.cpp
153 lines (137 loc) · 3.73 KB
/
IRremoteSend.cpp
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* IRremote
* Copyright 2009-2010 Ken Shirriff
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
*
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*/
#include "IRremote.h"
#include "IRremoteInt.h"
class space_enc_data necEnc = {9000 /* headerMark */ , 4500 /* headerSpace */,
560 /* mark0 */, 560 /* space0 */, 560 /* mark1 */, 1600 /* space1 */,
560 /* trailer */, 38 /* frequency */};
class space_enc_data sonyEnc = {2400 /* headerMark */ , 600 /* headerSpace */,
600 /* mark0 */, 600 /* space0 */, 1200 /* mark1 */, 600 /* space1 */,
0 /* trailer */, 40 /* frequency */};
class space_enc_data sharpEnc = {2400 /* headerMark */ , 600 /* headerSpace */,
600 /* mark0 */, 600 /* space0 */, 1200 /* mark1 */, 600 /* space1 */,
0 /* trailer */, 40 /* frequency */};
#define RC5_T1 889
#define RC5_RPT_LENGTH 46000
#define RC6_HDR_MARK 2666
#define RC6_HDR_SPACE 889
#define RC6_T1 444
#define RC6_RPT_LENGTH 46000
// Send a generic space encoded code
// The timings and frequency are in spaceEncData
void IRsend::sendSpaceEnc(unsigned long long data, int nbits, space_enc_data *spaceEncData)
{
enableIROut(spaceEncData->frequency);
mark(spaceEncData->headerMark);
space(spaceEncData->headerSpace);
data <<= (64 - nbits);
for (int i = 0; i < nbits; i++) {
if (data & TOPBIT) {
mark(spaceEncData->mark1);
space(spaceEncData->space1);
}
else {
mark(spaceEncData->mark0);
space(spaceEncData->space0);
}
data <<= 1;
}
if (spaceEncData->trailer > 0) {
mark(spaceEncData->trailer);
space(0);
}
}
void IRsend::sendNEC(unsigned long data, int nbits)
{
sendSpaceEnc(data, nbits, &necEnc);
}
void IRsend::sendSony(unsigned long data, int nbits) {
sendSpaceEnc(data, nbits, &sonyEnc);
}
void IRsend::sendRaw(unsigned int buf[], int len, int hz)
{
enableIROut(hz);
for (int i = 0; i < len; i++) {
if (i & 1) {
space(buf[i]);
}
else {
mark(buf[i]);
}
}
space(0); // Just to be sure
}
// Note: first bit must be a one (start bit)
void IRsend::sendRC5(unsigned long data, int nbits)
{
enableIROut(36);
data = data << (32 - nbits);
mark(RC5_T1); // First start bit
space(RC5_T1); // Second start bit
mark(RC5_T1); // Second start bit
for (int i = 0; i < nbits; i++) {
if (data & TOPBIT) {
space(RC5_T1); // 1 is space, then mark
mark(RC5_T1);
}
else {
mark(RC5_T1);
space(RC5_T1);
}
data <<= 1;
}
space(0); // Turn off at end
}
// Caller needs to take care of flipping the toggle bit
void IRsend::sendRC6(unsigned long data, int nbits)
{
enableIROut(36);
data = data << (32 - nbits);
mark(RC6_HDR_MARK);
space(RC6_HDR_SPACE);
mark(RC6_T1); // start bit
space(RC6_T1);
int t;
for (int i = 0; i < nbits; i++) {
if (i == 3) {
// double-wide trailer bit
t = 2 * RC6_T1;
}
else {
t = RC6_T1;
}
if (data & TOPBIT) {
mark(t);
space(t);
}
else {
space(t);
mark(t);
}
data <<= 1;
}
space(0); // Turn off at end
}
void IRsend::mark(int time) {
// Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency.
IRremoteEnablePwm();
delayMicroseconds(time);
}
/* Leave pin off for time (given in microseconds) */
void IRsend::space(int time) {
// Sends an IR space for the specified number of microseconds.
// A space is no output, so the PWM output is disabled.
IRremoteDisablePwm();
delayMicroseconds(time);
}
void IRsend::enableIROut(int khz) {
IRremoteEnableIRoutput(khz);
}