2021年12月3日 星期五

Python 學習筆記 : 中文繁簡轉換套件 HanziConv

今天在 "Python 技術者實踐! (旗標, 2018)" 這本書的第 15 章讀到 HanziConv 這個中文簡繁體套件, 在中文語意分析與自然語言處理時很好用, 於是便馬上進行測試. HanziConv 為第三方套件, 需先用 pip 或 pip3 install 指令安裝後才能使用 :

pip install hanziconv    

C:\Users\User>pip install hanziconv    
Collecting hanziconv
  Downloading hanziconv-0.3.2.tar.gz (276 kB)
     Preparing metadata (setup.py) ... done
Building wheels for collected packages: hanziconv
  Building wheel for hanziconv (setup.py) ... done
  Created wheel for hanziconv: filename=hanziconv-0.3.2-py2.py3-none-any.whl size=23214 sha256=2e97cb6420e5c4f9c2096e34c338174d9ea8560905594bc74df25ea54cfe9500
  Stored in directory: c:\users\user\appdata\local\pip\cache\wheels\bf\e3\22\7bf50146a3ee95d1fdcbfabc44a1fe15b6e2ab7348ab7337bf
Successfully built hanziconv
Installing collected packages: hanziconv
Successfully installed hanziconv-0.3.2

安裝完成即可匯入 hanziconv , 然後用 dir() 函式來觀察此套件之內容 : 

>>> import hanziconv    
>>> dir(hanziconv)   
['HanziConv', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'absolute_import', 'charmap', 'hanziconv', 'unicode_literals']

可以利用求值函式 eval() 取得成員的參考, 再用迴圈來檢視成員之資料類型 : 

>>> members=dir(hanziconv)     
>>> for mbr in members:                   # 走訪 hanziconv 模組成員
    obj=eval('hanziconv.' + mbr)         # 用 eval() 求值取得 hanziconv.成員之參考
    if not mbr.startswith('_'):               # 走訪所有不是 "_" 開頭的成員
        print(mbr, type(obj))                  # 輸出成員之類型
        
HanziConv <class 'type'>
absolute_import <class '__future__._Feature'>
charmap <class 'module'>
hanziconv <class 'module'>
unicode_literals <class '__future__._Feature'>

其中 HanziConv 就是這個套件定義的類別, 用 dir() 檢視其成員 : 

>>> dir(hanziconv.HanziConv)     
['_HanziConv__convert', '_HanziConv__simplified_charmap', '_HanziConv__traditional_charmap', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'same', 'toSimplified', 'toTraditional']

其中 toSimplified() 與 toTraditional() 就是用來做繁簡轉換的方法. 所以實際應用時不會用 import hanziconv 套件, 而是從套件 hanziconv 中指定匯入 HanziConv() 類別, 然後直接呼叫 toSimplified() 與 toTraditional() 這兩個方法 :

from hanziconv import HanziConv

>>> from hanziconv import HanziConv     
>>> dir(HanziConv)     
['_HanziConv__convert', '_HanziConv__simplified_charmap', '_HanziConv__traditional_charmap', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'same', 'toSimplified', 'toTraditional']

顧名思義, toSimplified() 是傳入繁體字串傳回簡體字串, 而 toTranditional() 則是傳入簡體字串傳回繁體字串, 可用 help() 查看其使用說明 : 

>>> help(HanziConv.toSimplified)      
Help on method toSimplified in module hanziconv.hanziconv:

toSimplified(text) method of builtins.type instance
    Convert `text` to simplified character string.  Assuming text is
    traditional character string
    
    :param text:  text to convert
    :returns:     converted UTF-8 characters
    
    >>> from hanziconv import HanziConv
    >>> print(HanziConv.toSimplified('繁簡轉換器'))
    繁简转换器

>>> help(HanziConv.toTraditional)   
Help on method toTraditional in module hanziconv.hanziconv:

toTraditional(text) method of builtins.type instance
    Convert `text` to traditional character string.  Assuming text is
    simplified character string
    
    :param text:  text to convert
    :returns:     converted UTF-8 characters
    
    >>> from hanziconv import HanziConv
    >>> print(HanziConv.toTraditional('繁简转换器'))
    繁簡轉換器

簡轉繁例如 : 

