-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathir.c
122 lines (97 loc) · 2.93 KB
/
ir.c
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
#include <ruby.h>
#include <wiringPi.h>
#define LOW_STATE 0
#define HIGH_STATE 1
#define SOFTWARE_SUBCARRIER 0
const int IRledPin = 1;//18; //BCM18, wPi1
const int IRrecvPin = 7;//4; //BCM4, wPi7
void sendIr(int irData[], int length){
int i;
delayMicrosecondsHard(50);
for(i=0;i<length;i++){
if(i%2 == 0){ //奇数データ目でON
#if SOFTWARE_SUBCARRIER
#warning Subcarrier are generated by software.
int microsecs = irData[i];
while (microsecs > 6) {
// 38 kHz is about 13 microseconds high and 13 microseconds low
digitalWrite(IRledPin, HIGH); // this takes about 2 microseconds to happen
delayMicrosecondsHard(7); // hang out for 11 microseconds
digitalWrite(IRledPin, LOW); // this also takes about 2 microseconds
delayMicrosecondsHard(16); // hang out for 11 microseconds
microsecs -= 26;
}
#else
#warning External subcarrier is needed.
digitalWrite(IRledPin, HIGH);
delayMicrosecondsHard(irData[i]);
digitalWrite(IRledPin, LOW);
#endif
}else{ //偶数データ目なら待つ
delayMicrosecondsHard(irData[i]);
}
}
digitalWrite(IRledPin, LOW); //fail-safe
}
VALUE readIr() {
VALUE ret = rb_ary_new();
while(digitalRead(IRrecvPin) == HIGH_STATE); // HIGHなら待ち続ける
unsigned int lastChanged = micros();
unsigned int now = 0;
// 信号が来ている間はLOW(0)
int lastSignal = LOW_STATE; //LOWなはず
while(1){
if(lastSignal == HIGH_STATE){
while(digitalRead(IRrecvPin) == HIGH_STATE){
if(micros() - lastChanged > 1000000){ //1秒以上HIGHのままだったら終わり
return ret;
}
}
}else{
while(digitalRead(IRrecvPin) == LOW_STATE);
}
// 現在時刻を保存
now = micros();
// 信号のオンオフが変化するまでにかかった時間(マイクロ秒)を記録
rb_ary_push(ret, INT2FIX(now-lastChanged));
// 次の変化までの時間を計測できるよう準備
lastChanged = now;
if(lastSignal == HIGH_STATE){
lastSignal = LOW_STATE;
} else {
lastSignal = HIGH_STATE;
}
}
}
VALUE meth_initialize(){
if (wiringPiSetup() == -1){
rb_raise(rb_eFatal, "Couldn't setup wiringPi");
}
pinMode(IRledPin, OUTPUT);
pinMode (IRrecvPin, INPUT);
delayMicrosecondsHard(25000);
return Qnil;
}
VALUE meth_sendIr(VALUE self, volatile VALUE varr){
int length = RARRAY_LEN(varr);
int i;
Check_Type(varr, T_ARRAY);
int arr[length];
for(i=0; i<length; i++){
VALUE vval = rb_ary_entry(varr,i);
int val = NUM2INT(vval);
arr[i] = val;
}
sendIr(arr, length);
return Qnil;
}
VALUE meth_recvIr(VALUE self){
return readIr();
}
void Init_IR(void){
VALUE rb_cIR;
rb_cIR = rb_define_class("IR", rb_cObject);
rb_define_private_method(rb_cIR, "initialize", meth_initialize, 0);
rb_define_method(rb_cIR, "sendIr", meth_sendIr, 1);
rb_define_method(rb_cIR, "recvIr", meth_recvIr, 0);
}