超圖解 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. 老師你好:
    我在課本 7-22 頁的部分,照著書上程式碼撰寫
    from machine import UART
    com = UART(0, 9600)
    com.init(9600)

    while True:
    data = com.readline()
    if data and (“$GPRMC” in data):
    print(data)

    測試很多次,都沒辦法進行 $GPRMC 的filter
    每次還是都會把所有的句子print出來
    找不出原因,麻煩老師解答,謝謝

    1. 我剛剛用MicroPython 1.9.4以及1.11版本的韌體測試沒有問題,請問原始字串裡面包含”$GPRMC”嗎?

      MicroPython GPS

      在1.11版的韌體上初始化序列埠之前要先執行dupterm()關閉REPL,避免終端機把序列埠輸入的資料當作命令執行。像這樣:

      from machine import UART
      import uos
      
      uos.dupterm(None, 1)  # 取消REPL功能
      com = UART(0, 9600)
      com.init(9600)
      

      thanks,
      jeffrey

    1. 赵老师,是不是可以这样理解,在给d1 mini 板刷入microPython固件时,其实ssd1306库的二进制代码已经包含在固件里面了,源代码并没有放在固件里,我们需要引用这个库时,只要在代码中import ssd1306 就可以使用了。 如果想要查阅该库的实现,也就是阅读源代码,可以查阅MicroPython在GitHub上的托管。 是这个意思吗?

    2. 是的,ssd1306库的二进制代码在编译MicroPython固件时,一并被包含进去了(请参阅附录B)。

      因为ssd1306不是标准库,所以需要用import叙述引用。

      通常,程序员写好新的库,都会同时编写API的说明文档以及使用例;如果没有,我们只好通过阅读源代码里来理解。

      thanks,
      jeffrey

  2. 老師你好:
    我在課本 9-22 頁的部分,照著書上電路接線

    唯一差別是 : DC-DC板我是用 9V Adaptor接 DC-in孔

    且測試 Pin(13)確實有PWM輸出
    但馬達就是不會轉

    直接拿3號電池接馬達測試也可正常轉動

    不知為何照課本接線,馬達無法轉動,麻煩老師解答,謝謝

    1. 不好意思,請參閱上文底部的勘誤,
      TIP120馬達驅動電路,TIP120的E(射極)要接地,馬達一端要接正電源。

      thanks,
      jeffrey

  3. 老師你好:
    課本 14-4 頁在室外實作後()
    OLED 顯示的 日期、時間 都正確
    但 經、緯 度顯示都是 0
    請問 是哪裡設定錯了嗎,謝謝

    1. 經緯度都是0,應該是GPS模組暫時收不到定位訊號,請再等一陣子或者換個地方,就能收到定位訊號了。

      thanks,
      jeffrey

  4. 赵l老师,您好:
    动手做13-1,书中提到:超声波模组Echo输出5V,但ESP8266接脚只能接受3.3V输入,方法是采用右图电阻分压电路,由于超声波的输出电流很小,我们可只用一个1千欧-3千欧左右电阻达成目的。 对于此处描述这里我有疑惑:1.Echo输出的5V,应该是理论上的5V吧,我觉得IO引脚内部应该也有一个等效的电阻的吧,一旦外部接上分压电路,esp8266引脚真的能分到3.3V吗? 我越想越糊涂,赵老师能给点拨一下吗 2. 文中说只用一个电阻,不用分压,也能达到目的,这是为什么?

    1. 对,请想像串接电阻的另一边接了一个负载(R2),相当于形成一个电阻分压电路。我以前测试连接HC-05蓝牙模块时,用1KΩ、2.2KΩ和4.7KΩ测试,4.7KΩ已经是极限了,电阻值再提高,蓝牙模组就收不到信号了。

      電阻分壓電路

      不过,这种接法仅限于低速通讯(几百KHz以内)线路,I2C之类的高速通讯线路,需要采用如12-25页的MOSFET元件。

      thanks,
      jeffrey

  5. 老師你好:
    課本 9-22 頁的部分,有依照你的回答再次確認過電路接線無誤
    TIP120馬達驅動電路,TIP120的E(射極)有接地,馬達一端也有接正電源。
    Pin(13)確實有PWM輸出
    馬達還是不會轉動
    唯一差別是 : DC-DC板我是用 9V-0.8A Adaptor接 DC-in孔
    請問老師,會是 9V-0.8A Adaptor電流不足,或者是其它問題嗎
    謝謝

    1. 有可能是電流不足,要看是哪一種馬達。你也可以先在MOSFET接馬達的位置,改接一個電阻和LED,看看能否調整LED的亮度。

      thanks,
      jeffrey

  6. 赵老师:
    我在windows 10 的命令行界面下,使用pip install esptool 命令成功安装好 esptool工具。为何在命令行界面中输入:esptool.py — port com4 erase_flash ,系统报错:’esptool.py’ 不是内部或外部命令,也不是可运行的程序
    或批处理文件。 什么原因呢?

    1. 请尝试升级esptool(我的系统有Python 2,所以pip命令是pip3):

      pip3 install –upgrade esptool

      或者先移除已安装的esptool,再重新安装试试:

      pip3 uninstall esptool

      thanks,
      jeffrey

    2. 后来我发现,把这个路径C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\Scripts 加入了系统环境变量path中,就可以执行esptool命令,而且我在命令行界面里输入的是 esptool 并非esptool.py,经测试输入esptool.py 反而报错。

      赵老师:刚才又遇到一个问题:就是用pip安装ampy,提示安装成功,而且我发现ampy.exe这个程序也是在C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\Scripts这里目录里,可是这次我在命令行里输入ampy命令,却报出了一堆错误,我个人感觉应该和esptool一样,为什么却执行不了?错误提示如下:
      Traceback (most recent call last):
      File “c:\users\administrator\appdata\local\programs\python\python35-32\lib\runpy.py”, line 170, in _run_module_as_main
      “__main__”, mod_spec)
      File “c:\users\administrator\appdata\local\programs\python\python35-32\lib\runpy.py”, line 85, in _run_code
      exec(code, run_globals)
      File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\Scripts\ampy.exe\__main__.py”, line 5, in
      File “c:\users\administrator\appdata\local\programs\python\python35-32\lib\site-packages\ampy\cli.py”, line 30, in
      import dotenv
      File “c:\users\administrator\appdata\local\programs\python\python35-32\lib\site-packages\dotenv\__init__.py”, line 2, in
      from .main import load_dotenv, get_key, set_key, unset_key, find_dotenv, dotenv_values
      File “c:\users\administrator\appdata\local\programs\python\python35-32\lib\site-packages\dotenv\main.py”, line 10, in
      from typing import (Dict, Iterator, List, Match, Optional, # noqa
      ImportError: cannot import name ‘TYPE_CHECKING’

    3. 了解,请参阅1-14和1-16页,你应该是忘记勾选「把Python 3.x加入系统路径」的选项了。

      thanks,
      jeffrey

  7. 老师你好:
    请教一个问题,我买了块esp32开发板,刷入micropython固件,我想问如何操控板上的蓝牙呢?有没有简单的范例呢?

  8. 赵老师,您好:
    有一个想法如下,当不知道如何实现?:
    让ESP8266作为AP运行,并启动一个HTTP服务器,并配置HTML页面,用户请求该页面,让用户输入Wi-Fi网络名称和密码,然后esp就可以STA模式用该名称和密码链接wifi,访问互联网。我现在疑惑是:用户POST方式提交的数据,esp服务端是如何获取用户提交的数据呢?赵老师,您是否有相关的demo?或者说get方式也行的吧,esp后端是如何获取用户提交的数据?

  9. 老師你好,想請問有沒有推薦MAC的燒入,灌完micropython 後用uPycraft我的d1mini都是忙線中請問該怎麼解決

  10. 請問在燒錄韌體之前,你有先清除快閃記憶體嗎?
    有的,後來改用screen後是可以燒錄但還是覺得用的不是很方便
    請問老師用esptool.py程式碼都用什麼編寫跟儲存?

    謝謝老師

  11. 老師您好
    在試做第12-20頁執行到這行:oled = ssd1306.SSD1306_I2C(128,64,i2c)
    會出現Error Code如下:
    File “ssd1306.py”, line 99, in init
    File “ssd1306.py”, line 36, in ini
    File “ssd1306.py”, line 61, in init display
    File “ssd1306.py”, line 104, in write cmd
    OSError: [Errno 110] ETIMEDOUT

    請問是什麼問題 謝謝您~

  12. 老師你好
    請問在課本P11-17電路中,我的分壓電阻用 2.2K
    也將11-18中程式改寫成,如下:
    from machine import ADC
    adc = ADC(0)

    def temp(adcV, R0=2200, R25=10000, T0=25, beta=3950):
    from math import log

    r = (adcV * R0)/(1023 – adcV)
    T0 += 273.15
    return 1/(1/T0 + 1/beta*log(r/R25)) – 273.15

    val = adc.read()
    t = temp(val)
    print(“temp:”, t)

    但抓到的溫度值,都只有19.xxx度
    試過許多次,也檢查了接線
    麻煩老師指導,謝謝

    1. 根據你的自訂函式參數,最後一行的return應該改成:

      return 1/(1/T0+1/beta*math.log(r/R25))-273.15

      請用三用電錶測量熱敏電阻的電阻值,在不同溫度底下,它的阻抗應該要有變化。

      thanks,
      jeffrey

  13. 赵老师:动手做15-5连接sd记忆卡,在import sdcard 模组时,提示‘no moudle named ‘sdcard’ ’ 我用help(‘modules’)列出microPython固件中的模块,的确没有sdcard模块,这个固件我是从microPython官网下载的固件安装包,按书本上提示烧录的,老师你是从哪里下载的?用的是哪个版本呢? putty上提示:MicroPython v1.11-8-g48dcbbe60 on 2019-05-29; ESP module with ESP8266

  14. 老師你好
    請問在課本P12-14的應用,如何將I2C讀到的熱敏電阻值換算成實際溫度值,謝謝

    1. 我們需要幾項數據才能轉換出正確值:

      熱敏電阻的規格
      分壓電阻(R0)的值
      PCF8591的類比數位轉換值是8位元,0~255。

      根據賣家提供的電路圖,分壓電阻是1KΩ,但沒有註明熱敏電阻的規格,請修改11-17頁的熱敏電阻轉換公式,1023改255,R0改1K試試。

      thanks,
      jeffrey

  15. 赵老师:
    注册ThingSpeak账号,页面提示输入,Email address: 我输入的是大陆网易163邮箱,其它几个栏位按要求填入,点击continue,页面提示警告:Personal Email Detected :To use your organization’s MATLAB, enter your work or university email 。 不过下方有个勾选框,Use this email for my MathWorks Account ,我勾选后,点击继续。注册成功。问题现在我点击登录页,输入email,点继续,没有任何反应。而且整个注册过程中,没有提示我设置登录密码。我现在用翻墙软件,访问登录页,输入email,点继续,提示我输入登录密码????问题是我在注册的过程中,根本就没有设置过登录密码呀。
    赵老师,您是怎么注册账号的呀?? 有没有可用账号分享一个

    1. 蛤?为何ThingSpeak网站会被和谐?
      我记得注册帐号之后,它会寄出一封确认邮件,请检查看看是否被丢到垃圾分类里面了。

      thanks,
      jeffrey

  16. 老師你好:
    請問課本P12-27的圖像和文字,老師是用什麼軟體編輯。
    因為我用小畫家編輯出來的文字,最後在OLED上顯示出來,都是缺邊缺角的。
    謝謝。

    1. 開啟小畫家之後,選擇主功能表的「檔案→內容」,把影像檔色彩設定為「黑白」。

      影像內容設定

      存檔時,選擇「檔案→另存新檔」,「存檔類型」選擇「單色點陣圖」。

      另存新檔的單色點陣圖設定

      thanks,
      jeffrey

  17. 老師你好:
    請問課本P13-13
    led = Signal(ledPin, invert=True)
    上列這行程式執行後,會顯示
    TypeError: can’t convert PWM to int
    請問應該如何修改,謝謝。

    1. 也許是韌體的bug,因為1.11版的Signal指令說明文件也提到它支援PWM物件。

      請把PWM設定敘述改成:

      led = PWM(Pin(2), freq=1000) # led接在第2腳

      然後刪除Signal()的敘述;LED元件改成外接(要串接一個電阻,參考3-24頁的電路)。

      另外,我後來測試SR04超音波感測器,可以採3.3V供電,如此,Echo腳也就不必串接電阻。

      thanks,
      jeffrey

  18. 老師你好:
    我照著課本 P15-8接線,程式碼也和課本 P15-14相同
    但實際執行後,LED矩陣 沒有被點亮
    請問應該如何修改,謝謝。

    1. 書本的程式和接線沒問題,請檢查你的線路是否接觸不良。

      thanks,
      jeffrey

    2. 不好意思,我也遇到一樣的問題,我也很確定硬體連接正確,沒有接觸不良. 但LED沒有反應. 請問應該如何debug? 請問要如何透過SPI指令讀取MAX7219確認數值真的有寫入?

    3. 底下照片是依照15-8頁的接線,執行diy15_2.py程式的結果,測試無誤。

      MicroPython LED矩陣

      MA7219不會回應收到的資料,若要檢查電路的訊號是否正常傳送,可用邏輯分析儀檢測,不過我們一般都不會買這種儀器;若接線確認正確無誤…那應該是模組本身有問題。

      thanks,
      jeffrey

    4. 你好,我找到問題了, 增加baudrate設定後, 就都可以正常工作了: spi = SPI(1, baudrate=600000)
      謝謝

  19. 趙老師您好,
    我是您Python物聯網的忠實讀者,從您書上獲益深廣,至為感謝 !
    近日想試試PM2.5感測電路的實作,鎖定了sharp之GP2Y1051AU0F感測元件,
    找了網路上相關的資源,也接上了線路,但始終無法獲取來自GP2Y1051AU0F
    的data, 查了相關的網路訊息,也把TX0/RX0給讓出來,利用WebREPL進行連線
    開發,也將 baudrate設定為2400,但未能成功讀到任何資料,煩請您賜教啊~
    至為感謝 !
    我的測試code如下 :
    ———————————-
    from machine import UART
    def run()
    serial = UART(0, 2400)
    serial.init(2400)
    # ———————–
    while True:
    data = serial.read()
    if data:
    print(data)
    else:
    print(“.”)
    ———————————-

    1. 拍謝,我手邊沒有這個用序列埠傳送空氣品質的檢測模組,無法驗證,上網查了一下相關模組,有些需要先傳送訊號給它,點滅PM 2.5感測器裡的LED,才能進行測量。

      thanks,
      jeffrey

  20. 老师您好 请问我可以将您书中的部分插图用于我的硕士毕业论文中吗

  21. 老師你好,
    課本P16-30,也就是範例程式 diy16_2,亦即直接建立位元組字串的方式
    實測無法正確執行,實際回應如下:
    74
    HTTP/1.1 400 Bad Request
    Date: Tue, 10 Dec 2019 12:00:10 GMT
    Server: Apache
    Content-Length: 417
    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.

    Apache Server at box5680.bluehost.com Port 80

    請問老師,有什麼地方可加以修正嗎?
    謝謝。

    1. 拍謝,那是我的網站伺服器最近更新了,MicroPython程式連到MicroPython.org網站提供的測試網址沒問題:http://micropython.org/ks/test.html

      連到我的網站,HTTP標頭欄位後面要用”\r\n”,不可只用”\n”結尾。所以請把HTTP標頭改成:

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

      thanks,
      jeffrey

  22. 老師你好,
    課本P16-35,即範例程式 https
    如果也按照老師上述所教 : HTTP標頭欄位後面要用”\r\n”,不可只用”\n”結尾
    並且以老師的網址下去做測試,實際回應如下:
    ssl_handshake_status: -40
    Traceback (most recent call last):
    File “”, line 12, in
    OSError: [Errno 5] EIO

    請問老師,應該如何修正
    謝謝。

  23. 老師你好,
    課本P17-18,將程式貼入終端機執行,實測無法正確執行,回應如下:
    Traceback (most recent call last):
    File “”, line 86
    SyntaxError: invalid syntax

    line86 是 f = open(WWWROOT+fileName, ‘r’)
    我看不出哪裡有錯,請問老師知道問題在哪嗎?
    謝謝。

  24. 老師你好,
    在你的網站,網址 https://swf.com.tw/?p=1201
    有一篇教學文章 : 使用select()改寫存取網頁檔案的MicroPython網站伺服器程式

    我實作後發現在瀏灠器上會發生:
    只顯示,歡迎來到MicroPython世界!
    底下的圖片就顯示不出來了。

    但如果是以 原本 課本17-14頁的程式執行,是沒問題的
    請問老師,程式哪裡有問題需要修改嗎?
    謝謝。

  25. 老師你好,
    關於上一個問題,即
    在你的網站,網址 https://swf.com.tw/?p=1201
    有一篇教學文章 : 使用select()改寫存取網頁檔案的MicroPython網站伺服器程式

    我剛剛實際用:
    1. 筆電上的Chrome browser,大約5次成功傳圖1次,共實測50次
    2. 手機上的Chrome browser,大約5次成功傳圖4次,共實測50次
    以上資訊,謝謝

    1. 我剛剛把select()的超時秒數設定成2和3測試:
      Windows 10的Chrome瀏覽器沒有載入圖檔的機率很高
      Android的Chrome約1/10
      iOS版的Safari瀏覽器約1/10
      Windows 10的Edge瀏覽器沒問題

      thanks,
      jeffrey

    2. 剛才改用ESP32上傳本文的程式碼,在電腦和Android手機的Chrome測試沒問題,
      本週我會更新文章說明。

      thanks,
      jeffrey

  26. 感謝老師之前回答的問題,目前使用書上wifi網頁控制程式都沒問題了,自己增加了時鐘模組、溫濕度等程式進入,會發現記憶體不足問題,我也更改為ESP32模組下,還是發生記憶體不足問題,請問有其他型號或方法擴充記憶體嗎?

    1. 如果無法精簡程式的話,我會改用Arduino(C/C++語言),MicroPython使用方便,但是Python直譯器會佔用記憶體空間。

      thanks,
      jeffrey

  27. 老師你好!
    程式中

    MicroPython

    其中img src=”img/python.png”路徑中的圖片無法正常顯示請問是什麼原因,如果把路徑換成圖片網址才可以正常顯示。期待您的回答謝謝您。

  28. 請問一下我在安裝完putty, 依照書中指示填入參數按open後。視窗開啟不會出現命令提示字元,而是一直直在scan. 請問是為什麼呢? 網路上好像沒看到類似的問題。

    1. 我也沒遇過這個情況,請問在燒錄MicroPython韌體之前,你有先清除Flash,快閃記憶體容量有選擇成32Mbit嗎?

      thanks,
      jeffrey

  29. 老師您好!
    請問如果ESP設為網路卡時,連接無線基地台為192.169.4.1,要指定自己的IP位置如:192.168.4.10,請問要如何設定?

  30. 請問老師:
    依書本中的13-19 頁,接好WEMOS 馬達擴展板和D1 Mini, 也將擴展板待機接脚, 接到了D1 Mini 的3.3V 接脚(尚未接馬達電源及馬達)
    但因所附的擴展板的插槽是母的, 所以我接只能是擴展板在下, 而D1 Mini在上
    書中的圖則是擴展板在上, 而D1 Mini在下
    連接USB 線至D1 Mini 後, 我想先SCAN一下擴展板的I2C 位址
    所以我用在WINDOWS 執行Putty, 並使用終端機輸出下述指令:
    from machine import I2C,Pin
    i2c=I2C(scl=Pin(5),sda=Pin(4),freq=100000)
    i2c.scan()
    但結果回傳的卻是空的List
    []
    表示並未SCAN到該擴展板的I2C 位址
    想請問老師可能原因為何??

    Steven

    1. 通常是因為模組上的32位元微控器沒有燒錄所需的韌體,請參閱13-23頁說明。

      thanks,
      jeffrey

  31. 請問老師:
    我依13-23頁說明, 燒錄了motor_shield.bin 至32位元微控器, 再重新接回D1 Mini
    並使用終端機輸出下述指令:
    from machine import I2C,Pin
    i2c=I2C(scl=Pin(5),sda=Pin(4),freq=100000)
    i2c.scan()
    但結果回傳的仍是空的List
    []
    想確認一下:
    1. scan I2C address時, 馬達的電源有必要接到motor shield?
    2. motor shield 的接脚S, 是不要接到3.3 V
    另外在網路上有看到一些針對該motor shield 韌體有Bug的文章, 且有人寫了新的韌體
    是否和這有關??

    Steven

    1. 掃描I2C週邊時,馬達驅動板的電源只要接3.3V和接地,馬達的電源和SS不用接。

      目前最新的WEMOS馬達驅動板是2.0版,我買的是1.0板,燒錄書本附帶的韌體沒有問題。

      請用電錶的歐姆檔,測量馬達驅動板的STM32F03微控器的19和20腳,看看是否有連接到SDA和SCL腳。

      thanks,
      jeffrey

  32. 請教老師:
    我另買一台馬達驅動板,燒錄https://hackaday.io/project/18439-motor-shield-reprogramming的新韌體
    再去scan I2C位址, 這次可以Scan 到[48],正常
    但依老師的接線接好馬達
    並燒錄wemotor.py 及hcsr04.py 到D1後, 再燒錄13-29 的程式成main.py 至D1,
    重置D1 後, 用Putty 去看, 發現setMotor原來是寫:
    motor.setMotor(wemotor.CW)
    Puttyutty告知少了一個參數, 所以我修改主程式中的setMotor加入轉速, , 如下:
    motor.setMotor(wemotor.CW,50)
    再重燒錄後Reset D1
    發現hcsr04 有測到距離, 但馬達驅動板卻沒法子驅動馬達
    我也有接S 接脚至D1 3.3V, 也有另接6V 的馬達電源, 但馬達卻不會動
    但程式也沒有當掉
    是否這一版的wemotor.py 有bug?? 還是我那做錯了
    請老師指導

    Steven

    1. 抱歉,13-29頁的馬達設定,要像13-22頁的setMotor()方法的說明,加上速度參數,感謝告知!

      我用最新的MicroPython韌體(1.8.12),加上書本的馬達控制板韌體以及wemotor.py測試,沒問題。請先依照13-22頁的說明測試馬達轉動。

      thanks,
      jeffrey

  33. 請教老師:
    MicroPython ESP8266 韌體在官網中的最新版本為esp8266-20191220-v1.12.bin
    我用的是這一版本的韌體, 測試結果馬達不動, 且也有用Putty,以13-22頁的說明測試馬達轉動
    但馬達不動
    老師所提的MicroPython韌體(1.8.12),指的是esp8266-20191220-v1.12.bin ??

    Steven

    1. 哎…我又打錯字了,是1.12版沒錯。請問你有試過書本的馬達驅動板的韌體版本嗎?

      thanks,
      jeffrey

  34. 請教老師:
    我在Putty中, 輸入:
    >>> from machine import I2C, Pin
    >>> import wemotor
    >>> i2c = I2C(scl=Pin(5), sda=Pin(4), freq=1000)
    >>> i2c.scan()
    [48]
    >>> i2c.writeto(0x30,b’\x10\x02\x03\xe8′)
    0
    最後一行指令, 依書上說明, 應會使馬達以轉速1000, 以逆時針轉
    但它return 0, 且馬達未作動, 請問老師 return 0 的意義是??

    steven

    1. 你的I2C頻率設定太低了,請改成100000。

      i2c.write()的傳回值是寫入的位元組大小,以底下令馬達B以轉速5000,逆時針方向旋轉的敘述為例:

      i2c.writeto(0x30, b’\x11\x02\x13\x88′)

      它的傳回值是4,因為送出的資料是4個位元組。

      thanks

  35. 請教老師:
    依老師指導, I2C頻率改成100000, 重測已能回傳4
    但馬達仍是不動
    那表示I2C 通訊沒有問題, 接下來應是STM32F03 控制TB6612FNG 為何不WORK
    假設馬達驅動板的韌體沒問題, 先請老師協助確認接線:
    1. 待機的接脚固定接到D1 3.3V
    2. 待機接脚後的4個接脚, 依序接左馬達+,-; 以及右馬達-+
    3. 第6支接脚接外接電源- (外接4個1.5V 乾電池)
    4. 第7,8 支接脚不接(因擴展板有二個GND,二個VM, 所以我只任取2個來接)
    5. 第9支接脚接外接電源+
    感謝老師協助

    Steven

  36. 老師您好:
    我用d1 mini pro執行程式時,經常會遇到自動復位的問題。
    如下(cause有時是4)
    ets Jan 8 2013,rst cause:2, boot mode:(3,6)
    load 0x40100000, len 31088, room 16
    tail 0
    chksum 0x44
    load 0x3ffe8000, len 1028, room 8
    tail 12
    chksum 0x1e
    ho 0 tail 12 room 4
    load 0x3ffe8410, len 824, room 12
    tail 12
    chksum 0x89
    csum 0x89
    可以請教如何解決嗎?
    感謝老師

    1. 請問你燒錄韌體時,快閃記憶體的容量是選擇32Mb (4MB) 嗎?雖然pro板的快閃記憶體是16MB (128Mb),但是ESP8266版的MicroPython的預設Flash容量是32Mb。

      如果要充分運用128Mb容量,可能要自行從原始碼編譯一個,請在make命令(參閱B-10頁)後面加上FLASH_SIZE=128m參數試試看:

      make FLASH_SIZE=128m

      thanks,
      jeffrey

  37. 16-31頁,執行結果如下,請問原因為何?
    74
    HTTP/1.1 400 Bad Request
    Date: Tue, 24 Mar 2020 09:02:02 GMT
    Server: Apache
    Content-Length: 417
    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.

    Apache Server at box5680.bluehost.com Port 80

    >>>

  38. 老師的書真的很淺顯易懂,不知老師有沒有規劃寫一本有關 raspberry pi/jetson nano這類的書呢?

  39. 我曾於2020/3/24提出: 16-31頁,存取未加密網站,出現異常(Bad Request),請問原因為何?
    經多日檢查: 發現範例程式中, httpHeader宣告有小問題,Host: {host}中的”:”與”}”必須留一個空白,才可執行成功,如下所示。
    httpHeader = b”’\
    GET /{path} HTTP/1.0
    Host: {host}
    User-Agent: MicroPython

    HTTP/1.1 200 OK
    Server: nginx/1.10.3
    Date: Mon, 30 Mar 2020 07:59:27 GMT
    Content-Type: text/html
    Content-Length: 180
    Last-Modified: Tue, 03 Dec 2013 00:16:26 GMT
    Connection: close
    Vary: Accept-Encoding
    ETag: “529d22da-b4″
    Accept-Ranges: bytes

    Test

    Test
    It’s working if you can read this!

    ”’

  40. 更正: 16-31頁,執行結果如下,已找到原因:

    httpHeader宣告:
    Host:與{host}中間,”:” 與 “{“ˋ中間要留一個空白。

    1. 這幾天又測試了16-31頁,發現:
      Host:與{host}中間,”:” 與 “{“ˋ中間要留一個空白。
      執行結果又失敗了,所以上次正常執行只是巧合。
      FYI

  41. 趙老師您好
    在超圖解Python物聯網p17-10提到, 在HTTP 1.1版標頭欄的Connection預設為Keep-Alive, 所以在一次client與server的連線中會進行多次的client請求與server回應才會將連線關閉

    這裡有一個問題想請教您

    Q: 請問連線是指socket連線嗎?

    Note: 如果上述是對的, 也即該連線是指socket連線, 那麼我試過在server回應標頭欄的Connection也設為Keep-Alive, 並在第一次請求後故意不將該client的socket物件給close掉, 但在這之後我就收不到任何client請求了。我想實現看看Keep-Alive的機制, 是否有哪個環節我搞錯了呢?

    再麻煩老師您解惑了, 查了好多資料試了好多次都沒有成功QQ

    底下是取得client的socket物件的局部程式碼, 也是改自您的範例程式
    client = s.accept()[0] #accept client socket
    while True:
    print(“接受client socket : “, client)
    handleRequest(client) #handle client
    #client.close()
    #gc.collect()

    1. 不,連線指的是底層的TCP連線,socket是在連線上面傳遞的訊息內容。

      如果你想讓用戶和伺服器端的連線保持暢通,即時交換訊息的話,可以採用WebSocket技術;BetaRavener先生寫了ESP8266適用的MicroPython Websocket伺服器,範例檔名是websocket_demo.py,執行之前要先連同test.html, ws_connection.py和ws_server.py檔一起上傳到ESP8266。

      thanks,
      jeffrey

  42. 趙老師, 您好,
    我今天購買這本書,
    針對封面提到的,
    ‘D1 mini (ESP8266) 控制板 (已焊好針腳) 購買網站 http://www.flag.com.tw/FM999D.asp
    上面網址無法進入,
    其實, 我的重點是, 除了上述建議網址可購買ESP8266相關產品之外,
    您有無其他推薦的建議的網址 ?

  43. 趙老師, 您好,

    請問我有個想法如下,

    ESP8266用在我的主程式,

    我的主程式大致說明如下:
    1.用到lib:
    Pyvisa, 控制測試儀器行為.
    Pyserial, 讀取待測物的 comport log, 並寫入指令.
    2.主程式流程, 先 Pyvisa 控制測試儀器再 Pyserial 讀取/寫入待測物的 comport.

    我的需求: 希望能把 ESP8266 的控制程序 (預計控制伺服馬達) 加進上述主程式流程的 Pyvisa 與 Pyserail之間,
    不知這該怎麼做 ? 或是有個研究方向?

    抱歉, 因只大致看過你書中的應用, 並無看到上述的應用, 所以發訊息詢問.

    1. 1. 書本或單一網站不可能囊括所有專案和應用,而且大多數人都沒有監控高端儀器的需求。
      2. 如果是尚未熟悉程式語法或控制板的輸出入控制,建議從基本著手。
      3. 先完成一小部份功能,再把它們組合起來。例如,先寫好把序列埠資料寫入log文字檔的功能,接著嘗試讀取、解析log檔、然後處理log資料,像是依照資料內容控制伺服馬達…

      thanks,
      jeffrey

  44. 趙老師, 您好,

    其實上述是我工作上有用到的應用,
    目前我只剩下ESP8266的控制程式合進我的主程式 (主程式已經完成),

    有先在網上搜尋類似案例,

    作者是用tkinter控制GUI控制步進馬達,
    如下連結,
    https://www.wolfaiottw.com/python-tkinter-gui%e6%8e%a7%e5%88%b6%e6%ad%a5%e9%80%b2%e9%a6%ac%e9%81%94/
    他是用pyserial把string轉byte再傳給控制板,
    只是這方法您是否有試過可用在ESP8266 ?

    1. 了解,所以問題聚焦在「微控器序列通訊」。UART是共通規範,所以每個控制板的連線方式都一樣,資料也都是以一個個位元組(byte)方式序列傳遞;跟你使用的控制板和程式庫無關。

      你可以自訂序列資料格式,例如,假設從電腦端發送兩個伺服馬達的轉動角度資料,資料格式可像這樣,兩個角度值中間用逗號區隔,最後用‘\n’字元結尾:

      “馬達1角度,馬達2角度\n”

      控制板收到資料之後,拆解出其中的角度值即可控制伺服馬達。

      thanks,
      jeffrey

  45. 趙老師, 您好,
    關於你提供的建議,
    我應該會朝兩個UART port控制的方向來寫程式,
    1. 我的DUT(待測物) 有 UART TX/RX port, 已佔一組 COMport, 負責讀log與寫入指令用途.
    2 .ESP8266, 也會佔一組 COMport, 接收來自PC端的控制訊號.

    這幾天在找我空閒時再試試,

    謝謝

  46. 課本範例diy17_2.py執行後,用瀏覽器瀏覽時會出現下列錯誤:
    Web server is running.
    Traceback (most recent call last):
    File “”, line 54, in
    KeyError: temp

    發現必須把主程式中無窮迴圈的client.send(…)中.format的參數設為(temp=temp, humid=humid),如下所示,採可正常執行:
    client.send(httpHeader.format(temp=temp, humid=humid))
    此外: 副程式readDHT()的回傳值是tuple: return (t, h),建議主程式在呼叫時也應把回傳值存到tuple,如下,(雖然沒有存到tuple也可以正常執行)。
    (temp, humid) = readDHT()

  47. 我將書籍中所13-19~13-26都做過一次無誤,但掃描I2C也是空集合
    上傳程式碼執行也是正常但馬達不動,爬了大家的問題,將wemotor.py點開後發現這一段
    針對書籍中提供範例的wemotor.py裡面寫到
    class Motor:
    def __init__(self, motor, i2c, address=0x30, freq=1000, standbyPin=None):
    當中的freq=1000是不是有誤?
    是否需要改為100000後重新用ampy放入D1 mini中

    1. 1000是PWM的頻率,跟I2C通訊無關。請問你的馬達控制板有燒錄韌體嗎?

      thanks,
      jeffrey

發佈留言

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

Related Posts

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

Back To Top