>>> HanziConv.toTraditional('游戏')    
'遊戲'
>>> HanziConv.toTraditional('软件')     
'軟件'
>>> HanziConv.toTraditional('内存')    
'內存'
>>> HanziConv.toTraditional('鼠标')   
'鼠標'
>>> HanziConv.toTraditional('打印机')    
'打印機'
>>> HanziConv.toTraditional('硬盘')    
'硬盤'

可見此套件只是逐字將簡體字轉成繁體字, 並沒有詞彙轉換功能 (例如將 '内存' 轉成 '記憶體', '打印机' 變 '印表機' 等).

繁轉簡例如 :

>>> HanziConv.toSimplified('中華民國萬歲')     
'中华民国万岁'
>>> HanziConv.toSimplified('蔣總統萬歲')   
'蒋总统万岁'
>>> HanziConv.toSimplified('智商高達 157 的阿北')     
'智商高达 157 的阿北'
>>> HanziConv.toSimplified('硬盤')    
'硬盘'
>>> HanziConv.toSimplified('硬碟')    
'硬碟'
>>> HanziConv.toSimplified('雷射')    
'雷射'

可見繁簡轉也是逐字轉換, 雷射不會得到激光. 關於兩岸用語差異參考 :


好書 : 數學, 確定性的失落

今天在研究 Python 的 type 時找到下面這篇文章 : 


作者是學數學的, 他談到了數學的公理系統 (公理 axioms 是雖然不知如何證明為真, 但經由人類長久實踐的經驗, 被普遍認為是不證自明的基本命題), 推薦我們去讀一讀美國數學史學家, 紐約大學教授 Morris Kline 寫的 "數學, 確定性的失落 (Mathematics: The Loss of Certainty)" 這本書 : 


Source : 博客來


雖然不確定自己是否能看得下去 (確定性的失落 XD), 但這應該是一本好書. 市圖有收藏這本, 所以不用買, 那就借來看看唄. 

2021年12月2日 星期四

2021年11月29日 星期一

2021 年第 48 周記事

這一周天氣大都為陰冷天, 週日鄉下還下起雨來, 原本要帶一大袋書去還也就作罷, 反正下周才到期. 寒流要來讓我認真地找之前一件很保暖有帽子的外套, 過完年後就不知塞到哪兒了, 找東西最累, 忙了老半天還徒勞無功. 

本周較少看電視了 (除了周三的韓劇 "戀慕"), 所以也比較專心於學習. 由於上周買的兩本 MicroPython 書到貨, 看著看著就去找出已兩年沒玩的 ESP8266/ESP 板子, 動手更新韌體, 順便把樹莓派 Pico 也搞定了, 還上 Aliexpress 買了一些新貨. 這些電子玩具很有趣, 看到組合起來的電路能照我們的意志工作就有一種成就感, 哈哈, 2022 還沒開始, 但我已暖身要開始來執行計畫已久的物聯網專案了. 

週五收到大灰熊要定檢的通知, 我週六馬上就去完成檢驗, 學乖了, 以前拖拖拉拉過了一個月到現場才發現強制險效期不足一個月, 要嘛現場買一家沒折扣的, 要嘛等上班後續約完成再跑一趟, 費事又費時, 該做的事不能拖. 

自從打兩劑 AZ 滿兩周後就開始預約周六下午去愛心探視, 本周第三次, 除了熟識的運金伯母外, 還多了一些生面孔長輩. 在推阿蘭逛花園時拍了一張花的微物攝影, 姊姊說我手機的鏡頭超棒 : 




以前都沒發現微物攝影的妙用, 直到最近看到一篇新聞介紹有一個人只用手機就拍出許多微小生物的美照, 我才開始嘗試, 發覺用來拍電路板效果特好. 

因週日下雨沒辦法整理菜園, 所以一整天都在書房玩 Pico. 但盤點一下最近要做的事還蠻多的 : 
  1. 安裝車庫米家監視器 2
  2. 種玉米 + 木瓜
  3. 剷除菜園甘蔗
  4. 除蟻
  5. 清除水圳淤泥 (菜園填土)
一個周末大概只能完成一項, 別貪心, 就一個一個來吧 (完成就槓掉). 

2021年11月28日 星期日

Raspberry Pi Pico 學習筆記 (二) : 燒錄 MicroPython 韌體

最近因為買了兩本 MicroPython 的書, 掀起了內心冷卻已久的 maker 熱, 也想起了我之前買的三片 Pico, 上回焊好針腳後就丟一邊, 這回打鐵趁熱把 MicroPython 灌進去吧! 以下測試除了參考官網資料外, 主要是按照神人筆記 "天花板隨記" 部落格的說明.  

