今兒學堂的氣氛頗不尋常,不見往日課前之嘻笑打鬧,正三五成群的討論紅外線控制種種以及入出針文法擴張等等的哩!
學長來了,看了看沒進教室,卻招手將我喚到室外,說道︰
同學們能主動學習很好,今天就不上課了。妳帶著大家研習,要是真的碰到了疑難,那時我再來。如果同學問起,就說我有事請假,晚點才能到校,請大家先行自習。
派︰☿ 長︰同學們請安靜。學長告知︰上午有事請假,請大家先行自習。既然昨日的討論,意猶未盡,何不今早大家就
輪番上陣講習,彼此觀摩,溝通想法。為著下午的 會 習,也來個 會外會的耶!……【鼓掌通過】
於此特寫一致同意的若干事項︰
正式將入出針程式命名為『TuxIOme』── Tux [GP]IO m[achin]e ──,啟始時數碼管顯示『 -| |- -| |- 』,意味井井相通,友情長存 。
【量系統溫度】
入出針文法增加系統溫度讀取,語法
系統溫度
,使用『 vcgencmd measure_temp 』傳回攝氏溫度浮點 數值。
建置範例︰
>>> import subprocess >>> import shlex >>> command_line = "vcgencmd measure_temp" >>> shlex.split(command_line) ['vcgencmd', 'measure_temp'] >>> t = subprocess.call(['vcgencmd', 'measure_temp']) temp=53.5'C >>> t 0 >>> t = subprocess.check_output(['vcgencmd', 'measure_temp']) >>> t b"temp=54.1'C\n" >>> >>> T = t.decode('utf-8') >>> T "temp=54.1'C\n" >>> >>> T.find('=') 4 >>> T.find("'") 9 >>> T[4-9] '.' >>> T[4] '=' >>> T[9] "'" >>> T[5:9] '54.1' >>> >>> TT = float(T[5:9]) >>> TT 54.1 >>>
17.5. subprocess — Subprocess management
【亂數隨選芻議】
random.choice(seq)
Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.
規劃增添一個亂數產生的語法。使之可用於入出針隨選,或是其它用途。
【執行緒結束法確證】
實務確證了將『 daemon 』設定為 True ,執行緒隨程式正常結束。
……
△ LIRC 紅外線發射︰
IRSEND
NAME
irsend – basic LIRC program to send infra-red commands
SYNOPSIS
irsend [options] DIRECTIVE REMOTE CODE [CODE…]
DESCRIPTION
Asks the lircd daemon to send one or more CIR (Consumer Infra-Red) commands. This is intended for remote control of electronic devices such as TV boxes, HiFi sets, etc.
DIRECTIVE can be:
- SEND_ONCE – send CODE [CODE …] once SEND_START – start repeating CODE SEND_STOP – stop repeating CODE LIST – list configured remote items SET_TRANSMITTERS – set transmitters NUM [NUM …] SIMULATE – simulate IR event
REMOTE is the name of a remote, as described in the lircd configuration file.
CODE is the name of a remote control key of REMOTE, as it appears in the lircd configuration file.
NUM is the transmitter number of the hardware device.
For the LIST DIRECTIVE, REMOTE and/or CODE can be empty:
- LIST “” “” – list all configured remote names LIST REMOTE “” – list all codes of REMOTE LIST REMOTE CODE – list only CODE of REMOTE
The SIMULATE command only works if it has been explicitly enabled in lircd.
OPTIONS
- -h –help
- display usage summary
- -v –version
- display version
- -d –device
- use given lircd socket [/var/run/lirc/lircd]
- -a –address=host[:port]
- connect to lircd at this address
- -# –count=n
- send command n times
ENVIRONMENT
- LIRC_SOCKET_PATH
- The lircd socket to connect to, defaults to a hardcoded default value usually /var/run/lirc/lircd
FILES
- /etc/lirc/lircd.conf
- Default lircd configuration file. It should contain all the remotes, their infra-red codes and the corresponding timing and waveform details.
DIAGNOSTICS
If lircd is not running (or /var/run/lirc/lircd lacks write permissions) irsend aborts with the following diagnostics:
"irsend: could not connect to socket" "irsend: Connection refused" (or "Permission denied").
EXAMPLES
- irsend LIST DenonTuner “”
- irsend SEND_ONCE DenonTuner PROG-SCAN
- irsend SEND_ONCE OnkyoAmpli VOL-UP VOL-UP VOL-UP VOL-UP
- irsend SEND_START OnkyoAmpli VOL-DOWN ; sleep 3 irsend SEND_STOP OnkyoAmpli VOL-DOWN
- irsend SET_TRANSMITTERS 1
- irsend SET_TRANSMITTERS 1 3 4
- irsend SIMULATE “0000000000000476 00 OK TECHNISAT_ST3004S”
DRIVER LOADING
Drivers are loaded dynamically. The directory used for this is determined by (falling priority):
- – The ‘plugindir’ entry in the [lircd] section of the lirc_options.conf file.
- – The environment variable LIRC_PLUGINDIR.
- – A hardcoded default (usually /usr/lib[64]/lirc/plugins).
△ 派生之 LIRC 程式庫︰
python-lirc 1.2.1
Python bindings for LIRC.
python-lirc
===========
LIRC extension written in Cython for Python 3 (and 2). I’m trying to get this into
[Debian]http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=Bug%23718980
[PyPI]https://pypi.python.org/pypi/python-lirc/
Install
=======
`python-lirc` is in the main repositories for Raspbian. If you’re on a
RaspberryPi you can just run:
sudo dpkg -i python3-lirc_1.2.1-1_all.deb
Configure
=========
You need a valid [lircrc configuration file]http://www.lirc.org/html/configure.html#lircrc_format) For example:
python3
>>> import lirc
>>> sockid = lirc.init(“myprogram”)
>>> lirc.nextcode() # press 1 on remote after this
[‘one’, ‘horse’]
>>> lirc.deinit()
Load custom configurations with:
>>> sockid = lirc.init(“myprogram”, “mylircrc”)
>>> lirc.load_config_file(“another-config-file”) # subsequent configs
Set whether `nextcode` blocks or not with:
>>> sockid = lirc.init(“myprogram”, blocking=False)
>>> lirc.set_blocking(True, sockid) # or this
……
△ 依據決議新增的 lircrc 檔案︰
pi@raspberrypi ~ ] 遲延 = 0.012 # 數碼管 四位數碼管位選一 = 17 四位數碼管位選二 = 27 四位數碼管位選三 = 22 四位數碼管位選四 = 10 LEDA = 21 LEDB = 16 LEDC = 19 LEDD = 6 LEDE = 5 LEDF = 20 LEDG = 26 LEDH = 13 # 初始態 GPIO.setup(四位數碼管位選一, GPIO.OUT, initial=關) GPIO.setup(四位數碼管位選二, GPIO.OUT, initial=關) GPIO.setup(四位數碼管位選三, GPIO.OUT, initial=關) GPIO.setup(四位數碼管位選四, GPIO.OUT, initial=關) GPIO.setup(LEDA, GPIO.OUT, initial=滅) GPIO.setup(LEDB, GPIO.OUT, initial=滅) GPIO.setup(LEDC, GPIO.OUT, initial=滅) GPIO.setup(LEDD, GPIO.OUT, initial=滅) GPIO.setup(LEDE, GPIO.OUT, initial=滅) GPIO.setup(LEDF, GPIO.OUT, initial=滅) GPIO.setup(LEDG, GPIO.OUT, initial=滅) GPIO.setup(LEDH, GPIO.OUT, initial=滅) def 數碼管執行緒(): global 數碼賦值 global 遲延 數碼管 = [LEDA, LEDB, LEDC, LEDD, LEDE, LEDF, LEDG, LEDH] while True : for 單元 in range(0,4): if 單元 == 0 : GPIO.output(四位數碼管位選一, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選一, 關) if 單元 == 1 : GPIO.output(四位數碼管位選二, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選二, 關) if 單元 == 2 : GPIO.output(四位數碼管位選三, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選一, 關) if 單元 == 1 : GPIO.output(四位數碼管位選二, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選二, 關) if 單元 == 2 : GPIO.output(四位數碼管位選三, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選三, 關) if 單元 == 3 : GPIO.output(四位數碼管位選四, 開) GPIO.output(數碼管, 數碼賦值[單元]) sleep(0.002) GPIO.output(四位數碼管位選四, 關) sleep(遲延) 數碼緒 = threading.Thread(name="數碼", target=數碼管執行緒) 數碼緒.daemon = True 數碼緒.start() 數碼管輸出字典 = { "0" : (亮, 亮, 亮, 亮, 亮, 亮, 滅, 滅) , "1" : (滅, 亮, 亮, 滅, 滅, 滅, 滅, 滅) , "2" : (亮, 亮, 滅, 亮, 亮, 滅, 亮, 滅) , "3" : (亮, 亮, 亮, 亮, 滅, 滅, 亮, 滅) , "4" : (滅, 亮, 亮, 滅, 滅, 亮, 亮, 滅) , "5" : (亮, 滅, 亮, 亮, 滅, 亮, 亮, 滅) , "6" : (亮, 滅, 亮, 亮, 亮, 亮, 亮, 滅) , "7" : (亮, 亮, 亮, 滅, 滅, 滅, 滅, 滅) , "8" : (亮, 亮, 亮, 亮, 亮, 亮, 亮, 滅) , "9" : (亮, 亮, 亮, 亮, 滅, 亮, 亮, 滅) , } def 輸出數碼管(數據) : global 數碼賦值 global 數碼管輸出字典 if 數據 > 999.9 : return "數值超過 999.9" else: 字符串 = "%05.1f" %數據 for 單元 in range(0,5): if 單元 == 0 : 數碼賦值[單元] = 數碼管輸出字典[字符串[單元]] elif 單元 == 1 : 數碼賦值[單元] = 數碼管輸出字典[字符串[單元]] elif 單元 == 2 : 暫列 = list(數碼管輸出字典[字符串[單元]]) 暫列[7] = 亮 數碼賦值[單元] = tuple(暫列) elif 單元 == 3 : continue else: 數碼賦值[單元 - 1] = 數碼管輸出字典[字符串[單元]] return "完成" GPIO.setup(11, GPIO.OUT, initial=GPIO.HIGH) 小哨子 = GPIO.PWM(11, 130.8) def 啟動蜂鳴器(): 小哨子.start(100) return "蜂鳴器已啟動" def 響聲控制(頻率): 小哨子.ChangeFrequency(頻率) 小哨子.start(50) return 頻率 def 噤聲控制(頻率): 小哨子.ChangeFrequency(頻率) 小哨子.start(100) return "噤聲" def 控制蜂鳴器(op): return { '響聲' : 響聲控制, '禁音' : 噤聲控制, }[op] def 輸入符碼(針碼): return GPIO.input(針碼) def 輸出符碼(針碼, 賦值): GPIO.output(針碼, 賦值) return "輸出" + str(賦值) def 出入定義(針碼, 入出): if 入出 == "出" : GPIO.setup(針碼, GPIO.OUT, initial = GPIO.HIGH) else: GPIO.setup(針碼, GPIO.IN, pull_up_down = GPIO.PUD_UP) return "定義完成" def 出針定義(針碼): GPIO.setup(針碼, GPIO.OUT, initial = GPIO.HIGH) return "定義輸出完成" def 入針定義(針碼): GPIO.setup(針碼, GPIO.IN, pull_up_down = GPIO.PUD_UP) return "定義輸入完成" def 入出針定義(op): return { '入針' : 入針定義, '出針' : 出針定義, }[op] import subprocess 重複次數 = 1 def 紅外線輸出(字碼): global 重複次數 subprocess.call(['irsend', 'SEND_ONCE', '/home/pi/lircd.conf', 字碼,"--count=" +str(重複次數) ]) return "已送出" import lirc sockid = lirc.init("TuxIOme", blocking=False) def 紅外線輸入(): return lirc.nextcode() def 讀取系統溫度(): t = subprocess.check_output(['vcgencmd', 'measure_temp']) T = t.decode('utf-8') Tb = T.find('=') Te = T.find("'") return float(T[Tb + 1 : Te]) class 實習機板(tpg.Parser, dict): r""" 此為實習基板入出針語言 TuxIOme 初始版,自 Calc.py 擴充而來。由於使用中文之故, 不能使用預設的 NamedGroupLexer 。 文法定義如下 :: set lexer = CacheLexer separator space '\s+' ; token 指數運算 '\^|\*\*' 入出針定義 token 聲音控制 '(響聲|禁音)\b' make_op token 乘除運算 '[乘|除|剩]' make_op token 函數二 '(norm)\b' float token integer '\d+' e=self.記憶() | VarId/v '=' Expr/e e=出入定義(p, '出') # | '定義' Expr/p '入' e=op(p) | '讀入' Expr/p e=輸出符碼(p, 0) | '寫出' Expr/p '關' e=啟動蜂鳴器() | "蜂鳴器" 聲音控制/op Expr/p e = 輸出數碼管(p) | "IRTX" VarId/s e = 紅外線輸入() | "系統溫度" self.get(v,0) e=op(e,t) )* ; Term/t -> Fact/t ( 乘除運算/op Fact/f f=op(0,f) | Pow/f ; Pow/f -> Atom/f ( 指數運算/op Fact/e y = f(x) | 函數二/f '' $ y = f(x1,x2) ; """ def __init__(self): super().__init__() self.名稱 = "實習機板" self["一藍"] = 5 self["二藍"] = 6 self["三藍"] = 13 self["四藍"] = 19 self["五綠"] = 0 self["六綠"] = 1 self["七黃"] = 7 self["八紅"] = 8 self["按鍵一"] = 23 self["按鍵二"] = 18 self["撥碼一"] = 24 self["撥碼二"] = 25 def 記憶(self): vars = sorted(self.items()) memory = [ "%s = %s"%(var, val) for (var, val) in vars ] return "\n\t" + "\n\t".join(memory) print("Calc (TPG example)") 實習機 = 實習機板() while 1: try: l = raw_input("\n:") except UnicodeDecodeError: continue if l: try: print(實習機(l)) except Exception: print(tpg.exc()) else: break # 數碼緒._stop() GPIO.cleanup()
碼︰會 習。☿ 長︰同學們請安靜。今天這第一次 會外會可是破天荒的熱烈,現在早過了响午,就算大家還不覺得 餓,也該中場休息一會兒吧!雖說還有一些分歧的意見,並不急的今天論定。稍晚飯後,就讓我們開始研讀資料、驗證 TuxIO me 程式 碼、測試 IRTX 與 IRRX ,隨性三三兩兩的分組討論,這樣好不好呢?……【鼓掌通過】