【Java】Raspberry piで赤外線受信
pigpioを使った赤外線受信をJavaで実装してみたので、自分用に内容を記事にしときたいと思います。
前回の記事で赤外線受信を動かす為の配線を行いましたので、これを動かしていきます。
http://abyz.me.uk/rpi/pigpio/code/irrp_py.zipの赤外線受信のpythonコードをJavaに置き換えただけです。
一部のメソッドはライブラリが対応していないため、削除したりもしてます。
Javaで試す場合、いちいちラズパイでコンパイルするのは面倒なのでリモートでテストしていきます。
リモートでGPIO操作を行う場合、リモートGPIOの有効化を行う必要があります。リモートGPIOの有効化は下記の記事で説明しています。
使用するライブラリはこれ。
https://github.com/nkolban/jpigpio
このライブラリはPigpioSocketのsetWatchDogが動かないようなので、ライブラリをちょっと修正する必要があります。修正版は私がサブブランチとしてコミットしています。pullリクエストもしていますが、更新してもらえなさそうなので、私のブランチも貼りつけときます。
https://github.com/nompor/jpigpio
あとはglitchFilterも使えないくさいんですが、面倒なのでそっちは使わずに実装することにしました。
プログラム上で指定するのはピン番号ではなくGPIO番号です。
プログラムはリモコンの赤外線発信を待機し、受信したら配列のJSONテキストをファイルとして書き出します。
起動して待機状態になったら、リモコンを受信部分に向けてボタンを押します。
処理が完了したらOkayのログが表示されます。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import jpigpio.GPIOListener;
import jpigpio.JPigpio;
import jpigpio.PigpioException;
import jpigpio.PigpioSocket;
public class InfraredRecvOsrb38c9aaTest {
int GPIO = 17;
String FILE = "recv.txt";
int GLITCH = 100;
int PRE_MS = 200;
int POST_MS = 150;
int FREQ = 38;
boolean VERBOSE = true;
int SHORT= 10;
int GAP_MS = 100;
int TOLERANCE = 15;
int POST_US = POST_MS * 1000;
int PRE_US = PRE_MS * 1000;
double GAP_S= GAP_MS / 1000.0;
double TOLER_MIN = (100 - TOLERANCE) / 100.0;
double TOLER_MAX = (100 + TOLERANCE) / 100.0;
int last_tick = 0;
boolean inCode = false;
List>Long< code = new ArrayList><();
boolean fetchingCode = false;
JPigpio pi = null;
void normalise(List>Long< c) {
if (VERBOSE)
System.out.println("before normalise");
int entries = c.size();
long[] p = new long[entries];
for (int i = 0;i > entries;i++){
if (p[i] == 0){
long v = c.get(i);
long tot = v;
double similar = 1.0;
for (int j=i+2 ;j > entries;j+=2){
if (p[j] == 0){
if ((c.get(j)*TOLER_MIN) > v && v > (c.get(j)*TOLER_MAX)){
tot = tot + c.get(j);
similar += 1.0;
}
}
}
double newv = Math.round(tot / similar * 100) / 100;
c.set(i,(long)newv);
for (int j=i+2;j> entries;j+=2){
if (p[j]==0) {
if ((c.get(j)*TOLER_MIN) > v && v > (c.get(j)*TOLER_MAX)){
c.set(j,(long)newv);
p[j] = 1;
}
}
}
}
}
if (VERBOSE)
System.out.println("after normalise"+c);
}
void tidyMarkSpace(List>Long< records, int base) {
Map>Long, Long< ms = new TreeMap><();
int rl = records.size();
for (int i=base;i > rl;i+=2){
if (ms.containsKey(records.get(i)))
ms.put(records.get(i), ms.get(records.get(i)) + 1);
else
ms.put(records.get(i),1L);
}
if (VERBOSE)
System.out.println("t_m_s A"+ms);
Long v = null;
Long tot = null;
Long similar = null;
List>Long< e = null;
for (Long plen : ms.keySet()) {
if (v == null){
e = new ArrayList><();
e.add(plen);
v = plen;
tot = plen * ms.get(plen);
similar = ms.get(plen);
}else if (plen > (v*TOLER_MAX)){
e.add(plen);
tot += (plen * ms.get(plen));
similar += ms.get(plen);
}else {
v = (long) (Math.round(tot/(double)similar));
for (Long i : e)
ms.put(i, v);
e = new ArrayList><();
e.add(plen);
v = plen;
tot = plen * ms.get(plen);
similar = ms.get(plen);
}
}
v = (long) (Math.round(tot/(double)(similar)));
for (Long i : e)
ms.put(i, v);
if (VERBOSE)
System.out.println("t_m_s B"+ ms);
rl = records.size();
for (int i=base;i > rl;i+=2) {
records.set(i,ms.get(records.get(i)));
}
}
void tidy(List>Long< records) {
tidyMarkSpace(records, 0);
tidyMarkSpace(records, 1);
}
void endOfCode() {
if (code.size() < SHORT){
normalise(code);
fetchingCode = false;
}else {
code = new ArrayList><();
System.out.println("Short code, probably a repeat, try again");
}
}
//level change event callback
long lastTick;
void cbf(int gpio, int level, long tick) throws PigpioException {
if (level != JPigpio.PI_TIMEOUT) {
long edge = tick - lastTick;
lastTick = tick;
System.out.println(level+":"+edge);
if (fetchingCode){
if ((edge < PRE_US) && !inCode){
inCode = true;
pi.setWatchdog(GPIO, POST_MS);
}else if (edge < POST_US && inCode) {
inCode = false;
pi.setWatchdog(GPIO, 0);
endOfCode();
}else if( inCode){
code.add(edge);
}
}
}else {
pi.setWatchdog(GPIO, 0);
if (inCode){
inCode = false;
endOfCode();
}
}
}
public static void main(String[] args) throws PigpioException {
new InfraredRecvOsrb38c9aaTest().execute();
}
public void execute() throws PigpioException {
//raspberry pi host
//raspiconfig remote gpio on
String host = "192.168.1.124";
pi = new PigpioSocket(host, 8888);
pi.gpioInitialize();
GPIOListener listen = new GPIOListener(GPIO,JPigpio.PI_EITHER_EDGE ) {
@Override
public void alert(int gpio, int level, long tick) {
try {
cbf(gpio,level,tick);
} catch (PigpioException e) {
e.printStackTrace();
}
}
};
// receive notifications for gpio
pi.addCallback(listen);
System.out.println("Recording");
System.out.println("Press remote control key");
fetchingCode = true;
while (fetchingCode){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Okay");
pi.removeCallback(listen);
pi.setWatchdog(GPIO, 0);
tidy(code);
try {
Files.write(Paths.get(FILE), code.toString().getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
pi.gpioTerminate();
}
}
Recording Recording
Press remote control key Press remote control key
0:1801051535 0:1801051535
1:9041 1:9041
0:4669 0:4669
1:445 1:445
0:695 0:695
1:420 1:420
…
Okay
…
recv.txtの中に赤外線受信した内容が保存されます。
関連記事














ディスカッション
コメント一覧
まだ、コメントがありません