本系列前面的相關文章參考 :


將 MicroPython 韌體燒錄到 Pico 的方式有兩種 : 
  • 使用 UF2 檔安裝 :  
    須先下載 MicroPython 的 UF2 檔, 放入 RPI-RP2 虛擬磁碟機即完成燒錄. 
  • 使用 Thonny 安裝 : 
    利用 Thonny 直譯器選單裡的安裝與更新功能進行燒錄. 
參考 Raspberry Pi Pico 的說明文件 :



1. 上傳 UF2 檔燒錄 MicroPython 韌體 :     

UF2 是微軟所制訂的一種二進制檔案格式, 可用來為 Flash 記憶體進行快速燒錄, 參考 : 


首先到 MicroPython 官網下載 Pico 的 UF2 檔 : 


點選 Releases 下最近的穩定版本, 不要下載 Nightly Builds 下的最新版 : 


然後按住 Pico 上的 BOOTSEL 鈕不放, 將 Pico 連接到 PC 的 USB 槽後再放開 : 




這時檔案總管會出現一個新的磁碟機 RPI-RP2, 裡面內建了 INDEX.HTM 與 INFO_UF2.TXT 這兩個檔案, 點擊前者會連接到 Pico 的說明文件網頁, 後者則是 UF2 的說明文件 :




不用管這兩個檔案, 直接將所下載的 MicroPython UF2 檔案複製到此 RPI-RP2 磁碟機即可, 貼上 UF2 就會馬上進行燒錄, 很快就完成了, 這時 Pico 板會重啟, RPI-RP2 磁碟機會會被卸除, 這時開啟裝置管理員可知 Pico 已連接到 COM 埠 : 




這時開啟 Putty 連線 COM 埠, 首先會進入 Raw REPL 介面, 要按 CTRL + B 才會進入 MicroPython Shell : 




Pico 板載的 LED 接在 GPIO25, 下面就用迴圈來測試 LED 閃爍 : 

MicroPython v1.17 on 2021-09-02; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> from machine import Pin
>>> import time   
>>> LED=Pin(25, Pin.OUT)   
>>> while True:   
...     LED.value(0) 
...     time.sleep(1)   
...     LED.value(1)   
...     time.sleep(0.5)   
...
...

由於 Pico 沒有 Reset 按鈕, 終止此無限迴圈的辦法是關掉 Putty, 移除 USB 接線接回後再重新連線. 或是把 RUN 接腳接地亦可, 參考 :

How to Reset Your Raspberry Pi Pico With a Button

也可以使用 Thonny 編輯器的 Shell 介面來執行 MicroPython 程式, 點選 "執行/選擇直譯器" : 



 
切到 "直譯器" 頁籤, 上面選擇 "MicroPython (Raspberry Pi Pico)", 底下選擇所連接的 COM 埠或 "自動偵測連接埠", 確認後底下應該會出現 MicroPython 命令列 :





輸入如下指令 :

MicroPython v1.17 on 2021-09-02; Raspberry Pi Pico with RP2040

Type "help()" for more information.
>>> from machine import Pin
>>> import time
>>> LED=Pin(25, Pin.OUT)
>>> while True:
    LED.toggle()
    time.sleep(1)

就可以看到板載 LED 閃爍了 : 




此處改用 Pin 物件的 toggle() 方法來使 LED 狀態 High/Low 切換, 雖然指令較精簡, 但缺點是 ON/OFF 時間相同, 無法個別調整. 


2. 使用 Thonny 燒錄 MicroPython 韌體 :  

Python 專用編輯器 Thonny 也可以直接燒錄 MicroPython 韌體 (須網路保持連線, 因 Thonny 要從官網下載 UF2 韌體檔), 以下就用 Thonny 來燒錄另外兩片空白的 Pico 吧! 

首先開啟 Thonny, 按住 Pico 的 BOOTSEL 鈕不放, 將 Pico 用 USB 連接 PC 後再放開 BOOTSEL 鈕, 跟上面一樣檔案總管會出現名稱為 RPI-RP2 的磁碟機, 但不用管它, 接下來點選 Thonny 的 "執行/選擇直譯器" : 




上面的選單選擇 "MicroPython (Raspberry Pi Pico)" : 




下面選擇 "自動偵測連接埠", 然後按右下角的 "" :




