超圖解 Python 物聯網實作入門:使用 ESP8266 與 MicroPython

超圖解Python物聯網實作入門

作者:趙英傑
出版社:旗標科技股份有限公司
出版日期:2018.5.1
頁數:640頁,雙色印刷(4頁全彩)。
定價:NT$699

  • 用最夯的Python語言學習程式設計
  • 用最超值的ESP8266控制板學物聯網
  • 用最易懂的超圖解學電子電路
  • 人人都能化身創客自造各種智慧應用

這是一本結合Python語言、電子電路、微電腦控制和物聯網的圖解入門書

本書的電子零件清單與配套的材料包,請參閱這一篇貼文

Python無疑是近年最受注目的通用型程式語言,它的語法簡單易學,不僅智慧型手機、個人電腦到網路雲端應用平台都支援Python程式,應用領域更遍及系統工具、網路程式、數值分析到人工智慧,而開放原始碼的MicroPython專案,則可在拇指大小的微電腦控制器上執行Python程式,讓你直接用Python控制硬體或開發物聯網專案,就連歐洲太空總署也將MicroPython應用在控制太空載具(詳見MicroPyhon官網論壇的“MicroPython and the European Space Agency”貼文)。

MicroPython支援多種32位元控制板,本書採用的是內建Wi-Fi無線網路、價格低廉的ESP8266系列控制板

打好基礎,超圖解電子電路觀念

本書的目標是讓沒有電子電路基礎,對微電腦、電子DIY 及物聯網有興趣的人士,也能輕鬆閱讀、認識Python語言,進而順利使用Python與ESP8266控制板完成互動應用。因此,實驗用到的電子、電路組裝和Python程式觀念,皆以手繪圖解的方式說明。例如,底下是二級體元件的概念圖解:

二極體元件圖解

為了方便讀者進行實驗,書本裡的電路都採用現成的模組,並搭配圖解說明,讓讀者不單只會照著接線,也能理解電子模組背後的原理,進而能靈活改造應用並實踐自己的想法。

類比搖桿模組圖解

WEMOS D1 mini (ESP8266) 控制板

ESP8266系列控制板種類很多,本書選用的是WEMOS D1 mini板

WEMOS D1 mini板

採用D1 mini板的主要原因:

  • 尺寸小、可插入麵包板。

WEMOS D1 mini與熱敏電阻麵包板電路

  • 有5V輸出和輸入,方便驅動各種週邊和感測器。

WEMOS d1 mini鋰電池擴展板

  • 有多種現成的「擴展板」模組可用,而且擴展板的接腳採用標準2.54mm孔距的排母或排針,不像某些廠商採用特殊規格的插座。

WEMOS d1 mini擴展板

擴展板雖然方便,但也有些缺點,像是配線彈性不足,有些擴展板佔用相同的微控器接腳,無法一同使用,有些則受限於擴展板的尺寸,像OLED顯示器和NeoPixel全彩LED,就採用解析度較低或者數量較少的元件,所以本書未全盤採用這些擴展板。

超圖解Python程式設計入門

為了清楚說明程式語法和執行結果,書本裡面的命令提示字元(終端機)視窗,也全都用手繪方式呈現:

命令提示字元(終端機)視窗

底下是用Python語言建立網路用戶端和伺服器程式的流程和相關指令對照說明:

網路用戶端和伺服器程式的流程

底下是在OLED螢幕呈現自訂符號的步驟和相關指令對照說明:

在OLED螢幕呈現自訂符號的步驟

本書也有說明實用的物件導向程式設計(OOP)手法,自行編寫伺服馬達(Servo)、超音波距離感測器、直流馬達控制板…等程式庫。

這是用自製的超音波距離感測器程式庫,達成測量物體距離的Python程式解說:

超音波距離感測器程式庫

書中也以範例實作說明物件導向程式設計中的「繼承」概念(註:實作內容與伺服馬達有關,不是拼裝獵雷鑑)。

物件導向程式設計之繼承

最後的「附錄B」則說明如何運用Windows 10的WSL(適用於Linux的Windows子系統),安裝Debian Linux並且配置交叉編譯器(cross-compiler),讓讀者了解如何自行編譯客製化的MicroPython韌體。

交叉編譯MicroPython

《超圖解Python物聯網實作入門:使用ESP8266, MicroPython》目錄

第1章 認識MicroPython與ESP8266控制板

  • 認識MicroPython、pyboard和ESP8266控制板
  • 認識程式語言
  • 在個人電腦上安裝Python 3.x版本
  • WEMOS D1 mini和NodeMCU控制板簡介
  • 下載與燒錄MicroPython韌體
  • 透過終端機操控MicroPython控制板
  • MicroPython和Arduino的程式開發流程比較
  • 動手做 1-1 用Python控制LED閃爍

第2章 認識電子零件與工具

  • 電壓、電流與接地
  • 電阻
  • 電容
  • 二極體
  • 發光二極體(LED)
  • 看懂電路圖
  • 微控制板和實驗電路的電源供應器
  • 電子工作必備的量測工具:萬用電錶
  • 動手做2-1 測量電阻或電容
  • 麵包板以及其他電子工具

第3章 MicroPython基本操作

  • MicroPython程式設計基礎
  • 使用迴圈執行重複性質的工作
  • 動手做 3-1 使用 while 執行已知次數或無限重複的工作
  • MicroPython的互動解譯器模式(REPL)操作說明
  • 上傳程式檔到ESP8266控制板
  • 負載的接法:源流與潛流
  • 動手做3-2 自行連接LED
  • 用歐姆定律計算出限流電阻值

第4章 開關電路

  • 認識開關
  • 開關電路與上/下拉電阻
  • 動手做4-1 用麵包板組裝開關電路
  • 改變程式流程的if條件式
  • 動手做4-2 LED切換開關
  • 動手做4-3 用RC電路消除開關彈跳訊號
  • 電容式觸控開關
  • 動手做4-4 使用觸控開關模組製作LED開關

第5章 Python程式設計基礎

  • 變數與資料類型
  • 建立自訂函式
  • 自訂程式庫與常數定義
  • 處理文字訊息:認識字元與字串資料類型
  • 列表(List)類型
  • 元組(Tuple)與其他循序型資料操作指令
  • 字典(Dictionary)類型
  • 認識數字系統

