【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の中に赤外線受信した内容が保存されます。
関連記事
ディスカッション
コメント一覧
まだ、コメントがありません