雖說用『裝置樹』 Device Tree 來描述硬體的介接,提供充分的相關資訊 ,因此作業系統可以選取『適當對應』裝置驅動程式。聽起來如是美好,易懂易解,然而實務上卻常叫人一頭霧水,這又是怎麼一回事的呢?
這或許因為人們不知道『困難』的問題有兩大類,一類的問題了解很『容易』,但是幾乎沒人會,這叫做『真難』。比方說︰
證明『費馬大定理』
沒有整數解。即使這個定理已被證明,想要『讀懂』依然十分困難 !這一類的『問題』在『實務』並上不多見,或許由於反正難有人能『解讀』的吧!!
另一類的問題對於『學習者』而言,就需要特別的『注意』。它的每一『小部份』也許都『不困難』,然而有太多的部份『構成』,十分的『複雜』。如果缺乏『系統思維』,又對於『容易理解』之『小部份』不能『深化認識』建立自身『體系』,以至於『引發』了常見的『或知或解』與『或不知或不解』現象,這大概也不奇怪的哩!?舉例來講,因為 Kernel 4.1.4 之更新,作者不得不『驗證』自己文本所說到底還『正不正確』?所以想著有沒有『比較快速』的辦法呢??針對 GPIO 的『測試』而言,想起了曾經編寫的
【TuxIOme V0.1】。設想那 M♪o 學習時所用的學習板
有四十根針而且含括多種 GPIO ,又是自己寫的,豈不正是合適︰
#!/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 單元 == 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', 'tuxiome', 字碼,"--count=" +str(重複次數) ]) return "已送出" 傳送重複 = 3 訊息編碼表 = {"0" : "KEY_0", "1" : "KEY_1", "2" : "KEY_2", "3" : "KEY_3", "4" : "KEY_4", "5" : "KEY_5", "6" : "KEY_6", "7" : "KEY_7", "8" : "KEY_8", "9" : "KEY_9", } 訊息解碼表 = {"0" : "0", "1" : "1", "2" : "2", "3" : "3", "4" : "4", "5" : "5", "6" : "6", "7" : "7", "8" : "8", "9" : "9", "SETUP" : "S", "ENTER" : "-", "BACK" : "E", } def 紅外線發訊(四位數): global 傳送重複 訊息串 = str(四位數) if len(訊息串) != 4 : return "訊息必須四位數" subprocess.call(['irsend', 'SEND_ONCE', 'tuxiome', "KEY_SETUP","--count=" +str(傳送重複) ]) for 字碼 in 訊息串 : subprocess.call(['irsend', 'SEND_ONCE', 'tuxiome', 訊息編碼表[字碼],"--count=" +str(傳送重複) ]) subprocess.call(['irsend', 'SEND_ONCE', 'tuxiome', "KEY_ENTER","--count=" +str(傳送重複) ]) subprocess.call(['irsend', 'SEND_ONCE', 'tuxiome', "KEY_BACK","--count=" +str(傳送重複) ]) return "已發訊" import lirc sockid = lirc.init("TuxIOme", blocking=False) def 紅外線輸入(): return lirc.nextcode() def 紅外線收訊(): 空碼 = 0 狀態 = 0 字串 = "" while True: 字碼 = 紅外線輸入() if 字碼 == [] : 空碼 += 1 if 空碼 < 10 : continue else: 狀態 = 1 break 空碼 = 0 字串 = 字串 + 訊息解碼表[字碼[0]] if 狀態 == 1 : return 字串 else: return "錯誤" 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]) from w1thermsensor import W1ThermSensor sensor = W1ThermSensor() def 讀取環境溫度(): return sensor.get_temperature() import random class 實習機板(tpg.Parser, dict): r""" 此為實習基板入出針語言 TuxIOme 0.1,自 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["周遭溫度"] = e = 讀取環境溫度() | "發訊" Expr/p e = 紅外線收訊() ; Var/ -> VarId/v ; Expr/e -> Term/e ( 加減運算/op Term/t t=op(t,f) )* ; Fact/f -> 加減運算/op Fact/f f=op(f,e) )? ; Atom/a -> real/a | integer/a | Function/a | Var/a | '' | Random/a ; Function/y -> 函數一/f '' y = f(x1,x2) ; Random/x -> "四位亂數" sudo ./TuxIOme Calc (TPG example) :系統溫度 50.8 :環境溫度 36.875 :變元 CPU溫度 = 50.8 一藍 = 5 七黃 = 7 三藍 = 13 二藍 = 6 五綠 = 0 八紅 = 8 六綠 = 1 周遭溫度 = 36.875 四藍 = 19 按鍵一 = 23 按鍵二 = 18 撥碼一 = 24 撥碼二 = 25 :顯示 CPU溫度 完成 :顯示 周遭溫度 完成 :四位亂數 6398 :四位亂數 5724 :發訊 5200 已發訊 :收訊 S55--22--0-E :發訊 1314 已發訊 :收訊 S11--33--11--4-EE :
只不過光為了跑那個程式,也得『重讀』自己寫的
‧ M♪o 之學習筆記本《巳》文章︰【䷒】知臨之宜
那些文本 ,然後『再驗』之以相同的測試
pi@raspberrypi ~ $ sudo ./TuxIOme Calc (TPG example) :系統溫度 53.0 :環境溫度 36.375 :變元 CPU溫度 = 53.0 一藍 = 5 七黃 = 7 三藍 = 13 二藍 = 6 五綠 = 0 八紅 = 8 六綠 = 1 周遭溫度 = 36.375 四藍 = 19 按鍵一 = 23 按鍵二 = 18 撥碼一 = 24 撥碼二 = 25 :顯示 CPU溫度 完成 :顯示 周遭溫度 完成 :四位亂數 7721 :四位亂數 5104 :發訊 5200 已發訊 :收訊 S55--22--0-00--EE :發訊 1314 已發訊 :收訊 S1-3-11-4--EE :
豈不是好笑的耶??!!