第6章 Wi-Fi 無線網路

  • 認識無線區域網路與Wi-Fi
  • 從網頁瀏覽器操作MicroPython控制板
  • 設定ESP8266以 STA(基站)模式連接無線網路
  • 修改boot.py檔、開機自動連線
  • 其他網路相關指令
  • bytes(位元組)類型與字元編碼

第7章 序列埠通信

  • 並列與序列通訊簡介
  • DHT11數位溫濕度感測器
  • 動手做7-1 製作數位溫濕度計
  • 認識UART序列埠
  • 建立UART序列通訊程式物件
  • 動手做7-2 連接GPS模組
  • 認識NMEA標準格式與獲取GPS的經緯度值

第8章 數位調節電壓強弱與全彩LED控制

  • 使用Timer(計時器)定時執行程式
  • 動手做8-1 使用定時器閃爍LED
  • 使用try…except捕捉例外狀況
  • 用匿名函式(lambda)改寫閃爍 LED 程式
  • 數位調節電壓變化
  • 動手做8-2 呼吸燈效果
  • 控制全彩 LED
  • 動手做8-3 控制RGB全彩LED
  • 旋轉編碼器
  • 動手做8-4 連接旋轉編碼器與ESP8266控制板
  • 動手做8-5 使用旋轉編碼器調整LED色彩
  • WS2812彩色LED模組與燈條
  • 動手做8-6 調控WS2812的色彩
  • 動手做8-7 跑馬燈效果

第9章 電晶體與蜂鳴器和直流馬達控制

  • 認識電晶體元件
  • 發音體和聲音
  • 動手做9-1 發出警報聲響
  • 動手做9-2 電流急急棒
  • 彈奏音樂
  • 動手做9-3 演奏一段瑪莉歐旋律
  • 認識直流馬達
  • 動手做9-4 電晶體馬達控制與調速器

第10章 控制伺服馬達

  • 認識伺服馬達
  • 動手做10-1 伺服馬達的控制程式
  • 自訂類別:遠離義大利麵條
  • 動手做10-2 編寫控制伺服馬達的自訂類別
  • 動手做10-3 吃錢幣存錢筒
  • 繼承:建立子類別
  • 動手做10-4 隨機轉動標靶

第11章 類比信號處理

  • 讀取類比值
  • 動手做11-1 讀取類比值並調控LED亮度
  • 認識光敏電阻與分壓電路
  • 動手做11-2 使用光敏電阻製作小夜燈
  • 壓力感測器與彎曲感測器
  • 熱敏電阻
  • 動手做11-3 使用熱敏電阻測量溫度
  • 動手做11-4 雷射槍玩具標靶
  • 電容式麥克風元件與聲音放大模組
  • 動手做11-5 拍手控制開關
  • 動手做11-6 拍手控制開關改良版

第12章 I2C介面:連接週邊與擴充ESP8266的類比輸入埠

  • 認識I2C介面
  • 類比轉數位(ADC)的專用IC介紹
  • 動手做12-1 連接PCF8591類比轉數位模組和I2C介面
  • 動手做12-2 自製二軸雲台(機械手臂)
  • 使用OLED顯示器顯示文字訊息
  • 動手做12-3 使用ssd1306程式庫操控OLED模組
  • 自訂顯示圖像
  • 動手做12-4 在OLED上顯示自訂符號
  • 使用LCD Assistant軟體轉換圖像
  • 動手做12-5 在OLED顯示動態溫濕度值

第13章 超音波距離感測器與I2C直流馬達驅動控制板實驗

  • 認識超音波
  • 動手做13-1 使用超音波感測器製作數位量尺
  • 建立超音波自訂類別與發出自訂例外錯誤
  • 動手做13-2 超音波距離控制燈光亮度
  • 控制馬達正反轉的H橋式馬達控制電路
  • WEMOS馬達擴展板
  • 動手做13-3 自動迴避障礙物的自走車
  • 用MicroPython改寫WEMOS原廠的Arduino馬達驅動程式庫
  • 位移和邏輯運算子

第14章 製作GPS軌跡記錄器

  • 讀取與設定本機時間
  • 動手做14-1 在OLED螢幕顯示GPS定位的台北時間
  • 使用os程式庫操作檔案
  • 建立與寫入檔案
  • 輪詢VS中斷
  • 動手做14-2 使用中斷要求開、關LED
  • 動手做14-3 建立儲存GPS紀錄的CSV格式檔案
  • 在谷歌地圖呈現GPS移動軌跡

第15章 SPI介面控制:LED矩陣和MicroSD記憶卡

  • LED矩陣元件
  • 認識SPI介面與MAX7219 IC
  • 動手做15-1 組裝LED矩陣電路
  • 顯示單一矩陣圖像
  • 動手做15-2 在 LED 矩陣上顯示音符圖像
  • 動手做15-3 在終端機顯示矩形排列的星號
  • 動手做15-4 LED矩陣動畫與多維序列資料程式設計
  • 動手做15-5 連接MicroSD/SD記憶卡

第16章 網路程式基礎入門

  • 認識網路與IP位址
  • 網域名稱、URL網址和傳輸協定
  • 網路的連線標準與封包
  • 使用Socket建立網路通訊程式
  • 動手做16-1 使用Socket建立一對一通訊程式
  • 認識網頁與HTML
  • 認識HTTP通訊協定
  • 動手做16-2 連結網站的用戶端程式
  • 認識HTTPS加密連線

第17章 物聯網應用初步

  • 建立網站
  • 動手做17-1 建立網站伺服器
  • 動手做17-2 動態顯示溫濕度資料
  • 動手做17-3 讀取並顯示HTML網頁和圖像
  • 認識 ThingSpeak物聯網雲端平台
  • 透過查詢字串傳遞資料
  • 動手做17-4 用urequest程式庫上傳資料到ThingSpeak平台
  • 使用POST方法傳遞資料
  • 解析查詢字串
  • 動手做17-5 搭配互動網頁介面的燈光調控器
  • 控制家電開關
  • 動手做17-6 使用繼電器控制家電開關

第18章 物聯網應用

  • 網路應用程式訊息交換格式:XML與JSON
  • 動手做 18-1 讀取JSON格式的世界各地天氣資料
  • 動手做 18-2 在OLED螢幕顯示氣象資訊
  • 認識MQTT
  • 動手做18-3 使用ESP8266發布資料到ThingSpeak MQTT伺服器
  • 動手做18-4 訂閱ThingSpeak MQTT訊息
  • ESP8266微控器的即時鐘(RTC)
  • 動手做18-5 透過網際網路更新時間
  • 超低功耗的深度睡眠模式
  • 動手做18-6 進入深度睡眠與喚醒微控器
  • 動手做18-7 自動睡眠、喚醒並上傳資料到ThingSpeak平台

