M♪o 之學習筆記本《巳》文章︰【䷒】知臨之宜

派生碼訊

巳 蛇

來氏《 易 》易註︰

六五,知臨,大君之宜,吉。

變坎,坎為通,智之象也。知臨者,明四目 ,達四聰,不自用而任人也。應乾陽,故曰大君。知臨之知,原生于九二,故即曰大君 。知者覺也,智即知也。六五非九二不能至此宜者,得人君之統體也。

六五柔中居尊,下任九二剛中之賢,兼眾智以臨天下,蓋得大君之宜者也,吉可知矣。占者有是德,亦如是占也。

︰甘澤 ☱ 連沃土 ☷ ,內兌悅外坤順,又有乾陽來相應,吉兆也。故曰︰知臨之宜。

今兒學堂的氣氛頗不尋常,不見往日課前之嘻笑打鬧,正三五成群的討論紅外線控制種種以及入出針文法擴張等等的哩!

學長來了,看了看沒進教室,卻招手將我喚到室外,說道︰

同學們能主動學習很好,今天就不上課了。妳帶著大家研習,要是真的碰到了疑難,那時我再來。如果同學問起,就說我有事請假,晚點才能到校,請大家先行自習。

 

派︰☿ 長 長︰同學們請安靜。學長告知︰上午有事請假,請大家先行自習。既然昨日的討論,意猶未盡,何不今早大家就

輪番上陣講習,彼此觀摩,溝通想法。為著下午的 會習 習,也來個 會 外 會 會外會的耶!……【鼓掌通過】

於此特寫一致同意的若干事項︰

【小學堂 旗 旗號】

正式將入出針程式命名為『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 apt-get install python-lirc  Otherwise, download the latest relase from [here]https://github.com/tompreston/python-lirc/releases and install with: 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:

cat ~/.lircrc begin button = 1 # what button is pressed on the remote prog = myprogram # program to handle this command config = one, horse # configs are given to program as list end  begin button = 2 prog = myprogram config = two end  Use === 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 ~ more /etc/lirc/lircrc begin   prog = TuxIOme   button = KEY_1   config = 1 end  begin   prog = TuxIOme   button = KEY_2   config = 2 end  begin   prog = TuxIOme   button = KEY_3   config = 3 end  begin   prog = TuxIOme   button = KEY_4   config = 4   end  begin   prog = TuxIOme   button = KEY_5   config = 5   end  begin   prog = TuxIOme   button = KEY_6   config = 6     end  begin   prog = TuxIOme   button = KEY_7   config = 7   end  begin   prog = TuxIOme   button = KEY_8   config = 8   end  begin   prog = TuxIOme   button = KEY_9   config = 9     end  begin   prog = TuxIOme   button = KEY_0   config = 0 end  begin   prog = TuxIOme   button = KEY_DOWN   config = DOWN end  begin   prog = TuxIOme   button = KEY_LEFT   config = LEFT end  begin   prog = TuxIOme   button = KEY_UP   config = UP end  begin   prog = TuxIOme   button = KEY_RIGHT   config = RIGHT end  begin   prog = TuxIOme   button = KEY_BACK   config = BACK end  begin   prog = TuxIOme   button = KEY_ENTER   config = ENTER end  begin   prog = TuxIOme   button = KEY_SETUP   config = SETUP end  begin   prog = TuxIOme   button = KEY_PLAYPAUSE   config = PLAYPAUSE end  begin   prog = TuxIOme   button = KEY_STOP   config = STOP end  begin   prog = TuxIOme   button = KEY_VOLUMEUP   config = VOLUMEUP end  begin   prog = TuxIOme   button = KEY_VOLUMEDOWN   config = VOLUMEDOWN end  </pre>    △ 按造結論新改之 TuxIOme 初始版程式︰ <pre class="lang:python decode:true ">#!/usr/bin/python3 # -*- coding: utf-8 -*-  import math import operator import string import threading import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False)  開 = 亮 = 低 = 0 關 = 滅 = 高 = 1  from time import sleep  import tpg   if tpg.__python__ == 3:     operator.div = operator.truediv     raw_input = input   def make_op(op):     return {         '加'   : operator.add,         '減'   : operator.sub,         '乘'   : operator.mul,         '除'   : operator.div,         '剩'   : operator.mod,         '^'   : lambda x,y:x**y,         '**'  : lambda x,y:x**y,         '餘弦' : math.cos,         '正弦' : math.sin,         '切弦' : math.tan,         'acos': math.acos,         'asin': math.asin,         'atan': math.atan,         '平方' : lambda x:x*x,         '根號': math.sqrt,         '正值' : abs,         'norm': lambda x,y:math.sqrt(x*x+y*y),     }[op]  數碼賦值 = [(滅, 亮, 亮, 滅, 滅, 滅, 亮, 滅), (滅, 滅, 滅, 滅, 亮, 亮, 亮, 滅), (滅, 亮, 亮, 滅, 滅, 滅, 亮, 滅),   (滅, 滅,
]