這時 Thonny 會自動找尋最新的 MicroPython 版本, 但在跳出的視窗中按 "安裝" 卻出現 "certificate verify failed: certificate has expired (_ssl.c:1091)" 的錯誤訊息 : 





完整的錯誤訊息如下 : 

Downloading 563200 bytes from https://micropython.org/resources/firmware/rp2-pico-20210902-v1.17.uf2

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 1350, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 1277, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 1323, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 1272, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 1032, in _send_output
    self.send(msg)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 972, in send
    self.connect()
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\http\client.py", line 1447, in connect
    server_hostname=server_hostname)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\ssl.py", line 423, in wrap_socket
    session=session
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\ssl.py", line 870, in _create
    self.do_handshake()
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\ssl.py", line 1139, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1091)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\site-packages\thonny\plugins\micropython\uf2dialog.py", line 271, in _perform_work
    self._download_to_the_device(download_url, size, target_dir)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\site-packages\thonny\plugins\micropython\uf2dialog.py", line 333, in _download_to_the_device
    with urlopen(req, timeout=5) as fsrc:
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 525, in open
    response = self._open(req, data)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 543, in _open
    '_open', req)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 503, in _call_chain
    result = func(*args)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 1393, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "C:\Users\User\AppData\Local\Programs\Thonny\lib\urllib\request.py", line 1352, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1091)>

看起來是 SSL 認證問題, 我檢查目前使用的 Thonny 版本是 3.3.10 : 




但官網已到 3.3.13 版, 我以為是版本太舊的關係, 就先移除 Thonny, 然後下載最新的 3.3.13 來安裝, 但結果還是一樣, 所以跟 Thonny 版本無關. 後來找到下面文章才找到解決辦法 :





原來只要去下載安裝 lets-encrypt-r3.der 憑證即可 : 


點擊下載的憑證檔按確定與下一步即可完成安裝 : 








然後回到 Thonny 再次安裝韌體即可順利進行了 :






OK! 完成了. 

2021年11月27日 星期六

於 Aliexpress 購買 D1 mini pro 十五套件組

今天在 Aliexpress 找到 Wavgate 免運 25.52 美元的 D1 mini 十五套件組 :





以昨日美元賣出匯率 27.87 計算, 25.25 美元折合台幣約 704 元. 為了避免以後用到時產品已下架, 所以將產品網頁截圖紀錄如下 : 







各元件電器規格摘要如下 : 
  1. D1 Mini pro : 
    • ESP-8266EX 
    • 16MB Flash
    • CP2102 USB 驅動
    • 板載陶瓷天線 + 外加天線座
  2. WS2812 RGB 全彩 LED 模組 :
    • 最高 800Kbps 傳輸率
    • 256 階明暗度
    • 16777216 全彩
    • 掃描頻率不低於 400 Hz/s
    • IO 介面 : D2
  3. DS18B20 溫度感測模組
    • 感測範圍 : 攝氏 -55~+125 誤差攝氏 0.5 度
    • 擷取精確度 9~12 位元
    • IO 介面 : D2
  4. DHT 溫溼度模組 :
    • 濕度範圍 : 20%~-95% 誤差 %
    • 溫度範圍 : 攝氏 0~50 度 誤差 2 度
    • 操作電壓 : 3.3~5V
    • IO 介面 : D4
  5. BMP180 氣壓感測模組 ; 
    • 氣壓範圍 : ˇ300~1100 hPa 解析度 0.03~0.06 hPa
    • 電源 1.8~3.6V (VDDA) 1.62~3.6V (VDDD)
    • IO 介面 : D1=SCL, D2=SDA
  6. 溫溼度感測器 SHT30 :
    • 溫度範圍 : 攝氏 -40~100 度 誤差 0.3 度 反應時間 8 秒
    • 濕度範圍 : 0~100% RH 誤差 3% 反應時間 5~30 秒
    • I2C 介面
    • IO 介面 : D1=SCL, D2=SDA
  7. 繼電器模組 :
    • 高位準觸發
    • KF301 控制端點
    • 電源 5V
    • IO 介面 : D1
  8. TF 卡模組 : 
    • 支援容量 : micro SD 小於 2GB, micro SDHC 卡 小於 32 GB
    • 電源 5V, 介面 3.3~5V
    • 最大電流 : 200 ma
    • IO 介面 : D5=CLK, D6=MISO, D7=MOSI, D8=CS
  9. 按鈕模組 : 
    • 按下是 High, 放開是 Low
    • 絕緣電壓 30 V
  10. 馬達驅動模組
    • 使用 TB6612 晶片, 自帶 boot 程式
    • 介面 : A1, A2 (馬達 A 驅動端子), B1, B2 (馬達 B 驅動), S (模式選擇)
    • IO 介面 : D1=SCL, D2=SDA
  11. 0.66 吋 OLED 顯示模組 :
    • 解析度 : 64848
    • 驅動 IC : SSD1306
    • I2C 介面 : 位址 0x3C, 0x3D
    • 工作電壓 : 3.3V
    • IO 介面 : D1=SCL, D2=SDA