附錄A uPyCraft與Tera Term使用說明

  • uPyCraft整合開發工具使用說明
  • 使用Tera Term終端機軟體

附錄B 編譯客製化的MicroPython韌體

  • 在Windows 10系統中安裝與執行Linux工具軟體
  • 交叉編譯MicroPython韌體
  • 從Linux環境複製檔案到Windows環境
  • 建立客製化的MicroPython韌體

內容勘誤

第3章 MicroPython基本操作

3-20頁,上方程式編輯器裡的while i in range(3):敘述,正確是for i in range(3):

第4章 開關電路

4-14頁,底下程式第一行的time=5,正確是time=15

第5章 Python程式設計基礎

5-19頁,中間程式第一行id=12,正確是num=12

第7章 序列埠通信

7-18頁,下方團片中的GPIO11,正確是GPIO1

GPIO1接線

7-28頁,最後一段的第13章,正確是第14章

7-48頁以及14-5頁,GPS日期格式的圖說中,日、月數字顛倒。

GPS日期格式

第8章 數位調節電壓強弱與全彩LED控制

8-4頁,底下的ujon程式碼,D1 = ”’,正確是 data = ”’

8-28頁,實驗程式第一行,from machine import Pin,正確是from machine import Pin, PWM

第9章 電晶體與蜂鳴器和直流馬達控制

9-22頁,TIP120馬達驅動電路,TIP120的E(射極)要接地,馬達一端要接正電源。

TPI120電晶體電路

9-23頁,中間內文(參閱第12章介紹),正確是第13章

第10章 控制伺服馬達

10-2頁,第二段文字中的參閱第10章,正確是第8章

第11章 類比信號處理

11-29頁,「增加拍手次數」註解底下的 print(‘claps: ‘ + claps),正確是print(‘claps: ‘ + str(claps))

第12章 I2C介面:連接週邊與擴充ESP8266的類比輸入埠

12-25頁,最下方程式碼當中的 oled.framebuf.blit,正確是oled.blit

12-30頁,程式碼當中的 self.oled.framebuf.blit,正確是self.oled.blit

第16章 網路程式基礎入門

16-32頁,程式碼當中的 wlan = network.WLAN(network.waln),正確是wlan = network.WLAN(network.STA_IF)

第17章 物聯網應用初步

17-7頁,程式碼當中的 client.send(httpHeader.format(temp, humid)),正確是client.send(httpHeader.format(temp=temp, humid=humid))

第18章 物聯網應用

18-10頁,「實驗說明」中的動手做11-3,正確是12-3

18-11頁,內文中間的第11章,正確是第12章

18-14頁,程式碼第2行的 oled.framebuf.blit(fb, 0, 15),正確是oled.blit(fb, 0, 15)

延伸閱讀

Posts created 483

