-
Notifications
You must be signed in to change notification settings - Fork 1
/
irrp_data_code05.py
456 lines (402 loc) · 15 KB
/
irrp_data_code05.py
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
#!/usr/bin/env python
# irrp.py
# 2015-12-21
# Public Domain
"""
irrp_data_code04.py
リモコンコマンド受信
プログラム一本化 使用
2020/07/27 irrp.pyを改造して、以下の機能を実現する。irrp_r_data.py
*1.受信データからrawデータを保存する。
'python3 irrp_r_data.py -r -g4 -f receive r_data --no-confirm --post 130'
起動後、receiveファイルがあれば、なくなるまで待って
無ければ、受信待ちに入る。
リモコンを受信したらファイルを作って、最初に戻る。
- 一回めはちゃんと受信データができるが、2回めからは0,がついてしまう。
2020/08/14 初期化ルーチンを繰り返しループに入れたらうまく行きました。論理はわからんけど....
*1-2 高速化のためrawデータをそのまま保存せずにコード化して保存する。
irrp_data_code01.py
削除 2.保存されたrawデータを01コードに変換する。
*3.リモコンのrawデータを事前に01コードにして保存しておく
ファイルを読み込み、01コードにして持っておく
複数ファイル対応とした。2020/08/17
*4. 01コードと受信01コードを比較して、合致するものがあれば、そのボタンを押されたと判定する。
receiveファイルを監視して、なければ、出来るまで待つ。
receiveファイルが出来れば、01コードに変換して、oso 01コードと比較して、合致すれば
そのコマンド名を取得する。
receiveファイルは読み込み後削除する。
4の最初に戻り繰り返す。
取得したコマンド名は後着優先として上書きする。
5.リモコンコマンドを処理するプログラムは、コマンドを待ち、あれば処理して削除を繰り返す。
2020/08/16 プログラム名だけで起動する様にした。
2020/08/19 プログラム一本化
2020/09/11 iR GPIOを変数設定とした。
2020/09/18 ユーザー名変更に対応
2020/10/11 iR受信時にピープ音を鳴らす
2021/03/14 LED,LED1のgpio設定が抜けていた
2021/03/30 sensorHAT用に改造
04 リモコンふぁぃるを持たずにコードを表示
2022/02/07 sensorHATのコード表示用に改造
05 GPIO iR_sensor = '4' 以外を使わないようにする
pigpiod のインストール
sudo apt-get install pigpio
コピースクリプト
scp -r remocon/irrp_data_code03.py pi@192.168.68.135:/home/pi/remocon
scp -r aircontrol pi@192.168.68.131:/home/pi
scp -r aircontrol tk@192.168.68.124:/home/tk
scp -r L_remocon/irrp_data_code03.py pi@192.168.68.128:/home/pi/L_remocon
scp -r sensorHAT/*.py pi@172.20.10.6:/home/pi/sensorHAT
"""
import csv
import sys
import time
import json
import os
import argparse
import datetime
# from nobu_LIB import Lib_OLED
# disp_size = 'SSD1306_128_32'
import pigpio # http://abyz.co.uk/rpi/pigpio/python.html
import getpass
# ユーザー名を取得
user_name = getpass.getuser()
print('user_name', user_name)
path = '/home/' + user_name + '/sensorHAT/' # cronで起動する際には絶対パスが必要
# path = '/home/' + 'tk' + '/L_remocon/' # systemdで起動する際にはrootになり絶対パスが必要
# disp_size = 32 # or 64
# iR_LED = '22'
# LED = '17'
# LED1 = '27'
iR_sensor = '4'
# beep = '6'
# beep2 = '18'
""" リモコンファイルは持たない """
# FILE=[path + 'oso']
# FILE=[path + 'ali'] # 黒地のaliリモコン
# FILE=[path + 'ali-w'] # 白地のaliリモコン
###################log print#####################
# 自身のプログラム名からログファイル名を作る
args = sys.argv
logFileName = args[0].strip(".py") + "_log.csv"
print(logFileName)
# ログファイルにプログラム起動時間を記録
# 日本語文字化けするので、Shift_jisやめてみた。
f = open(logFileName, 'a')
csvWriter = csv.writer(f)
csvWriter.writerow([datetime.datetime.now(), ' program start!!'])
f.close()
# ----------------------------------------------
def log_print(msg1="", msg2="", msg3=""):
# エラーメッセージなどをプリントする際に、ログファイルも作る
# 3つまでのデータに対応
print(msg1, msg2, msg3)
# f = open(logFileName, 'a',encoding="Shift_jis")
# 日本語文字化けするので、Shift_jisやめてみた。
f = open(logFileName, 'a')
csvWriter = csv.writer(f)
csvWriter.writerow([datetime.datetime.now(), msg1, msg2, msg3])
f.close()
################################################
GPIO = int(iR_sensor) # args.gpio
# FILE = 'プログラムで決定' #args.file
GLITCH = 100 # args.glitch
PRE_MS = 200 # args.pre
POST_MS = 130 # args.post
FREQ = 38 # args.freq
VERBOSE = False # args.verbose
SHORT = 20 # args.short
GAP_MS = 100 # args.gap
NO_CONFIRM = True # args.no_confirm
TOLERANCE = 15 # args.tolerance
def carrier(gpio, frequency, micros):
# キャリア方形波を生成します。
wf = []
cycle = 1000.0 / frequency
cycles = int(round(micros/cycle))
on = int(round(cycle / 2.0))
sofar = 0
for c in range(cycles):
target = int(round((c+1)*cycle))
sofar += on
off = target - sofar
sofar += off
wf.append(pigpio.pulse(1 << gpio, 0, on))
wf.append(pigpio.pulse(0, 1 << gpio, off))
return wf
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 = {}
for rec in records:
rl = len(records[rec])
for i in range(base, rl, 2):
if records[rec][i] in ms:
ms[records[rec][i]] += 1
else:
ms[records[rec][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)
for rec in records:
rl = len(records[rec])
for i in range(base, rl, 2):
records[rec][i] = ms[records[rec][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()
def number_of_1(receive_s, st_start=0):
# 与えられた文字列の最初の区切りを数字にして返します。
# 数字にした文字列は与えられた文字列から削除して返します。
st_end = receive_s.find(", ")
# print(st_start,st_end)
result_s = receive_s[st_start:st_end]
# print(result_s)
result = int(result_s)
# print(result)
receive_s = receive_s[st_end+1:]
# print(receive_s)
return result, receive_s
def rawTocode(receive):
# raw Data 一つ分をcodeに変換します。
# コマンド名を切り出す
command = receive[receive.find('"')+1:receive.find("[")-3]
# log_print(command)
# print('[ ] の間の文字列を切り出す')
receive_s = receive[receive.find("[")+1:receive.find("]")]
# print(receive_s)
# 数字の数を数える
n = receive[receive.find("[")+1:receive.find("]")].count(',')+1
# print(n)
# 最後の数字を取り出せる様にスペースを追加
receive_s = receive_s + ' '
# 文字列の頭から順に数字に変換していく rawデータの取り出し
number = []
for i in range(n):
result, receive_s = number_of_1(receive_s, st_start=0)
# print(result)
if result > 300 and result < 800:
number.append(1)
if result > 700 and result < 1700:
number.append(3)
# rawデータからcodeデータに変換する。
code = ''
err = 0
if len(number) % 2 != 0:
err = -1
for i in range(0, len(number) + err, 2):
# print(i)
if number[i] == 1:
if number[i+1] == 1:
code += '0'
if number[i+1] == 3:
code += '1'
else:
# print('err')
pass
return command, code
# def main():
while True:
code_data = []
command = []
records = {}
# 受信待ちに入る。
# pi = pigpio.pi() # Connect to Pi.
while True:
POST_US = POST_MS * 1000
PRE_US = PRE_MS * 1000
GAP_S = GAP_MS / 1000.0
CONFIRM = not NO_CONFIRM
TOLER_MIN = (100 - TOLERANCE) / 100.0
TOLER_MAX = (100 + TOLERANCE) / 100.0
last_tick = 0
in_code = False
code = []
fetching_code = False
pi = pigpio.pi() # Connect to Pi.
if not pi.connected:
print("GPIO noconnect")
exit(0)
# # beep音設定
# beep = int(beep)
# pi.set_mode(beep, pigpio.OUTPUT)
# pi.write(beep, 0) # beep off
# # beep2音設定 音声再生の代わり
# beep2 = int(beep2)
# pi.set_mode(beep2, pigpio.OUTPUT)
# pi.write(beep2, 0) # beep off
# LED = int(LED)
# LED1 = int(LED1)
# pi.set_mode(LED, pigpio.OUTPUT)
# pi.set_mode(LED1, pigpio.OUTPUT)
# pi.write(LED, 1) # beep on
# time.sleep(0.05)
# pi.write(LED, 0) # beep off
# 赤外線センサーのデータを待ち、くれば読み取る
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)
for arg in ['r_data']:
print('Plese Press key ')
code = []
fetching_code = True
while fetching_code:
time.sleep(0.1)
print("Okay")
time.sleep(0.1)
if CONFIRM:
press_1 = code[:]
done = False
tries = 0
while not done:
# print("Press key for '{}' to confirm".format(arg))
print('Plese Press key ')
code = []
fetching_code = True
while fetching_code:
time.sleep(0.1)
press_2 = code[:]
the_same = compare(press_1, press_2)
if the_same:
done = True
records[arg] = press_1[:]
print("Okay")
time.sleep(0.5)
else:
tries += 1
if tries <= 3:
print("No match")
else:
print("Giving up on key '{}'".format(arg))
done = True
time.sleep(0.1)
else: # No confirm.
records[arg] = code[:]
pi.set_glitch_filter(GPIO, 0) # Cancel glitch filter.
pi.set_watchdog(GPIO, 0) # Cancel watchdog.
tidy(records)
# print('command receive!!')
# intリストを文字列に変換する。
result = ", ".join(map(str, records['r_data']))
print(result)
result = '{"receive": [' + result + '],}'
# print(result)
R_command, R_code = rawTocode(result)
print('code=', R_code, ' code-len=', len(R_code))
try:
R_code = R_code[7:30] # 頭8,尻尾2文字削る ap_remocon
# R_code = R_code[7:-1] #頭8,尻尾2文字削る oso
except:
pass
print('code=', R_code, ' code-len=', len(R_code))
# print(R_command , R_code)
# print()
j = 0
with open(path + 'iR_command.txt', mode='w') as f: # 上書き
f.write(R_code)
# -----------------------------
# log_print(R_code)
# -------------------------------------------
try:
# なぜかたまにここでエラーになることがある
pi.stop() # Disconnect from Pi.
except:
log_print('pi.stop() エラー 1 ***********')
time.sleep(1)
try:
pi.stop()
except:
log_print('pi.stop() エラー 2 ************')
time.sleep(1)
pi.stop()
# -------------------------------------------