【Python】Raspberry Piで赤外線受信
pigpioを使った赤外線受信をPythonで実装してみたので、自分用に内容を記事にしときたいと思います。
前回の記事で赤外線受信を動かす為の配線を行いましたので、これを動かしていきます。
http://abyz.me.uk/rpi/pigpio/code/irrp_py.zipの赤外線受信のPythonコードを流用して赤外線受信専用にしてます。
プログラム上で指定するのはピン番号ではなくGPIO番号です。
プログラムはリモコンの赤外線発信を待機し、受信したら配列のJSONテキストをファイルとして書き出します。
起動して待機状態になったら、リモコンを受信部分に向けてボタンを押します。
処理が完了したらOkayのログが表示されます。
import time import json import os import argparse import pigpio GPIO = 17 FILE = "recv.txt" GLITCH = 100 PRE_MS = 200 POST_MS = 150 FREQ = 38 VERBOSE = False SHORT = 10 GAP_MS = 100 TOLERANCE = 15 POST_US = POST_MS * 1000 PRE_US = PRE_MS * 1000 GAP_S = GAP_MS / 1000.0 TOLER_MIN = (100 - TOLERANCE) / 100.0 TOLER_MAX = (100 + TOLERANCE) / 100.0 last_tick = 0 in_code = False code = [] fetching_code = False def normalise(c): if VERBOSE: print("before normalise", c) entries = len(c) p = [0]*entries # Set all entries not processed. for i in range(entries): if not p[i]: # Not processed? v = c[i] tot = v similar = 1.0 # Find all pulses with similar lengths to the start pulse. for j in range(i+2, entries, 2): if not p[j]: # Unprocessed. if (c[j]*TOLER_MIN) < v < (c[j]*TOLER_MAX): # Similar. tot = tot + c[j] similar += 1.0 # Calculate the average pulse length. newv = round(tot / similar, 2) c[i] = newv # Set all similar pulses to the average value. for j in range(i+2, entries, 2): if not p[j]: # Unprocessed. if (c[j]*TOLER_MIN) < v < (c[j]*TOLER_MAX): # Similar. c[j] = newv p[j] = 1 if VERBOSE: print("after normalise", c) def compare(p1, p2): if len(p1) != len(p2): return False for i in range(len(p1)): v = p1[i] / p2[i] if (v < TOLER_MIN) or (v > TOLER_MAX): return False for i in range(len(p1)): p1[i] = int(round((p1[i]+p2[i])/2.0)) if VERBOSE: print("after compare", p1) return True def tidy_mark_space(records, base): ms = {} # Find all the unique marks (base=0) or spaces (base=1) # and count the number of times they appear, rl = len(records) for i in range(base, rl, 2): if records[i] in ms: ms[records[i]] += 1 else: ms[records[i]] = 1 if VERBOSE: print("t_m_s A", ms) v = None for plen in sorted(ms): if v == None: e = [plen] v = plen tot = plen * ms[plen] similar = ms[plen] elif plen < (v*TOLER_MAX): e.append(plen) tot += (plen * ms[plen]) similar += ms[plen] else: v = int(round(tot/float(similar))) # set all previous to v for i in e: ms[i] = v e = [plen] v = plen tot = plen * ms[plen] similar = ms[plen] v = int(round(tot/float(similar))) # set all previous to v for i in e: ms[i] = v if VERBOSE: print("t_m_s B", ms) rl = len(records) for i in range(base, rl, 2): records[i] = ms[records[i]] def tidy(records): tidy_mark_space(records, 0) # Marks. tidy_mark_space(records, 1) # Spaces. def end_of_code(): global code, fetching_code if len(code) > SHORT: normalise(code) fetching_code = False else: code = [] print("Short code, probably a repeat, try again") def cbf(gpio, level, tick): global last_tick, in_code, code, fetching_code if level != pigpio.TIMEOUT: edge = pigpio.tickDiff(last_tick, tick) last_tick = tick if fetching_code: if (edge > PRE_US) and (not in_code): # Start of a code. in_code = True pi.set_watchdog(GPIO, POST_MS) # Start watchdog. elif (edge > POST_US) and in_code: # End of a code. in_code = False pi.set_watchdog(GPIO, 0) # Cancel watchdog. end_of_code() elif in_code: code.append(edge) else: pi.set_watchdog(GPIO, 0) # Cancel watchdog. if in_code: in_code = False end_of_code() pi = pigpio.pi() # Connect to Pi. if not pi.connected: exit(0) try: f = open(FILE, "r") records = json.load(f) f.close() except: records = [] pi.set_mode(GPIO, pigpio.INPUT) # IR RX connected to this GPIO. pi.set_glitch_filter(GPIO, GLITCH) # Ignore glitches. cb = pi.callback(GPIO, pigpio.EITHER_EDGE, cbf) # Process each id print("Recording") print("Press remote control key") code = [] fetching_code = True while fetching_code: time.sleep(0.1) print("Okay") time.sleep(0.5) records = code[:] pi.set_glitch_filter(GPIO, 0) # Cancel glitch filter. pi.set_watchdog(GPIO, 0) # Cancel watchdog. tidy(records) f = open(FILE, "w") f.write(json.dumps(records, sort_keys=True).replace("],", "],\n")+"\n") f.close() pi.stop() # Disconnect from Pi.
Recording
Press remote control key
Okay
recv.txtの中に赤外線受信した内容が保存されます。
元のPythonコードが出来上がっているので、いちいち改変しなくても良いのですが、このコードを流用して汎用的なことをできるようにしたかったので、ある程度処理の流れだけでもつかむために改変しました。ちょっとでも弄っておくと後で応用しやすくなるんでね。
関連記事
ディスカッション
コメント一覧
まだ、コメントがありません