-
Notifications
You must be signed in to change notification settings - Fork 1
/
irt.ts
142 lines (126 loc) · 4.19 KB
/
irt.ts
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
// MakeCode blocks for sending commands using an IR LED
/**
* MakeCode extension for IR Kit
*/
//% weight=9 color=#0F8AAE icon="\uf14C" block="Hackbit IR"
//% category="IR Kit"
namespace hackbitIR {
let irLed: InfraredLed;
class InfraredLed {
private pin: AnalogPin;
private waitCorrection: number;
constructor(pin: AnalogPin) {
this.pin = pin;
pins.analogWritePin(this.pin, 0);
pins.analogSetPeriod(this.pin, 26);
// Measure the time we need for a minimal bit (analogWritePin and waitMicros)
{
const start = input.runningTimeMicros();
const runs = 32;
for (let i = 0; i < runs; i++) {
this.transmitBit(1, 1);
}
const end = input.runningTimeMicros();
this.waitCorrection = Math.idiv(end - start - runs * 2, runs * 2);
}
// Insert a pause between callibration and first message
control.waitMicros(2000);
}
public transmitBit(highMicros: number, lowMicros: number): void {
pins.analogWritePin(this.pin, 511);
control.waitMicros(highMicros);
pins.analogWritePin(this.pin, 1);
control.waitMicros(lowMicros);
}
public sendNec(hex32bit: string): void {
if (hex32bit.length != 10) {
return;
}
const NEC_HDR_MARK = 9000 - this.waitCorrection;
const NEC_HDR_SPACE = 4500 - this.waitCorrection;
const NEC_BIT_MARK = 560 - this.waitCorrection + 50;
const NEC_HIGH_SPACE = 1690 - this.waitCorrection - 50;
const NEC_LOW_SPACE = 560 - this.waitCorrection - 50;
// Decompose 32bit HEX string into two manageable 16 bit numbers
const addressSection = parseInt(hex32bit.substr(0, 6));
const commandSection = parseInt("0x" + hex32bit.substr(6, 4));
const sections = [addressSection, commandSection];
// send the header
this.transmitBit(NEC_HDR_MARK, NEC_HDR_SPACE);
// send the address and command bits
sections.forEach((section) => {
let mask = 1 << 15;
while (mask > 0) {
if (section & mask) {
this.transmitBit(NEC_BIT_MARK, NEC_HIGH_SPACE);
} else {
this.transmitBit(NEC_BIT_MARK, NEC_LOW_SPACE);
}
mask >>= 1;
}
});
// mark the end of transmission
this.transmitBit(NEC_BIT_MARK, 0);
}
}
/**
* Connects to the IR-emitting LED at the specified pin.
* @param pin IR LED pin, eg: AnalogPin.P0
*/
//% subcategory="IR Sender"
//% blockId="hackbit_infrared_sender_connect"
//% block="connect IR sender LED at pin %pin"
//% pin.fieldEditor="gridpicker"
//% pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false"
//% weight=90
//% color=#0F8AAE
export function connectIrSenderLed(pin: AnalogPin): void {
irLed = new InfraredLed(pin);
}
/**
* Sends a 32bit IR datagram using the NEC protocol.
* @param hex32bit a 32bit hex string, eg: 0x00FF02FD
*/
//% subcategory="IR Sender"
//% blockId="hackbit_infrared_sender_send_datagram"
//% block="send IR datagram %hex32bit"
//% weight=80
//% color=#0F8AAE
export function sendIrDatagram(hex32bit: string): void {
if (!irLed) {
return;
}
irLed.sendNec(hex32bit);
}
/**
* Returns an NEC IR datagram as a 32bit hex string.
* @param address an 8bit address, eg. 0
* @param command an 8bit command, eg. 2
*/
//% subcategory="IR Sender"
//% blockId=hackbit_infrared_sender_nec_datagram
//% block="address %address | command %command"
//% address.min=0 address.max=255
//% command.min=0 command.max=255
//% weight=56
//% color=#0F8AAE
export function irNec(address: number, command: number): string {
const addrSection = ((address & 0xff) << 8) | (~address & 0xff);
const cmdSection = ((command & 0xff) << 8) | (~command & 0xff);
return "0x" + to16BitHex(addrSection) + to16BitHex(cmdSection);
}
function to16BitHex(value: number): string {
let hex = "";
for (let pos = 0; pos < 4; pos++) {
let remainder = value % 16;
if (remainder < 10) {
hex = remainder.toString() + hex;
} else {
hex = String.fromCharCode(55 + remainder) + hex;
}
value = Math.idiv(value, 16);
}
return hex;
}
}