用 esptool.py 燒錄 MicroPython 韌體 (ESP8266/ESP32)

今天在零件箱找到一塊之前測試過的 Wemos ESP8266, 接上 USB 後板載藍色 LED 會持續閃爍, 可見裡面已有程式在跑, 但卻無法用 Thonny 與 Putty 連線 COM 埠, 可能太久沒有使用秀逗了. 我看背板有打印這是 32MB, 喜出望外以為這是 32M Bytes : 





我用 esptool.py 查詢 flash_id 發現只有 4M Bytes, 背板打印的其實是 32M bits, 執行下列指令前須按住右下方的 Flash 鈕約直到顯示結果再放開 : 

D:\ESP8266>esptool.py --port COM8 flash_id    
esptool.py v2.6
Serial port COM8
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX   
Features: WiFi
MAC: 2c:3a:e8:06:b9:ca
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB    
Hard resetting via RTS pin...

雖然用 Thonny 或 ESPFlasher.exe 燒錄韌體很方便, 但命令列的 esptool.py 提供的功能更多 (Thonny 背後也是執行 esptool.py), 例如 flash_id 指令不僅顯示 Flash 大小, 還包括所使用的晶片. 詳細用法參考 :


我之前都是在燒錄 ESP32 時才會用 esptool.py, 今天就用它來將這塊無法連線的板子重新燒錄最新版 MicroPython 吧! 


1. 抹除 Flash 內容 :   

首先要將 Flash 裡面的舊資料清除乾淨, 同樣地, 在執行下列指令前須按住右下方的 Flash 鈕直到顯示結果再放開 : 

D:\ESP8266>esptool.py --chip esp8266 --port COM8 erase_flash     
esptool.py v2.6
Serial port COM8
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: 2c:3a:e8:06:b9:ca
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 6.1s
Hard resetting via RTS pin...


2. 燒錄 MicroPython 映像檔 :   

接下來就可以開始燒錄映像檔了, 同樣地, 在執行下列指令前須先按住右下方的 Flash 鈕直到顯示結果再放開 : 