遲延 = 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 指數運算    '\^|\*\*'                                               make_op         token 入出設定    '(入針|出針)\b' 入出針定義
        token 聲音控制    '(響聲|禁音)\b'                                                   控制蜂鳴器         token 加減運算    '[加|減]' make_op
        token 乘除運算    '[乘|除|剩]'                                                 make_op         token 函數一    '(餘弦|正弦|切弦|acos|asin|atan|平方|根號|正值)\b' make_op
        token 函數二    '(norm)\b'                                              make_op         token real      '(\d+\.\d*|\d*\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+' float
        token integer   '\d+'                                                   int         token VarId     '\w*'                                                    ;          START/e ->                 '變元' e=self.記憶()
            |   VarId/v '=' Expr/e      self[v]=e             |   Expr/e #            |   '定義' Expr/p '出' e=出入定義(p, '出')
#            |   '定義' Expr/p '入'             e=出入定義(p, '入')             |   '入出針'  Expr/p 入出設定/op e=op(p)
            |   '讀入' Expr/p                  e=輸入符碼(p)             |   '寫出' Expr/p '開' e=輸出符碼(p, 0)
            |   '寫出' Expr/p '關'                 e=輸出符碼(p, 1)             |   "打開蜂鳴器" e=啟動蜂鳴器()
            |   "蜂鳴器" 聲音控制/op Expr/p       e = op(p)             |   "顯示" Expr/p e = 輸出數碼管(p)
            |   "IRTX" VarId/s                    e = 紅外線輸出(s)             |   "IRRX" e = 紅外線輸入()
            |   "系統溫度"                        e = 讀取系統溫度()         ;          Var/self.get(v,0)-> VarId/v ;          Expr/e -> Term/e ( 加減運算/op Term/t e=op(e,t)
                         )*
        ;

        Term/t -> Fact/t ( 乘除運算/op Fact/f     t=op(t,f)                          )*         ;           Fact/f ->                 加減運算/op Fact/f f=op(0,f)
            |   Pow/f
        ;

        Pow/f -> Atom/f ( 指數運算/op Fact/e      f=op(f,e)                         )?         ;          Atom/a ->                 real/a             |   integer/a             |   Function/a             |   Var/a             |   '<img src="http://www.freesandal.org/wp-content/ql-cache/quicklatex.com-47b60ee797a9328acb352e3ae7895aa5_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="' Expr/a '" title="Rendered by QuickLaTeX.com" height="19" width="68" style="vertical-align: -5px;"/>'         ;          Function/y ->                 函數一/f '<img src="http://www.freesandal.org/wp-content/ql-cache/quicklatex.com-22e0e32183ddc257d3b853d237d23b4a_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="' Expr/x '" title="Rendered by QuickLaTeX.com" height="19" width="69" style="vertical-align: -5px;"/>' y = f(x)
            |   函數二/f '' Expr/x1 ',' Expr/x2 ''  $ 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 ,隨性三三兩兩的分組討論,這樣好不好呢?……【鼓掌通過】

 

訊 ︰☿ 果其然《 易 》易曰︰咸臨貞吉,志行正也。