445 thoughts on “超圖解 Python 物聯網實作入門:使用 ESP8266 與 MicroPython

  1. 我的步驟和書本裡的過程都相同,燒錄韌體的結果也和書籍相同,但程式上傳就是無法作動
    另外,我馬達控制器接的電源是18650*2,約8V的電壓,應該是不會燒掉
    如果我想使用三用電表查SCL與SDA是否有再傳輸訊息,是要在上傳程式之後量測嗎?

    1. 剛剛想到有可能是控制板接腳焊接不良(虛焊),請測量I2C、電源以及待機是否和D1 mini主板相通。如果I2C掃描沒有回應,那肯定無法控制。

      請參閱13-17頁的規格表,馬達電壓接8V,晶片電壓接5V沒有問題。

      I2C訊號無法用三用電錶測量,因為它的變化速度很快,應該使用示波器或邏輯分析儀。

      那個MicroPython控制程式沒有問題,本書的編輯還有台灣樹莓派公司的負責人也都測試過了。

      thanks,
      jeffrey

  2. 您好,因為要測試馬達控制器是否有在與D1連接,我又再次測試了馬達控制器的i2c,
    這次我將i2c scan後得出的數字是48,這樣是書裡面13-20所提到的馬達控制板預設值為0x30嗎?
    如果不是的話,請問我還可以有甚麼方法可以做調整?

  3. 挖….感覺甚麼都對了 ,但是馬達就是動不起來(馬達也測過是良好的)
    如果I2C的位址有出來,代表馬達擴充板是好的可以運作對吧?
    那您在前面所說「請測量I2C、電源以及待機是否和D1 mini主板相通」
    這部分該怎麼測量?
    另外謝謝您如此快速的回答,因為我下下週要製作這樣的課程,所以真的很想弄清楚,拜託了

    1. MicroPython有掃描到I2C位址,代表ESP8266和馬達控制板的通訊IC溝通沒問題,5V電源也有接通。

      剩下「待機」接線,假設它與D1 mini板的3.3V相連,在通電之前,使用電錶的歐姆檔測量D1 mini的3.3V和馬達驅動板的S腳,其歐姆值應該是0或非常低的阻值,代表兩者有相連。

      馬達控制板的馬達電源接上後,setMotor()的轉速設大一點試試(請參閱13-22中間的測試程式碼),例如:

      motorA.setMotor(wemotor.CW, 80)
      

      thanks,
      jeffrey

  4. 趙老師, 您好,
    請問書本中的page 4-26有提到,
    開機後自動執行main.py程式檔,

    我有一個溫溼度感應.py, 如下,
    把下面這個py檔名改成main.py放進ESP8266在重開機,
    並不會自動執行, 請問是什麼問題?
    我燒入是esp8266-20191220-v1.12.bin,
    採用TeraTerm看程式執行結果,
    我試過書本
    page 3-20,
    Page 13-7~13-8
    以上兩個.py檔改成main.py, 卻又可以正常開機後自動執行?

    from machine import Pin
    import dht
    import time

    d = dht.DHT22(Pin(2))
    i = 0

    while True:
    d.measure()
    temp = d.temperature()
    hum = d.humidity()
    i += 1
    print(‘Temperature: {}{}C’.format(temp,’\u00b0′))
    print (‘Humidity: {}%’.format(hum))
    print (‘No. {} test’.format(i))
    time.sleep(3)

  5. 趙老師, 你好,

    1. 關於你網頁中提到的充電模塊 + 3.7V 鋰電池, 請問用 3.7V 電源似乎會燒毀 ESP8266 ?
    我上網查過ESP8266 VCC耐壓最高只有3.6V.

    2. 這2天試過你書內提到的溫溼度器, 我採用 DHT22 (D1 mini 專用模塊, 你書中是用 DHT11),
    在執行過你所寫的code後, 會一直產生,下面 error,
    後來我查過該 DHT22 / DHT11 最小要求輸入電壓 3.3V,
    ESP8266 GPIO out 最大也才 3.3V,
    後來我從 D1 mini 板的 5V pin 跳線到 DHT22 VDD pin, 才可正常讀取溫濕度,

    不知道你在用 DHT11 VDD 只接 ESP8266 pin (3.3V), 是否會一直出現以下error ?

    import Temp_hum
    Traceback (most recent call last):
    File “”, line 1, in
    File “Temp_hum.py”, line 9, in
    File “dht.py”, line 16, in measure
    OSError: [Errno 110] ETIMEDOUT

    1. 感謝分享DHT22使用經驗,DHT11接3.3V沒問題,從Wemos官方的DHT12擴展板電路圖可看到,它也是接3.3V。

      3.7鋰電池模組,2-18頁內文有提到,它是DC升壓電路,把3.7V升壓到5V;1-21頁有提到,D1 mini板子上面有5V轉3.3V IC,所以ESP8266不會燒毀。

      thanks,
      jeffrey

  6. 趙老師, 您好,
    請問書本中的page 16-30的程式碼無法執行,會出現以下Error message

    s.send(httpHeader.format(path=path,host=host))
    AttributeError: ‘bytes’ object has no attribute ‘format’

    如果將httpHeader裡面的path,host直接輸入,不使用format會出現以下結果(400 Bad Request)

    HTTP/1.1 400 Bad Request
    Date: Thu, 23 Jul 2020 14:36:48 GMT
    Server: Apache
    Content-Length: 347
    Connection: close
    Content-Type: text/html; charset=iso-8859-1

    400 Bad Request

    Bad Request
    Your browser sent a request that this server could not understand.

    Additionally, a 400 Bad Request
    error was encountered while trying to use an ErrorDocument to handle the request.

    請問該如何修改呢?

  7. 趙老師, 您好,

    感謝回復,將’\r’加入後確實正常可以傳回 200 OK,但以下問題如何修改讓程式比較有彈性呢?

    請問書本中的page 16-30的程式碼無法執行,會出現以下Error message

    s.send(httpHeader.format(path=path,host=host))
    AttributeError: ‘bytes’ object has no attribute ‘format’

    1. 我剛剛燒錄最新的1.12版MicroPython,修改16-30頁的httpHeader:

      httpHeader = b'''\
      GET /{path} HTTP/1.0\r
      Host:{host}\r
      User-Agent: MicroPython\r
      \r
      '''
      

      測試沒問題。

      thanks,
      jeffrey

  8. 您好,我重新測試馬達的部分,使用課本p13-23的程式碼做測試,然後發現有出現這樣的錯誤訊息:
    Traceback (most recent call last):
    File “”, line 6, in
    File “wemotor.py”, line 32, in __init__
    File “wemotor.py”, line 60, in setFreq
    OSError: [Errno 110] ETIMEDOUT
    這個會是造成馬達無法作棟的原因嗎?

  9. 另外我發現兩個點,馬達控制器後面有STBY和RST的位置有露出焊接點,假設STBY由上到下分別是1號、2號、3號焊接點
    第一,我的馬達控制器的後面,在STBY的位置,不像是課本p13-20在2號與3號兩個連接點有焊接起來(預設透過S腳控制)、課本RST也焊接起來,所以我應該跟課本圖片一樣,將我買得STBY下方2號與3號兩個連接點焊接起來嗎?
    第二,我買的馬達控制器裡面,有部分的STBY已經是將STBY的1號與2號焊接點和起來了,這代表馬達控制器不用將馬達控制器上的 S 接上3.3V的高電位嗎?
    以上是我觀察到與課本不同的地方

    1. 馬達驅動板的PCB上面有印刷接腳的名字,用這個名字來描述問題比較明確。

      STBY標示的IO接點焊接在一起,代表由驅動板的STBY接腳決定是否進入待機模式(請對照13-17頁的模組),如果你的驅動板的IO接點沒有焊接在一起,請依照13-20頁的圖示焊接。

      RST接點焊接在一起,只是讓馬達驅動板的Reset和D1 mini控制板的Reset相連,跟控制程式無關。

      剛剛重新燒錄1.2版韌體,上傳wemotor.py檔,測試馬達轉動沒問題。

      thanks,
      jeffrey

  10. 我換了一塊新的D1 mini重新測試,馬達就可以工作了
    當然……我還是不知道舊的板子為什麼無法工作
    但是我在使用OLED時,測試SDA與SCL(與馬達I2C的SDA與SLC相同腳位)也是正常可已顯示資訊
    所以我還是不知道問題出在哪裡
    總之謝謝您們團隊的解答!
    感恩

    1. 赵老师 1-21页序列通信ic和usb母坐之间的电子元件是啥?是石英震荡器吗

  11. 趙老師, 你好,
    請問關於Page 15-7, Matrix LED 問題,
    我手邊有一片 D1 mini 專用Matrix LED模塊,
    驅動IC是用TM1640,
    我查過這顆 IC 無 CS pin,
    只有
    SCLK 對應 D1 mini pin, D5,
    DIN 對應 D1 mini pin, D7,
    也是吃 5V 電源,

    我採用你書中提到的page 15-14,
    但完全不會亮,
    也未產生任何的error,

    請問像這類無CS pin的驅動IC,
    cs code的部分該怎麼寫?

    謝謝

    1. 驅動IC不同,程式寫法也不一樣,如果你打算編寫它的驅動程式,應該從閱讀它的技術文件著手,裡面有說明它的介面規格和控制方式。

      有人已經寫好了TM1640的MicroPython程式庫,煩請自行測試。

      thanks,
      jeffrey

  12. 你好,我买过你编写的arduino图书,是简体字的,请问其他几本图书有简体字版本吗?在哪里可以买到呢?

    1. 《超圖解物聯網IoT實作入門》有简体中文版,由电子工业出版发行,分成两册,书名是《完美图解物联网IoT实操》,谢谢!

      thanks,
      jeffrey

  13. 趙師父,您好,我來自秘魯,我喜歡您的書,但是我不知道您是否以數字方式出​​售它,以及如何付款,謝謝

  14. 請問“超圖解 Python 物聯網實作入門- 使用 ESP8266 與 MicroPython” 第13-13 中的書中範例的程式碼, 都會顯示”Can’t conver PWM to int” 請協助(官方下載的範例,未改過)

    10 sr04 = HCSR04()
    11 ledPin = (PWM(Pin(2), freq=1)) # led接在第2腳
    12 led = Signal(ledPin, invert=True)
    >>>
    Traceback (most recent call last):
    File “”, line 12, in
    TypeError: can’t convert PWM to int

  15. 我的電腦的putty畫面跟書本不一樣,字母’O’和數字’0’很像,請問怎麼改?

    1. 書本裡的程式碼採用名叫”Source Code Pro”的開源字體,可在這個網站下載

      字體安裝完畢後,開啟PuTTY,點擊左窗格的Window底下的Appearance(外觀),再點擊字體設定邊的Change(更改)鈕:

      字體設定

      選擇Source Code Pro字體,樣式選擇「標準」,按下「確定」。

      字體設定

      點擊左窗格上面的Session(會談),回到PuTTY主畫面。替這個連線設置取個名字,例如:MicroPython,按下Save鈕儲存。

      字體設定

      日後開啟PuTTY,點擊MicroPython再按下Load,即可載入上面的字體和連線設定。

      相關的程式設計字體說明,請參閱這篇貼文:《超圖解Arduino互動設計入門》的書本封面、插圖與程式字體之Hack

      thanks,
      jeffrey

  16. 1) 使用DOS cmd 編輯甚無效率,書本僅提及Thonny編輯器,未交代如何運作?
    2) ” 書本裡的程式碼採用名叫”Source Code Pro”的開源字體,可在這個網站下載。” 指何網站可下載
    Source Code Pro字體 ?
    3) Flash Download Tools可用3.8.5版,MicroPython燒錄v1.12版後,因無Source Code Pro字型,改用
    先前Python 3 Consolas字型,PuTTY DOS Cmd畫面確是漆黑閃爍 ?

    以上煩請大師回覆

    感謝!

  17. 老師你好,
    我按照P16-30的程式碼Key-in並執行,會跳出如下錯誤。
    Traceback (most recent call last):
    File “C:\Users\ACER\Micropy\FT797\範例程式\ch16\http_basic.py”, line 23, in
    s.send(httpHeader.format(path=path, host=host))
    AttributeError: ‘bytes’ object has no attribute ‘format’

    我有嘗試過使用Spyder跟Thonny等IDE都會有這樣的錯誤訊息出現。直接在Powrshell下執行也會有這樣的問題,請問這個問題要如何解決呢?感謝。

  18. 請問老師,我按照17-25頁的範例把溫濕度計的資料拋到Thingspeak上。發現會出現下列錯誤。
    memoryerror: memory allocation failed, allocating 10134 bytes
    一剛開始都可以正常執行,大約5-6個小時後就會發現資料沒有繼續往上拋。
    網路部份我有確認過沒問題,我做過以下嘗試。
    1.將上拋的頻率延長到30秒。
    2.每5分鐘檢查一次網路是否連線,如果沒有就重新連線一次。
    3.在execption下加入
    import sys
    sys.exit()
    做soft reboot.
    但是現象依然沒有改善。請問老師我應該從什麼地方著手?
    我用的是esp8266-20200911-v1.13.bin的Firmware.
    用的是D1 mini的硬體
    感謝。

    1. 請參考17-17頁的回收記憶體說明,在程式開頭引用gc程式庫:

      import gc
      

      然後在sendDHT11()函式最後加上回收記憶體的敘述,比較前後差別:

      print('before:', gc.mem_free())
      gc.collect()
      print('after:', gc.mem_free())
      

      thanks,
      jeffrey

  19. 感謝老師回應,我有嘗試在sendDHT11()的else底下加入您建議的內容,但是每一次的before還是越變越少,最後仍然是一樣的問題。然後跟您請教一下,為什麼17-25頁的程式 def sendDHT11(t),為什麼這裡要傳t這個參數?函式中並沒有用到阿,我有google一下,發現類似的架構好像都是這樣寫的,但是都沒有解釋為什麼?我嘗試拿掉的話,程式執行會出錯。煩請指導,感謝。

    1. 這樣的話,可能要將讀取溫濕度、上傳thingspeak的程式編譯成.mpy再執行(請參閱附錄B)。
      至於參數t,請參閱8-6頁的定時器說明。

      thanks,
      jeffrey

  20. 感謝老師建議,我參閱了附錄B中的方式要來編譯溫濕度的程式,在WSL中下載了Debian,在make階段遇到了一些問題,勉力解決第一個bash版本的問題之後遇到了第二個問題,實在無頭緒應該要如何下手,還請老師指導。錯誤訊息如下:
    [INFO ] Installing MPFR for host
    [ERROR] gcc: error: : No such file or directory
    [ERROR] make[5]: *** [Makefile:760: set_z_exp.lo] Error 1
    [ERROR] make[4]: *** [Makefile:445: all] Error 2
    [ERROR] make[3]: *** [Makefile:466: all-recursive] Error 1
    [ERROR]
    [ERROR] >>
    [ERROR] >> Build failed in step ‘Installing MPFR for host’
    [ERROR] >> called in step ‘(top-level)’
    [ERROR] >>
    [ERROR] >> Error happened in: CT_DoExecLog[scripts/functions@257]
    [ERROR] >> called from: do_mpfr_backend[scripts/build/companion_libs/110-mpfr.sh@149]
    [ERROR] >> called from: do_mpfr_for_host[scripts/build/companion_libs/110-mpfr.sh@104]
    [ERROR] >> called from: do_companion_libs_for_host[scripts/build/companion_libs.sh@36]
    [ERROR] >> called from: main[scripts/crosstool-NG.sh@646]
    [ERROR] >>
    [ERROR] >> For more info on this error, look at the file: ‘build.log’
    [ERROR] >> There is a list of known issues, some with workarounds, in:
    [ERROR] >> ‘share/doc/crosstool-ng/crosstool-ng-1.22.0-60-g37b07f6f-dirty/B – Known issues.txt’
    [ERROR]
    [ERROR] (elapsed: 16:06.08)
    [16:08] / make[2]: *** [ct-ng:152: build] Error 2
    make[2]: Leaving directory ‘/home/yimean/esp-open-sdk/crosstool-NG’
    make[1]: *** [../Makefile:139: _toolchain] Error 2
    make[1]: Leaving directory ‘/home/yimean/esp-open-sdk/crosstool-NG’
    make: *** [Makefile:131: crosstool-NG/.built] Error 2

    感謝。

    1. 剛剛嘗試在WSL的Debian Linux環境編譯esp-open sdk時,也出現如下的錯誤:

      cubie@Doggie:~/esp-open-sdk$ make
      Makefile:186: warning: overriding recipe for target 'ESP8266_NONOS_SDK-2.1.0-18-g61248df/.dir'
      Makefile:181: warning: ignoring old recipe for t
        
      configure: error: could not find bash >= 3.1
      make[1]: *** [../Makefile:149: _ct-ng] Error 1
      make[1]: Leaving directory '/home/cubie/esp-open-sdk/crosstool-NG'
      make: *** [Makefile:145: crosstool-NG/ct-ng] Error 2:
      

      查閱esp-open-sdk原始碼網站的issues,發現是每個人都會遇到的問題,參考這個連結的說明,把esp-open-sdk/crosstool-NG/configure.ac第193行的敘述改成:

      修改設置檔

      再次編譯並沒有發現問題(先執行make clean清除之前的編譯內容):

      esp open sdk編譯成功

      倒是編譯交叉編譯器時,出現找不到python3的錯誤:

      make: python3: Command not found
      

      所以先安裝python3再嘗試編譯,也沒有問題。

      sudo apt install python3
      

      thanks,
      jeffrey

  21. 感謝老師回覆,我確實沒有進行make clean.
    我重做一次就好了。
    另外,在網友的指導下我也找到問題了,apiURL應該是不需要設成global,把apiURL放進senDHT11裡面問題就解決了。
    其實不需要重新編譯的。
    供您參考。

  22. 老師 你好 慣用Python 結合 樹梅派, 被動元件 建立IoT生態系統 應該選擇這本書還是IoT那本書呢?(因有其他程式語言的concern) 謝謝!

    1. 我目前的硬體控制都是用Arduino和MicroPython程式,樹莓派則用於伺服器。IoT物聯網書籍的主題是JavaScript,我尚未撰寫Python控制樹莓派方面的內容,謝謝。

      thanks,
      jeffrey

  23. 老師你好!
    如果想使用ESP32配合micropython開發
    如果能對應相關引腳的話 是否本書也適用來學習呢?
    謝謝

    1. 可以,ESP32, Micro:bit和新問世的Raspberry Pi Pico (RP2040) 也能用相同的MicroPython語言開發,基本概念都一樣。

      thanks,
      jeffrey

  24. 老師你好
    webprel的部分,不管怎麼試,還是一樣不能打字,我目前版本試v1.14,
    我想說先跳過webprel的部分,但是到gps的部分,我用PUTTY輸入完程式,執行後,
    PUTTY就卡住,按任何按鍵都沒有反應了。
    你在UART連接GPS模組,這部分的說明有寫到 – GPS模組連接實驗,需要搭配webrepl操作
    我想請問,不能用webprel的形況下,還有其他方式可以做gps模組實驗嗎?
    https://drive.google.com/drive/folders/1IsqwRNVYgLlMEE49-kYDyZPpK-5X-2vi?usp=sharing
    (相關圖片,請看上面的連接)

    1. 我剛剛在ESP8266燒錄MicroPython 1.14版韌體,先清除Flash,然後按照6-8頁的步驟重做一次,可以連線WebREPL輸入文字。

      如果你的電腦有安裝防毒軟體,請先取消它試試看,有些防毒軟體會禁止瀏覽器跨網站存取、執行JavaScript。

      thanks,
      jeffrey

  25. 老師你好
    我已經嘗試關閉防毒軟體,但還是一樣的狀況
    如果說先跳過WebREPL這部分
    GPS可以用PUTTY或是其他的軟體來操作嗎?

    1. 我在不同電腦連過N遍都沒問題…建議直接在OLED顯示器顯示GPS內容,或改用ESP32。

      thanks,
      jeffrey

  26. Traceback (most recent call last):
    File “”, line 6, in
    File “esp8266_i2c_lcd.py”, line 25, in __init__
    OSError: [Errno 110] ETIMEDOUT

    在執行後跑出這個錯誤 不知道是什麼問題(使用LCD1602及esp8266做LCD顯示功能,程式碼如下)
    from machine import I2C, Pin
    from esp8266_i2c_lcd import I2cLcd

    DEFAULT_I2C_ADDR = 0x27
    hw_i2c0 = I2C(scl=Pin(5),sda=Pin(4), freq=200000)
    lcd = I2cLcd(hw_i2c0, DEFAULT_I2C_ADDR, 2, 16)
    lcd.putstr(“Hello World ~~”)
    while 1:
    pass

    1. 我沒試過MicroPython接1602 LCD,請確認I2C的接腳或者I2C位址是否有誤。

      thanks,
      jeffrey

  27. 老師不好意思打擾:

    我目前參考書本第 7 章有關網路連線,與第 16 章中有關 socket 的程式,嘗試將兩塊 D1 mini 相互直接連線,分別做為 Server 與 Client 的角色。

    目前在 esptool 燒錄完 MicroPython 的韌體(esp8266-20210418-v1.15.bin)後,並分別利用 ampy 工具,將對應的 boot.py、server.py、client.py 上傳至 D1 mini 開發版後,可以成功連線,並依照預期,透過 Client 端的按鈕,讓 Server 端接收到訊息,並讓 Led 動作。上述動作皆利用 Putty 分別連接到對應開發版,以終端機畫面開啟 server.py 與 client.py 來測試。

    但目前遭遇的問題是,若將開發版連結線從電腦拔除後重新連接,或是在未斷開與電腦的實體連接,但持續執行 client.py 多次後,Server 端仍可順利執行程式,但 Client 端會出現「OSError: [Errno 103] ECONNABORTED」的錯誤訊息,於後續的連線,也皆會出現上述錯誤。

    目前在網路上看到有很多針對這個錯誤的發問,但因為對於 socket 底層運作原理不熟悉,不太能理解其中提及的解決方案,大部份有提及的是 esp8266 的記憶體不夠多,所以需要用到 gc.collect() 或 gc.mem_free() 來釋放記憶體,不過在嘗試後,發生錯誤的情況並未改善。

    現在實驗的結果是,利用 esptool 重新燒錄韌體,並重新上傳對應程式碼後,便可重新成功運作,但從電腦拔除後重新連接,或是在未斷開與電腦的實體連接,但持續執行 client.py 多次後,還是會出現上述提及的錯誤訊息,想請問老師,這個錯誤有無辦法透過程式的方式避免,或是根據某些底層的運作原理,進行改善。

    下方分別為上傳至 Server 端與 Client 端的程式碼,分別皆於 D1 mini 上執行,不好意思再麻煩老師解惑了,感謝。

    Server:
    1. https://github.com/gandolfreddy/esp8266_project/blob/main/server_src/boot.py
    2. https://github.com/gandolfreddy/esp8266_project/blob/main/server_src/server.py
    Client:
    1. https://github.com/gandolfreddy/esp8266_project/blob/main/client_src/boot.py
    2. https://github.com/gandolfreddy/esp8266_project/blob/main/client_src/client.py

    1. 底下是我在ESP8266上的MicroPython伺服器端socket程式,修改了幾個地方:

      1. gc.collect()放入while迴圈
      2. HOST位址改成”0.0.0.0″
      3. 切換led的訊息文字改成”toggle”
      4. 關閉socket的client.close()敘述放在送出’quit’訊息之後
      5. 檔案命名成main.py讓它在開機後自動執行
      6. 啟用13腳的上拉電阻,開機時,若第13腳接地,則不執行socket。如果要上傳新的main.py程式,請在重置板子之前,先把第13腳接地。

      import socket
      import gc
      from machine import Pin
      from time import sleep
      
      def start():
          HOST = "0.0.0.0"
          PORT = 13326
      
          s = socket.socket()
          s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
          s.bind((HOST, PORT))
          s.listen(1)
          print("{} server in {} port is on!".format(HOST, PORT))
          client, addr = s.accept()
          print("Client: {}, Port: {}".format(addr[0], addr[1]))
          led = Pin(2, Pin.OUT, value=1)
      
          while True:
              msg = client.recv(128).decode("utf-8")
      
              print("Receive message:", msg)
              reply = ''
      
              if msg == "toggle":
                  led.value(not led.value())
                  reply = b"Led {}".format(led.value())
                  client.send(reply)
              elif msg == "bye":
                  client.send(b"quit")
                  client.close()
                  break
      
              gc.collect()
              print('Free RAM:', gc.mem_free())
      
          led.value(1)
          
      if __name__ == "__main__":
          sw = Pin(13, Pin.IN, Pin.PULL_UP)
          
          if sw.value() == 1:
              start()
          else:
              print("hello!")
      

      另外,我沿用書本裡的boot.py,開機時連線到本地的Wi-Fi分享器。

      為了方便測試,socket用戶端我是在電腦上執行,client.py的程式碼改成每1秒鐘自動發送’toggle’訊息給ESP8266;若在終端機中按下Ctrl+C,則發送’bye’訊息給ESP8266,它將終止socket伺服器程式。

      client.py的程式碼如下,’192.168.0.101’要改成你的ESP8266的位址。

      import socket
      import time
      
      s = socket.socket()
      s.connect(('192.168.0.101', 13326))
      try:
          while True:
              print('傳遞"toggle"訊息給ESP8266。')
              s.send(b'toggle')
              reply = s.recv(128)
              print(str(reply))
              time.sleep(1)
      except KeyboardInterrupt:
          print('關閉連線')
          s.send(b'bye')
          reply = s.recv(128)
          if reply == b'quit':
              print('關閉連線')
              s.close()
      

      目前測試的結果,ESP8266的剩餘記憶體穩定維持在34816 bytes,請再測試看看。

      thanks,
      jeffrey

  28. 您好
    有關於動手做17-1,17-2
    單純文字沒有問題
    加上DHT11就不行了
    請問我有哪個步驟錯了嗎?
    network config: (‘192.168.88.157’, ‘255.255.255.0’, ‘192.168.88.1’, ‘192.168.88.1’)
    WebREPL is not configured, run ‘import webrepl_setup’
    MicroPython v1.16 on 2021-06-18; ESP module with ESP8266
    Type “help()” for more information.
    >>>
    paste mode; Ctrl-C to cancel, Ctrl-D to finish
    === from machine import Pin
    === import dht, socket
    ===
    === d = dht.DHT11(Pin(2))
    ===
    === s = socket.socket()
    === HOST = ‘0.0.0.0’
    === PORT = 80
    ===
    === httpHeader = b”””\
    === HTTP/1.0 200 OK
    ===
    ===
    ===
    ===
    ===
    === ESP8266 Webserver
    ===
    ===
    === Temperture: {temp}
    === Humid: {humid}
    ===
    ===
    === “””
    ===
    === s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    === s.bind((HOST, PORT))
    === s.listen(5)
    === print(“Web server is running.”)
    ===
    === def readDHT():
    === d.measure()
    === t = ‘{:02}\u00b0C’.format(d.temperature())
    === h = ‘{:02}%’.format(d.humidity())
    === return (t, h)
    ===
    === while True:
    === client, _ = s.accept()
    === temp, humid = readDHT()
    === client.send(httpHeader.format(temp=temp, humid=humid))
    === client.close()
    Web server is running.
    175
    Traceback (most recent call last):
    File “”, line 39, in
    File “”, line 32, in readDHT
    File “dht.py”, line 17, in measure
    OSError: [Errno 110] ETIMEDOUT

    1. 請檢查DHT11的接線,並先執行7-5頁的程式測試看看DHT11能否正常運作。

      thanks,
      jeffrey

    2. 老師您好
      7-1動手做測試是沒有問題的溫濕度都有正常顯示
      我有試著更換不同的控制板也是顯示一樣
      謝謝

    3. 拍謝,忽然想到之前讀者的糾錯:

      swf.com.tw/?p=1129&cpage=3#comment-986037

      diy17_2.py倒數第2行的設定字串格式敘述:

      client.send(httpHeader.format(temp, humid))

      要改成:

      client.send(httpHeader.format(temp=temp, humid=humid))

      或者把httpHeader字串裡的{temp}和{humid}改成{0}和{1},相關語法說明請參閱5-19頁,修改字串設定之後的敘述執行無誤。

      thanks,
      jeffrey

    4. 老師您好
      這個修正我有先前修正過了
      可以看我上面貼出來的程式碼已有修正
      我再試試看httpHeader字串裡的{temp}和{humid}改成{0}和{1}好了
      謝謝

    5. 了解。不過,從錯誤訊息看來,問題是出在你的dht.py檔,讀不到DHT11的資料:

      File “dht.py”, line 17, in measure
      OSError: [Errno 110] ETIMEDOUT

      thanks,
      jeffrey

    6. 老師您好
      7-1-2測試的時候是沒有問題的
      另外Traceback (most recent call last):
      File “”, line 39, in
      File “”, line 32, in readDHT
      File “dht.py”, line 17, in measure
      OSError: [Errno 110] ETIMEDOUT
      這串錯誤碼是當網頁打開IP位置時才會跳出來
      我的設備IP是192.168.88.70,直接在網頁上打上此IP這個步驟沒錯吧?
      謝謝

    7. 你程式的錯誤訊息代表讀不到DHT11的資料,我剛剛測試動手做17-2的範例程式,執行無誤;我的實驗板是把DHT11焊接在腳5,MicroPython韌體版本是1.13。

      自製的ESP8266擴充板

      thanks,
      jeffrey

  29. 老師您好

    我開啟webREPL顯示IP為0.0.0.0
    這樣無法連結webrepl.html
    請問要如何處理

    謝謝

    1. 請問你燒錄的MicroPython韌體是哪個版本?我剛剛燒錄最新的1.6版,按照6-8頁的操作,連線無誤。

      連線WebREPL

      thanks,
      jeffrey

  30. 老師您好

    對網路很陌生
    不知道要用sta.scan()找周邊網路
    現在問題已經解決了
    謝謝老師
    順便提一下
    輸入密碼時毫無動靜
    還以為哪裡又出錯了呢

  31. 趙老師您好:
    我在實作本書1-6章,透過puTTY控制ESP8266時遇到PuTTY會不斷跑亂碼,造成無法打字的問題
    有確認PuTTY上的設定都對,
    燒錄的韌體用書中20171101的版本及最新版的燒錄
    都出現同樣PuTTY無法編寫的情形,想問可能是甚麼原因呢?

    謝謝老師

  32. 老師你好:
    學生是初學者,按照超圖解PYTHON物聯網實作入門書籍,購入WEMOS D1 MNI控制板照書本
    內容P1-24操作”下載與安裝USB驅動程式”, 但是在裝置管理員/連接埠找不到USB SEARIAL CH340
    ,只有原電腦設定的COM1 與 ECP印表機連接埠LPT1, 請問要如何解決? 才能再進入燒錄韌體的階段。
    PS: 已經下載CH341SER.EXE安裝

  33. 老師,已經抓到USB340 (COM3)連接埠了(是MICRO USB 連接線規格的問題)
    接下來的問題,是依照1-5下載與燒錄MICRO PYTHON韌體,寫不進韌體(我是使用
    ESPFlashDownloadTool_v3.6.4燒錄工具

  34. 老師,拍謝!! 我也將韌體燒錄完成了(4bit燒錄非常快!!!哈), 我是再看一遍書內容,進入上海網站下載
    FLASH最新燒錄軟體,但是發現解壓後無8266專用.BIN檔,因此再由網頁找到檔案下載,終至成功燒錄。
    非常感謝你書本精彩、詳盡的說明

  35. 老師,為何我下載最新版PuTTY安裝,總是出現警告”Installation directory must be on a local hard drive.”
    以致無法安裝?

  36. 也不行,我有上網找同樣問題的解答,不過按照他們的方式也無法安裝putty.msi檔(右鍵沒發現系統管理員
    權限),嘗試許久後,就直接下載putty.exe檔安裝。
    Putty的設置畫面下,依照書本1-31頁同樣設定埠號、通訊速率115200、選擇SERIAL後按下OPEN鍵結果….
    一片黑暗,只有左上角的游標點孤零零的待在那,甚麼也沒有!! 按了CTRL+D也是一樣,不知為何?

    1. PuTTY畫面空白,可能是MicroPython韌體沒有燒錄成功。建議改用Thonny IDE試試。

  37. 老師,請教你有關第六章WIFI無線網路的設定,學生依照P6-10打開webrepl.html網頁後按下connect鍵,只見
    黑色銀幕顯出”disconnect”,其他訊息皆無。是否在microPython wifi設定還少了甚麼嗎?以致無法連線。

  38. 老師您好,近日添購MircroPython的STM32F722,想嘗試於物聯網的部分,此本書適合嗎?謝謝您

    1. 不適合,因為至少有三個章節內容跟Wi-Fi網路通訊相關,只適合ESP8266和ESP32開發板,謝謝您!

  39. 如何用郵件聯絡 趙老師
    須詢問相關書籍與開發板
    是否有STM32 相關書籍與 程式

    1. 微電腦控制板的種類和型號眾多,我目前使用的開發板主要是採用ATmega328以及ATmega32u4微控器的Arduino板,以及EP8266和ESP32開發板;ST的板子我很少用,手邊也只有兩、三款。

  40. 感謝老師的指點迷津,進入路由器找到正確IP位置,就可以透過網頁無線連結MicroPython

  41. 老師:
    請問在P4-11上拉電阻迴路,D7腳輸出電壓是1.75DV嗎 ? 另,該頁上拉電阻啟用程式,是否只要執行一回即可?
    爾後Pin 13都會呈輸出狀態?

  42. P4-21動手做4-3用RC電路消除開關彈跳訊號
    電阻使用68K才能完美動作,以上心得分享

    1. 感謝分享!上拉電阻只要設定一次,該腳位就變成「數位輸入」模式。

    1. 請檢查電路是否連接正確,如果ADC的輸入為0,將會導致math.log()函式計算錯誤,因為log()輸入值不能是0。你可以加入一個條件式排除ADC為0的情況,像這樣:

      val = adc.read()
      if val > 0:
          t = temp(val)
          print("temp: ", str(t))
      else:
          print("ADC reading error.")
      
  43. 照書上接的電路圖一個一個接,電路應是沒問題;但upycraft執行後的問題還是一樣(math domain error)
    會不會是類比輸入腳有誤, A0腳是VP腳嗎?

  44. 趙老師你好,我發現16-30頁中間的圖片
    取得列表裡的元’祖’是不是打錯了呢~

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top