D:\ESP8266>esptool.py --port COM8 --baud 115200 write_flash --flash_size=detect -fm dio 0 esp8266-20210902-v1.17.bin   
esptool.py v2.6
Serial port COM8
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: 2c:3a:e8:06:b9:ca
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0040
Compressed 633688 bytes to 416262...
Wrote 633688 bytes (416262 compressed) at 0x00000000 in 36.8 seconds (effective 137.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

此處黃底色部分是連續燒兩次沒成功 (燒錄過程無錯誤, 但出現怪碼) 後添加上去的, Baud rate 用 115200 較保險, 總之, 整個指令須要改的部分就是 COM 埠與映像檔檔名而已. 

完成後用 Thonny 或 Putty 均可正常連線進入 Shell/REPL 介面了 : 




關於 Thonny 操作參考 :


燒錄 ESP32 的 esptool 指令轉寫如下 : 

1. 清除 Flash :

esptool.py --port COM9 flash_id

2. 燒錄韌體 : 

esptool.py --chip esp32 --port COM9 write_flash -z 0x1000 esp32-20210418-v1.15.bin

3. 檢查 Flash : 

esptool.py --chip esp32 --port COM9 erase_flash

參考 : 


市圖還書 8 本 (二哥的參考書)

本周市圖還書如下 : 
這些主要是之前幫二哥借的, 除 3, 5 續借外, 其餘已修過不用再借. 工程數學我想要複習, 但現在還沒空, 要用時再借. 

2021年11月26日 星期五

好站 : Home Assistant 是甚麼?

最近收到熱心網友 Daren 兄留言 (他也記錄了非常豐富的物聯網實驗記錄, 非常值得參考學習), 建議我在進行智慧家居的物聯網專案時可以考慮使用 Google Home Assistant, 還提供了如下參考文章 : 


此文建議使用低耗電且運轉穩定的樹莓派來安裝 Home Assistant, 透過 Etcher 軟體來燒錄 Hass.io 作業系統的映像檔 (新版 Etcher 有 Flash from URL 按鈕可輸入 URL 下載映像檔並進行燒錄), 然後就可以用瀏覽器連線到 http://hassio.local:8123 來加入物聯網設備. 

下面這篇的做法說明也很詳細, 還有 Youtube 影片 Demo : 





有空拿閒置中的 Pi Zero 來安裝 Home Assistnt 試試. 

發現新玩具 : Pimoroni Tiny 2040

今天在 Pimoroni 網站上發現一塊非常小巧可愛的 RP2040 開發板 : Tiny 2040, 它使用樹莓派自行開發的 ARM 處理器 RP2040, 板載一顆 RGB 全彩 LED, 一個 Reset 按鈕, 以及一個 Flash 按鈕, 自帶 Type-C USB 介面可連接電腦, 結構就這麼簡單, 大小差不多跟郵票一樣大. 最吸睛的是配備超大 8MB Flash, 是我夢想中的極品 : 





主要性能如下 :
  • MPU : RP2040 (ARM M0+ 133 MHz)
  • SRAM : 264KB
  • FLASH :  8MB
  • GPIO : 8 個 (GPIO0~7)
  • ADC : 4 個 (12 bits)
參考 : 


可以把 Tiny 2040 看成是樹莓派 Pico 的縮小版, 可像 Pico 那樣用 C/C++ 或 MicroPython, CircuitPython 來操控它. 板載 RGB 全彩 LED 內接於 GPIO18~20, 不占用外接的 GPIO 接腳. 不過一塊報價 8.4 英鎊有點小貴 (約台幣 311 元), 目前促銷降價為 6.4 英鎊 (約台幣 237 元, 但放進購物車卻是 5.25 英鎊), 倒是可以考慮買一片來玩玩. 但買一片加上 5 英鎊運費就有點貴了 : 




10.25 英鎊約合台幣 380 元, 買兩片含運是 15.5 英鎊, 合台幣 574 元, 單價就降到台幣 287 元 :




總之要買多片才會把運費攤掉 (運費都是 5 英鎊), 我試算買 5 片單價降到 231 元, 買 10 片降到 213 元,  買 15 片是 207 元, 買 20 片是 204 元, 買 25 片是 202 元, 買 30 片是 200 元 ... 我寫了一個 Python 程式做單價估算, 發現買 2~5 片降幅較大 :

for i in range(1, 31):
    gpb=5.25 * i + 5          # 英鎊含運總價
    gpb_pc= gpb / i           # 英鎊含運單價
    twd=gpb * 37              # 台幣含運總價
    twd_pc=twd / i            # 計算現在單價
    if i==1:
        pre_drop=0                  # 與前一單價相比降幅初值
        total_drop=0                # 總降幅初值
        twd_pc_1=twd_pc       # 記住只買 1 片單價
    else:
        pre_drop=(twd_pc_old - twd_pc) / twd_pc_old * 100
        total_drop=(twd_pc_1 - twd_pc) / twd_pc_1 * 100
    twd_pc_old=twd_pc         # 記住前一個單價    
    print(f'{i}片總價={gpb:.2f}英鎊, 約台幣={twd:.2f}', end=" ")
    print(f'單價={gpb_pc:.2f}英鎊 約台幣={twd_pc:.2f}', end=" ")
    print(f'前降幅={pre_drop:.2f}% 總降幅={total_drop:.2f}%')
    
1片總價=10.25英鎊, 約台幣=379.25 單價=10.25英鎊 約台幣=379.25 前降幅=0.00% 總降幅=0.00%
2片總價=15.50英鎊, 約台幣=573.50 單價=7.75英鎊 約台幣=286.75 前降幅=24.39% 總降幅=24.39%
3片總價=20.75英鎊, 約台幣=767.75 單價=6.92英鎊 約台幣=255.92 前降幅=10.75% 總降幅=32.52%
4片總價=26.00英鎊, 約台幣=962.00 單價=6.50英鎊 約台幣=240.50 前降幅=6.02% 總降幅=36.59%
5片總價=31.25英鎊, 約台幣=1156.25 單價=6.25英鎊 約台幣=231.25 前降幅=3.85% 總降幅=39.02%
6片總價=36.50英鎊, 約台幣=1350.50 單價=6.08英鎊 約台幣=225.08 前降幅=2.67% 總降幅=40.65%
7片總價=41.75英鎊, 約台幣=1544.75 單價=5.96英鎊 約台幣=220.68 前降幅=1.96% 總降幅=41.81%
8片總價=47.00英鎊, 約台幣=1739.00 單價=5.88英鎊 約台幣=217.38 前降幅=1.50% 總降幅=42.68%
9片總價=52.25英鎊, 約台幣=1933.25 單價=5.81英鎊 約台幣=214.81 前降幅=1.18% 總降幅=43.36%
10片總價=57.50英鎊, 約台幣=2127.50 單價=5.75英鎊 約台幣=212.75 前降幅=0.96% 總降幅=43.90%
11片總價=62.75英鎊, 約台幣=2321.75 單價=5.70英鎊 約台幣=211.07 前降幅=0.79% 總降幅=44.35%
12片總價=68.00英鎊, 約台幣=2516.00 單價=5.67英鎊 約台幣=209.67 前降幅=0.66% 總降幅=44.72%
13片總價=73.25英鎊, 約台幣=2710.25 單價=5.63英鎊 約台幣=208.48 前降幅=0.57% 總降幅=45.03%
14片總價=78.50英鎊, 約台幣=2904.50 單價=5.61英鎊 約台幣=207.46 前降幅=0.49% 總降幅=45.30%
15片總價=83.75英鎊, 約台幣=3098.75 單價=5.58英鎊 約台幣=206.58 前降幅=0.42% 總降幅=45.53%
16片總價=89.00英鎊, 約台幣=3293.00 單價=5.56英鎊 約台幣=205.81 前降幅=0.37% 總降幅=45.73%
17片總價=94.25英鎊, 約台幣=3487.25 單價=5.54英鎊 約台幣=205.13 前降幅=0.33% 總降幅=45.91%
18片總價=99.50英鎊, 約台幣=3681.50 單價=5.53英鎊 約台幣=204.53 前降幅=0.29% 總降幅=46.07%
19片總價=104.75英鎊, 約台幣=3875.75 單價=5.51英鎊 約台幣=203.99 前降幅=0.26% 總降幅=46.21%
20片總價=110.00英鎊, 約台幣=4070.00 單價=5.50英鎊 約台幣=203.50 前降幅=0.24% 總降幅=46.34%
21片總價=115.25英鎊, 約台幣=4264.25 單價=5.49英鎊 約台幣=203.06 前降幅=0.22% 總降幅=46.46%
22片總價=120.50英鎊, 約台幣=4458.50 單價=5.48英鎊 約台幣=202.66 前降幅=0.20% 總降幅=46.56%
23片總價=125.75英鎊, 約台幣=4652.75 單價=5.47英鎊 約台幣=202.29 前降幅=0.18% 總降幅=46.66%
24片總價=131.00英鎊, 約台幣=4847.00 單價=5.46英鎊 約台幣=201.96 前降幅=0.17% 總降幅=46.75%
25片總價=136.25英鎊, 約台幣=5041.25 單價=5.45英鎊 約台幣=201.65 前降幅=0.15% 總降幅=46.83%
26片總價=141.50英鎊, 約台幣=5235.50 單價=5.44英鎊 約台幣=201.37 前降幅=0.14% 總降幅=46.90%
27片總價=146.75英鎊, 約台幣=5429.75 單價=5.44英鎊 約台幣=201.10 前降幅=0.13% 總降幅=46.97%
28片總價=152.00英鎊, 約台幣=5624.00 單價=5.43英鎊 約台幣=200.86 前降幅=0.12% 總降幅=47.04%
29片總價=157.25英鎊, 約台幣=5818.25 單價=5.42英鎊 約台幣=200.63 前降幅=0.11% 總降幅=47.10%
30片總價=162.50英鎊, 約台幣=6012.50 單價=5.42英鎊 約台幣=200.42 前降幅=0.11% 總降幅=47.15%

可見, 超過 5 片之後前降幅就變很小了, 而超過 10 片之後總降幅就不大了, 所以如果只是測試的話, 考量運費的攤分效果, 買 3~10 片攤提效果就算不錯了, 例如買五片含運單價 6.25 英鎊就低於 DM 上的促銷價 6.3 英鎊了.