《超圖解Arduino互動設計入門》補充資料、勘誤及目錄大綱

本文補充《超圖解Arduino互動設計入門》書籍的技術文件資料下載連結、勘誤以及目錄大綱。

《超圖解Arduino互動設計入門》書籍封面

《超圖解Arduino互動設計入門》的目標是讓高中以上,沒有電子電路基礎,對微電腦、電子DIY 及互動裝置有興趣的人士,也能輕鬆閱讀,進而順利使用Arduino 控制板完成互動應用。因此,實驗用到的電子和程式觀念,皆以手繪圖解的方式說明。

書中涉及某些較深入的概念,或者和「動手做」相關,但是在實驗過程中沒有用到的相關背景知識,都安排在各章節的「充電時間」單元(該單元的左上角有一個電池充電符號),像第三章 3-26 頁「記憶體類型說明」,讀者可以日後再閱讀。

充電時間

《超圖解 Arduino 互動設計入門》基本資料:

各大網路書店與購物商場連結:

內容勘誤

【2013/04/07 更新】

  • 9-25頁:第二段,600µs (毫秒…,正確的單位名稱是微秒
  • 13-4頁:表13-1上方的說明文字,「對照表(單位.png) Hz)」,當中的 ".png)" 是多餘的。
  • 14-12頁:內文提到的AccessPort軟體,並未收錄在書本DVD光碟,請讀者到AccessPort的官網(sudt.com)下載
  • 15-27頁:底下的程式片段:

    正確是:

  • D-13頁:4N25電路圖底下的「接TRIAC的T1腳」,正確是「接TRIAC的A1腳」。有些廠商的TRIAC元件用A1和A2來標示陽極腳位,有些則標示成T1和T2(代表Terminal 1, 終端腳1)。

【2013/04/08 更新】

  • 5-4頁,第一行「序列埠通訊視窗」,正確是「序列埠監控視窗」。
  • 14-10頁,實驗說明裡的「序列埠通訊視窗」,正確是「序列埠監控視窗」。
  • 18-10頁,RFID麵包板電路組裝圖中的蜂鳴器元件是多餘的。
  • 附錄E,"BTRobotControl.apk"(藍牙遙控機器人APP)無法送出「左轉」訊息,請參閱這篇文章,下載修正之後的APP和原始檔。

【2013/04/20 更新】

  • 10-24頁,倒數第二段最後一行,「反電動式損害電晶體」,正確是「反電動勢…」。
  • 10-31頁,第一段第一行中的「表 10-4 」,正確是「表 10-5」。

【2013/04/27 更新】

  • B-7頁:第一段倒數第二行,「參閱動手做 B-2」,正確是「動手做 B-1」。

【2013/04/30 更新】

17-34頁:書本裡的程式是正確的,但是光碟的”接接樂Firmata.fla”程式有誤(main場景的34~38行):

function receiveData(e):void  // 接收Arduino的資料
{
   var n:Number = Number(e.data);
   bian.moveX(n * 0.54);
}

請將上面的敘述改成書本17-34頁的敘述:

function readAnalog(e:ArduinoEvent):void  // 接收Arduino的資料
{
   var n:Number = Number(e.value);
   bian.moveX(n * 0.54);
}

然後,在25行的這一行敘述:

var a:Arduino = new Arduino("127.0.0.1", 5331);

後面新增底下的敘述(請參閱17-33頁說明):

a.addEventListener(ArduinoEvent.ANALOG_DATA, readAnalog);

【2013/05/13 更新】

第九章並接式LCD中,初始化LCD程式庫,設定接腳的程式有誤,9-5頁的接線圖是正確的。9-6的程式碼有誤:

錯誤的初始化LCD程式庫,設定接腳的程式。

正確的LCD資料腳位設定敘述如下:

正確的初始化LCD程式庫,設定接腳的程式。

影響的內文(頁數):9-6, 9-7, 9-12, 9-18和9-23。

【2013/05/19 更新】

  • 5-10頁,中間的圖說「封包(package)」,正確是「封包(packet)」。
  • 10-22頁,NPN型的電晶體將負載接在C腳(集極),PNP型電晶體…,應改成「NPN型的負載接在電源端;PNP型的負載接在接地端。」

【2013/06/29 更新】

  • 8-16頁8-17頁的MAX7219矩陣LED麵包板的第7腳,接線有誤,正確是:

組裝MAX7219 LED矩陣電路麵包板

  • B-4頁補充:使用UNO板燒錄Bootloader(開機啟動程式),在插上10uF電容之前,請先上傳B-3頁說明的ISP程式。上傳ISP之後,執行燒錄之前,請從Arduino軟體的「工具→板子」選單,選擇要燒錄的bootloader版本,以B-2的範例而言,請選擇Arduino Duemilanove w/ATmega328

【2013/07/18 更新】

  • 10-9頁,timer 2 對應的腳位是數位311腳,其PWM頻率設定語法為:
    TCCR2B=TCCR2B & 0b11111000 | 0×02;
  • D-13頁,4N25的橋式整流電路正確是:

    4N25零交越檢測電路

    為了避免橋式整流器部分接錯,同時減少接線,可以採用現成的「橋式整流器」,如下:

    4N25零交越檢測電路

    橋式整流器有多種耐電壓和安培規格,選購時,至少選用400V/1A。它的外觀有圓有扁,上面有交流和+, -符號。

【2013/07/21 更新】

【2013/08/28 更新】

  • 2-3頁,第二段最後的單位”mA”,正確中譯為「毫安培」。
  • 3-18頁,表3-1,類型boolean佔用記憶體大小寫著「1位元」,實際是佔用8位元。
  • 4-20頁,倒數第三段第二行,「源流(Source Sink)」正確是「源流(Source Current)」。
  • B-12頁,圖片中的”DTS”標示,正確是”DTR”。

【2013/09/10 更新】

B-9頁,電路圖的正確接法如下:

【2013/11/07 更新】

7-6頁,中間的圖解,"abcdefg"的順序有誤,更正如下:

在Arduino的埠D輸出七段LED訊息

8-10頁,MAX7219的要點補充說明:需要搭配「共陰極」LED;在MAX7219的規格書「一般說明」(第一段文字)寫著:”common-cathode display drivers”(共陰極)驅動器。

8-35頁,「動手做8-6」的LED矩陣逐字捲動效果程式,並無法顯示文字,請在此下載更新後的diy8_6程式,程式修訂說明請參閱此留言

補充說明:使用MemoryFree.h程式庫檢查剩餘的主記憶體空間

Arduino有個MemoryFree.h程式庫,可檢查目前可用的記憶體量。下載並存入libraries資料夾之後,可在程式中透過MemoryFree.h的freeMemory()函數,傳回可用的主記憶體位元組(byte)數。如範例程式所示:

#include <MemoryFree.h>   // 引用程式庫

// 佔用14位元組的字串資料(含結尾的null字元)
char str[] = "Hello, world!";

void setup() {
   Serial.begin(9600);
}

void loop() {
   Serial.println(str);
   Serial.println(freeMemory());  // 顯示剩餘的記憶體量
   delay(1000);
}

用類似的方式,執行舊的diy8_6程式,序列監控視窗將顯示負值,代表記憶體空間不足:

剩餘的記憶體數量

在更新後的程式上測試,則得到如下的結果:

剩餘的記憶體數量

D-12D-14頁的動手做D-1單元,所採用的「零交越檢測元件」,正確的編號是H11AA1(書本內文多寫了一個1),接MOC3020M第1腳的電阻是它內部LED的限流電阻,電路圖上畫的是180Ω,但我實際在板子上焊接的是1KΩ電阻(如下圖)。其實跟外部的LED一樣用470Ω電阻或330Ω就好了,180Ω也可以。

焊接在萬用PCB板的交流電調光器

更新後的調光器電路圖:

交流電調光器電路圖

資料文件與視訊影片下載

  • 最新版本的Arduino開發工具軟體,請到Arduino官方網站下載。
  • 第五章提到的ASCII字碼對照表,請參閱維基百科的ASCII條目
  • Arduino創始人在TED大會的演說 (Massimo Banzi: How Arduino is open-sourcing

  • 導演Rodrigo Calvo和Raul Alejos拍攝了一部紀錄片Arduino: The Documentary(有英文和西班牙文字幕),由Arduino的創始者訴說Arduino的誕生過程,還有運用Arduino製作出開放軟/硬體原始碼的3D印表機"MakerBot"的創辦人Zach Smith,和其他互動設計師的訪談紀錄,以及在工廠大量生產Arduino微電腦的片段。

電子零組件的技術資料下載

原本計畫收錄在書本光碟鋰的技術資料文件,為避免涉及著作權問題,在此提供連結(皆為PDF格式)。

第三章「Arduino互動程式設計入門」,ATMEL公司的"Efficient C Coding for AVR"(直譯為:AVR 晶片的高效 C 程式設計)技術文件

第六章「類比信號處理」,運算放大器(OP-Amp)技術文件:LM358LM741

第七章「LED七段顯示器」,8位元位移暫存器(shift register)74HC595

第八章「LED矩陣與SPI介面控制」,SPI介面的8個七段顯示器,或者一個8×8 LED矩陣顯示器驅動ICMAX7219

第九章「LCD顯示器+溫濕度感測器+超音波感測器」:

第十章「變頻控制LED燈光和馬達」

第十二章「紅外線遙控與縮時攝影控制器」,紅外線遙控訊號接收元件TSOP4838

第十三章「製作光電子琴與MIDI電子鼓」,TCRT5000紅外線反射型感測器

附錄C,光耦合元件PC817

附錄D,TRIAC元件BTA12-600B

《超圖解Arduino互動設計入門》目錄

第一章 認識Arduino

  • Arduino 微電腦板
  • Arduino 的相關軟體
  • Arduino 開發環境安裝
  • 上傳「LED 閃爍」範例程式

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

  • 電壓、電流與接地
  • 微電腦板的電源供應器
  • 電阻
  • 電容
  • 二極體
  • 發光二極體(LED)
  • 看懂電路圖
  • 電子工作必備的量測工具:萬用電錶
  • 用麵包板組裝實驗電路

第三章 Arduino 互動程式設計入門

  • Arduino 程式設計基礎
  • 動手做 3-1 寫一個 LED 閃爍控制程式
  • 用「變數」來管理程式碼
  • 認識數字系統
  • 不變的「常數」

第四章 開關電路與LED跑馬燈效果

  • 認識開關
  • 讀取數位輸入值
  • 改變程式流程的if條件式
  • 動手做 4-1 用麵包板組裝開關電路
  • 動手做 4-2 跑馬燈範例程式一
  • 撰寫迴圈程式
  • 動手 做4-3 跑馬燈範例程式二:使用for迴圈
  • 認識陣列
  • 動手做 4-4 跑馬燈範例程式三:使用陣列變數
  • 使用埠口操作指令與位移運算子製作跑馬燈程式
  • 動手做 4-5 跑馬燈範例程式四:使用位移運算子

第五章 序列埠通信

  • 並列與序列通訊簡介
  • 處理文字訊息:認識字元與字串資料類型
  • 從Arduino傳遞序列訊息給電腦
  • 動手做 5-1 從序列埠監控視窗觀察變數值
  • 從 Arduino 接收序列埠資料
  • 動手做 5-2 從序列埠控制LED開關
  • switch…case 控制結構

第六章 類比信號處理

  • 讀取類比值
  • 動手做 6-1 從序列埠讀取「類比輸入」值
  • 認識光敏電阻與分壓電路
  • 動手做 6-2 使用光敏電阻製作小夜燈
  • 壓力感測器與彎曲感測器
  • 電容式麥克風元件與運算放大器
  • 動手做 6-3 自製麥克風聲音放大器(拍手控制開關)
  • 動手做 6-4 拍手控制開關改良版

第七章 LED七段顯示器

  • 七段顯示器
  • 動手做 7-1 連接 LED 七段顯示器與Arduino板
  • 使用積體電路簡化電路
  • 動手做 7-2 序列連接七段顯示器

第八章 LED矩陣與SPI介面控制

  • 建立自訂函數
  • 動手做 8-1 建立自訂函數
  • 認識變數的有效範圍
  • LED矩陣簡介
  • 認識SPI介面與MAX7219
  • 動手做 8-2 組裝LED矩陣電路
  • 顯示單一矩陣圖像
  • 動手做 8-3 在矩陣LED上顯示音符圖像
  • 動手做 8-4 在序列埠監控視窗輸出矩形排列的星號
  • LED矩陣動畫與多維陣列程式設計
  • 動手做 8-5 在矩陣 LED 上顯示動態圖像
  • LED 矩陣跑馬燈
  • 動手做 8-6 LED矩陣逐字捲動效果程式
  • 將常數保存在「程式記憶體」裡

第九章 LCD顯示器+溫濕度感測器+超音波感測器

  • 認識文字型 LCD 顯示模組
  • 動手做 9-1 在 LCD 顯示器上顯示一段文字
  • 動手做 9-2 在 LCD 上顯示自訂字元符號
  • 動手做 9-3 串列連接 LCD 顯示模組
  • 數位溫濕度感測器
  • 動手做 9-4 製作數位溫濕度顯示器
  • 認識超音波
  • 動手做 9-5 使用超音波感測器製作數位量尺

第十章 變頻控制LED燈光和馬達

  • 調節電壓變化
  • 類比輸出(PWM)指令和預設頻率
  • 動手做 10-1 調光器
  • 動手做 10-2 隨機數字與燭光效果
  • 動手做 10-3 透過序列埠調整燈光亮度
  • 動手做 10-4 使用atoi()轉換字串成數值
  • 認識直流馬達
  • 齒輪箱 / 滑輪組和動力模型玩具
  • 認識電晶體元件
  • 動手做 10-5 電晶體馬達控制與調速器
  • 控制馬達正反轉的H橋式馬達控制電路
  • 動手做 10-6 自動迴避障礙物的自走車

第十一章 使用Wii搖桿控制機械手臂

  • 認識伺服馬達
  • 動手做 11-1 自製機械手臂
  • 認識Wii左手把的通訊介面:I2C
  • 動手做 11-2 透過I2C介面串連兩個Arduino板
  • 動手做 11-3 在I2C介面上傳送整數資料
  • 動手做 11-4 讀取Wii左手把的搖桿、按鈕與加速度計值
  • 動手做 11-5 使用Wii左手把控制機械手臂
  • 改造伺服馬達成連續360°旋轉

第十二章 紅外線遙控與縮時攝影控制器

  • 認識紅外線
  • 動手做 12-1 偵測人體移動
  • 紅外線遙控
  • 動手做 12-2 使用IRremote程式庫解析紅外線遙控值
  • 動手做 12-3 使用紅外線遙控器控制伺服馬達
  • 動手做 12-4 從Arduino發射紅外線遙控電器
  • 運用紅外線遙控照相機
  • 動手做 12-5 遙控照相機拍攝縮時影片

第十三章 製作光電子琴與MIDI電子鼓

  • 發音體和聲音
  • 使用tone()函數發出聲音
  • 動手做 13-1 演奏一段瑪莉歐旋律
  • 使用#define巨集指令替換資料
  • 認識反射型與遮光型光電開關
  • 動手做13-2 光電子琴製作
  • 認識MIDI
  • MIDI訊息格式
  • 動手做 13-3 透過 Arduino 演奏 MIDI 音樂
  • 動手做 13-4 透過「虛擬 MIDI」介面演奏音樂
  • 動手做 13-5 製作 MIDI 電子鼓

第十四章 手機藍牙遙控機器人製作

  • 電波、頻段和無線傳輸簡介
  • 認識藍牙(Bluetooth)
  • 動手做 14-1 使用軟體序列埠程式連接Arduino與藍牙模組
  • 動手做 14-2 用Android手機藍牙遙控機器人

第十五章 網路與HTML網頁基礎+嵌入式網站伺服器製作

  • 認識網路與IP位址
  • 網域名稱、URL網址和傳輸協定
  • 動手做 15-1 認識網頁與HTML
  • 網路的連線標準與封包
  • 認識HTTP協定
  • 連接乙太(Ethernet)網路卡
  • 建立Arduino微型網站伺服器
  • 動手做 15-2 建立微型網站伺服器

第十六章 網路家電控制

  • 使用Webduino程式庫建立微型網站
  • 自訂錯誤訊息網頁與超連結設定
  • 動手做 16-1 監控遠端的溫濕度值
  • 傳遞資料給網站伺服器
  • 動手做 16-2 建立網頁表單
  • 認識傳遞資料的 GET / POST 方法和查詢字串
  • 動手做 16-3 建立接收 POST 表單資料的自訂命令
  • 動手做 16-4 從瀏覽器控制遠端的燈光開關
  • 控制家電開關
  • 動手做 16-5 使用繼電器控制家電開關

第十七章 Arduino +Flash整合互動應用

  • Arduino + Flash = 多元互動媒體
  • 動手做 17-1 測試Arduino與Flash連線
  • 動手做 17-2 「接電子零件」互動遊戲
  • 認識Arduino的String(字串)程式庫
  • 動手做 17-3 Flash燈光開關和調光器
  • 使用Firmata在Flash和Arduino之間傳遞資料

第十八章 RFID無線識別裝置與問答遊戲製作

  • 認識條碼與RFID
  • RFID 模組介紹與標籤讀取實驗
  • 動手做 18-1 讀取RFID標籤
  • 儲存與比對RFID編碼
  • 動手做 18-2 使用RFID控制開關
  • 動手做 18-3 使用RFID進行Flash問答遊戲

附錄A 認識焊接工具:焊錫、電烙鐵及焊接助手

  • 焊接工具
  • 動手做 A-1 基礎焊接練習
  • 動手做 A-2 焊接鱷魚夾
  • 印刷電路板及萬用板
  • 動手做 A-3 焊接電路板
  • 動手做 A-4 活用USB電源供應器

附錄B 燒錄ATmega微處理器的開機啟動程式(boot loader)

  • 動手做 B-1 使用Arduino控制板燒錄ATmega328韌體
  • 動手做 B-2 用麵包板組裝Arduino微電腦實驗板

附錄C 改造 3C 小玩意的控制鈕

  • 認識光電耦合元件

附錄D 中斷處理與交流電調光器製作

  • 輪詢 VS 中斷
  • 調整交流電的輸出功率
  • 動手做 D-1 交流電調光器電路

附錄E 使用App Inventor開發Android App

  • 準備App Inventer開發環境
  • 建立第一個App Inventor專案:聲音播放程式
  • 藍牙遙控機器人App的程式碼說明
Posts created 467

264 thoughts on “《超圖解Arduino互動設計入門》補充資料、勘誤及目錄大綱

  1. 頁數4-33,最上面,
    使用了”串連”、”串接”、”並聯”等詞彙,或許統一為串聯與並聯比較好。

    1. hi angus:

      校稿時,編輯也有指出類似的問題,我以為都已經修改好了。
      感謝您的指正。
      剛才我也更新了「內容勘誤」。

      thanks,
      jeffrey

    2. 奇怪的问题,Arduino IDE里无法输入中文,但是可以粘贴进中文,我用了微软bing输入法、谷歌输入法、百度输入法、搜狗输入法均无法解决问题,我用Arduino IDE1.03、1.54beta均无法解决问题,我用win764位操作系统,我在其他软件里面或者浏览器里面输入中文却没问题。

  2. 小節4-6使用”埠口”,這似乎有點突兀,篇幅也很少,不適合初階入門書。(個人意見)

  3. 5-4頁,最上面”通訊埠通訊視窗”,應該改成”通訊埠監控視窗”比較好,統一詞彙。

  4. 頁數14-4的頻段表裡,在這張表裡加入Wi-Fi、藍牙、ZigBee、NFC,應該更顯得完整。

    頁數14-10,同時出現”序列埠監控視窗”與”序列埠通訊視窗”,詞彙統一應該比較好。

    頁數14-12,這裡有兩段程式碼,或許合併成一段比較好,或是改成同樣的底色。

    1. hi angus:

      「通訊埠監控視窗」名詞已修正。

      關於「埠口」,其實我的本意是提供讀者處理LED跑馬燈的四種不同程式設計方法,讓讀者知道同一個問題,有多種可能的解決方式。同時也為第七章的「七段顯示器」設下基礎。

      非常感謝您的寶貴意見。

      thanks!
      jeffrey

  5. p4-7下方的最右邊的圖,說「此處若直接接地,會造成短路」。是什麼東西會短路?是arduino還是D2上的東西?
    還有,大家是應該都聽過「短路」,但不知道為什麼「短路」會造成危害。是不是一樣以水池理論比喻的話,「短路」就是不當洩洪,造成水災呢?

    1. hi naive231:

      感謝您的回應,我的確應該要將「短路」解釋清楚。

      按照字面上的意思,「短路」就是「最短的路徑」,相當於一般道路的捷徑,更貼切的說法是,「阻礙最少、最順暢的通路」。

      電流和水流一樣,會往最順暢的通路流動。從歐姆定律(4-30頁)可知,電流和電阻成反比:電路中的電阻值越小,電流越大(就像您比喻的水庫洩洪)。

      電流越大,消耗功率和發熱量也越大(10-2頁)。導線的電阻值趨近於0,直接用它連接電源的正極和接地,將導致大量電流通過導線,可能會引發火災。

      年少時懵懂無知,我曾直接用一段銅線連接二號電池的正、負極,發現銅線會發燙;後來還調皮地把神明桌上的光明燈泡兩端,用導線接起來再插電,結果在將插頭接上插座的那一剎那,插座激起藍色火光,整條電線也在瞬間冒出大量白色煙霧,並散發塑膠燒焦的味道。

      總開關的保險絲燒斷了,所幸電線並未釀成火災,但是我被父母親訓了一頓。

      應該是短路的緣故,光明燈的電源線以及裡面的塑膠燈座,都有脆化的現象。

      這是我對「短路」最深刻的記憶。現在比較懂事了,也沒有勇氣把電池短路(危險!)。

      thanks,
      jeffrey

  6. 趙老師您好!
    我最近對Arduino產生了興趣,您的書看起來很不錯,我好想趕快買來動手。

    但我遇到一個問題:
    台灣有不少代理商與網拍賣家都有賣所謂的入門套件組,有些甚至有附上入門說明。
    我想買您的書來按圖組裝,但我不知道到底我該購買哪個套件?
    相信您也知道,雖然Arduino算是平價的電路板,但如果分散買組件的話,成本會拉高很多的,買套件組應該比較划算。

    我對這個問題蠻苦惱的,不同的套件組馬上可以有幾千元的差價,實在是新生的大問題!
    請問您可以在這個問題上給予我跟其他新生一些個人的想法與建議嗎?謝謝您!

    1. 其實並不需要事先買一堆套件。從一塊Arduino控制板、幾個電阻和LED,就可以開始玩Arduino了。

      學習套件裡面通常會附帶常見的感測器,以及必要的零組件。不過,假設你對其中一個主題特別感興趣,例如馬達控制,並想要製作一台自走車或者機械手臂,可是套件裡面只有一個小馬達。

      這時,你除了要添購馬達,可能還要購買不同的馬達控制器。

      又如書本的《動手做12-1,偵測人體移動》單元,你可能對它不感興趣,那只需要了解其中的紅外線原理,不必購買人體紅外線感測器。

      有些裝置背後的程式控制原理是一樣的,只是硬體介面不同。像調整LED的亮度以及馬達的轉速,都用到稱為「PWM調變」的技術。如果你的目的只是想要了解「PWM調變」這個重要概念,那麼,拿LED來練習就行了。

      另外,有些零組件可以用現成有的(或廢棄的)物品來改造,底下的照片是《動手做11-1,自製機械手臂》單元中的一部分支架(這張照片沒有出現在書裡面),我是用舊的5.25吋磁碟片的塑膠外盒來改造的。

      改造軟碟片保護盒,自製機械手臂。

      底下照片則是《動手做11-4》單元中,連接Arduino和Wii左手把搖桿的轉接板,市面上可以買到現成的。我是用廢棄的電腦介面卡來改造。

      用廢棄的電腦介面卡自製Wii左手把搖桿的轉接板

      我的想法是,你可以先實作基本單元(第一章到第九章,以及第十一章),明白基本電學和程式原理,之後再挑選你感興趣的單元,或者試著改造身邊的3C小玩意,不必急著一次購買很多零件。

      have fun!
      jeffrey

  7. 作者您好

    我發現在動手做9-1的圖(9-5頁)和對應的程式碼(9-6頁)有些問題, 圖中D4-D7接腳是對應到Arduino的D3-D6輸入, 因此程式碼在初始化LCD函式庫應改為
    LiquidCrystal lcd(12, 11, 6, 5, 4, 3)

    相同的問題出現在9-20頁的圖和對應的程式碼

    請參考

    謝謝

  8. 您好,非常推薦您的書,將許多複雜的電路解釋得很清楚,讓我弄懂很多以前似懂非懂的概念。
    在書中有個疑惑想請教。
    10-22「PNP型電晶體的負載接在E極(射極)。」
    但是下面圖中的PNP卻是將負載接在C極

    請問應該是哪個才對?

    1. hi 阿簡:

      抱歉,圖片是正確的。內文應改成「NPN型的負載接在電源端;PNP型的負載接在接地端。」
      感謝您的指正!

      thanks,
      jeffrey

  9. 4-16頁程式碼第22行,click ++; ,是不是類似 click = click + 1 這種語法?(++在書上沒看到語法說明)。
    另若是的話為何要click == 2 才做LED的動作?這樣不是檢查3次嗎(0,1,2),範例是檢查2次?
    是否可針對書中內容疑問開闢一專區做提問呢?謝謝。

    1. hi Ayu:

      “++”代表「加1」;另外有個”–“(兩個連續減號),代表「減1」。因此,底下這兩行敘述的意思是一樣的:

      click ++;
      click = click + 1;

      此外,”+=”代表「加上某數」,假如要替click的值加1,寫法如下(其用意和上面兩行相同):

      click += 1;

      除了”+=”,還有”-=”, “*=”和”/=”這樣的寫法,相當於:

      // 變數值減2,等同:click = click – 2;
      click -= 2;

      // 變數值乘3,等同:click = click * 3;
      click *= 3;

      // 變數值除4,等同:click = click / 4;
      click /= 4;

      至於比較 (click == 2),是因為click最初是0:

      第一次按下開關後,click值變成1。
      第二次按下開關後,click值變成2。

      因此,LED在click等於2的時候點亮,並將click的值重設為0。

      感謝您的回應,日後有相關疑義,煩請在此留言。

      thanks,
      jeffrey

  10. Dear jeffrey
    不太了解您的說明,我的理解:程式第16行第1次比對,若有異於20行比對第2次,若B1=B2則click +1,這不就代表每查2次click值+1?若要click值=2,理應已檢查4次了吧?程式第26行是否改成if (click == 1) {即可?

    1. hi Ayu:

      請參考4-17頁以及4-15頁的圖說,程式16~24行用於確認開關的狀態是否真的改變(即:消除彈跳),若有的話,click的值就加1。

      程式第16行第1次比對,從4-17頁的圖可以看出來,b1是和”lastState”比對;
      第20行的b1則是和b2比對,用於確認開關訊號真的改變了。

      換句話說,只有當開關訊號的狀態改變時(如:從低到高),click的值才會加1。

      程式16~24行用於「消除彈跳」。

      26~30行是第二個if條件判斷敘述,用來確認開關的狀態改變了兩次(如:從低到高,再從高到低),所以click的比對值是2。

      你把程式上傳到Arduino板測試,就可以得到結果了。

      have fun!
      jeffrey

  11. 在 5-9 頁底有 “第七章 「擴充 Arduino 的數位輸出腳位」一節介紹。。。” 遍尋本書找不到所指的章節在哪裡,是否有錯???

  12. 前一個問題謝謝。。。

    另一個問題,5-22頁,有關 “序列埠監控視窗低下的彈出選單”,可在輸出字串後面加上 ‘CR’ or ‘LN’ or ‘CRLF’。。。
    我怎麼試,都沒效果。我用的系統是 Mac OS X 10.7, Arduino UNO R3 + Arduino IDE 1.05。。。

    1. hi sam:

      那個下拉式選單指的是,「在傳送出去的資料」後面附加’CR’或’NL’,所以主要是影響「資料接收端」的程式,請參閱10-10頁的「動手做10-3」。

      have fun!
      jeffrey

    2. 所以是說 “序列埠監控視窗” --》“Arduino UNO 卡片” 時加上 CRLF,
      而不是 “Arduino UNO 卡片” --》“序列埠監控視窗” 時加上的。。。謝謝

    3. 不,依你的程式而定。

      請參閱5-12頁和5-17頁,關於向序列埠監控視窗「輸出」控制字元的方法說明。

      序列埠監控視窗底下的”結尾字元”下拉式選單,則用在向Arduino「輸入」序列資料時,選擇性地在資料後面加上”NL”, “CR”等控制字元。

      thanks,
      jeffrey

  13. 我想我知道我的問題在那了,這個範例是用微動開關這類的非自保開關,所以按一下會有開、閉的變話,而我想成自保式的開關,才一直想不通為何要到click=2才觸發digitalWrite。謝謝您一直幫我解說~

  14. 可能的幾個錯誤:

    9-10頁下面: char str[] = {‘8’, ‘b’, ‘i’, ‘t’, ‘ ‘, 0xCF, 0xB2, 0xBA, 0xDD};

    不是正確的 “字串”,LCD 顯示時,後面會出現怪字。 應更改為

    char str[] = {‘8’, ‘b’, ‘i’, ‘t’, ‘ ‘, 0xCF, 0xB2, 0xBA, 0xDD, 0};

    7-14頁下面: shiftOut(dataPin, clockPin, MSBFIRST, LEDs[index]);

    在我的 Arduino UNO R3 下,7段顯示器會亂跳,改成如下,就會正確。

    shiftOut(dataPin, clockPin, LSBFIRST, LEDs[index]);

    可以解釋一下如何造成的。

    另外在 7-3 頁下面圖,左邊的表格二進位數字,跟右邊的圖上的二進位數字,左右是顛倒的,為什麼???

    1. hi sam:

      是的,如5-14提到的,C語言的字串應該用0或NULL結尾,感謝糾正!

      關於7-3頁底下的圖說…我在規劃程式時,將七節顯示器的a,設定在最低位元,g設定在最高位元,所以實際儲存資料時,位元的排列順序是這樣的:gfedcba

      然而,實際寫程式時(如7-14頁的LEDs陣列),我自己忘了(拍謝啦~);高位元和低位元的順序相反,所以資料傳送的順序也要跟著改成顛倒,從「最高位元先傳(MSBFIRST)」改成「最低位元先傳(LSBFIRST)」。

      再次感謝!

      thanks,
      jeffrey

  15. 9-18頁:

    LiquidCrystal_SR lcd(7, 8, TWO_WIRE);

    應更正為

    LiquidCrystal_SR lcd(8, 7, TWO_WIRE);

    一個建議:是否可以另作一份 “以章節順序排序” 的勘誤表,方便讀者查找。。。

    請教一個問題:Arduino 是否相關組合語言編譯器可用,還是可在 C 裡內嵌???有否相關資料???

    1. 坦白說,除了早就已經還給老師的Z-80(猛然想起宏碁的小教授微電腦,那時候的宏碁不叫Acer,而是Multitech)和8051,以及短暫的6502之外,我不曾接觸過其他微處理器的組合語言。

      忘記在哪裡看到的,AVR處理器的效能大約是8051的10倍,也就是說,20MHz的AVR大約是200MHz的8051。

      再加上C語言編譯器的改良,使得C語言程式僅比組合語言程式的執行效率低10%~20%;而且C語言的可讀性、可移植性、容易開發…等的優點,可大幅彌補執行效率的缺點,所以就連嵌入式系統開發,也是以C語言為主流。

      不過,有些時候的確需要用到組合語言。根據arduino.cc官網的”AVR Code”文章指出,Arduino的delayMicroseconds()函數,最短暫的延遲時間是2 µs(微秒);如需更短的延遲時間,必須採用組合語言的‘nop’ (原意為no operation,代表「不操作」)。每道’nop’敘述的執行時間為一個機械週期,在16MHz時脈運作下,底下的「行內組合語言(Inline Assembler,亦即,直接寫在Arduino的C程式裡面)」,會產生62.5 ns(奈秒,10-9秒)的延遲:

      __asm__(“nop\n\t”);

      底下的程式摘自arduino.cc討論區的“Other ways to Blink !”這篇文章,採用組合語言撰寫每隔一秒閃爍LED的程式,可直接貼入Arduino的程式編輯器並編譯:

      /* blick-asm.pde
       * Created Nov 2009, by Bill Westfield.
       *   Based on the blink.pde example distributer with the Arduino IDE,
       *      Created 1 June 2005 By David Cuartielles
       *        based on an orginal by H. Barragan for the Wiring i/o board
       */
      
      #define LEDPORT PORTB    // Arduino pin 13 is bit 5 of port B
      #define LEDPORT_DIR DDRB
      #define LEDBIT 5
      
      // The setup() method runs once, when the sketch starts
      // For this example, we're going to put ALL of our code in setup, and
      // never actually return...
      
      void setup()   {
      
        asm volatile ("  sbi %[portdir], %[lbit]  \n"    // Set bit direction
            "3: "                                        // main loop label
            "   sbi %[port], %[lbit] \n"                 //  Turn on.
                /*
                 * About the delay loop:
                 *   The inner loop (dec, brne) is 3 cycles.
                 *   For one second, we want 16million cycles, or 16000000/(3*256*256) loops.
                 *   This is "about" 81.
                 */
            "    clr r16  \n"
            "    clr r17  \n"
            "    ldi r18, 81  \n"   // 100 * 256
            "1:"  // 1st delay loop label
            "        dec r16  \n"
            "        brne 1b  \n"
            "      dec r17    \n"
            "      brne 1b    \n"
            "    dec r18      \n"
            "    brne 1b      \n"
        
            "    cbi   %[port], %[lbit] \n"             // Turn off.
            
            "    clr r16  \n"
            "    clr r17  \n"
            "    ldi r18, 81  \n"
            "2:"  // 2nd delay loop label
            "        dec r16  \n"
            "        brne 2b  \n"
            "      dec r17    \n"
            "      brne 2b    \n"
            "    dec r18      \n"
            "    brne 2b      \n"
            
            "    rjmp 3b  \n"
            :
            : [portdir] "I" (_SFR_IO_ADDR(LEDPORT_DIR)),
              [port] "I" (_SFR_IO_ADDR(LEDPORT)),
            [lbit] "I" (LEDBIT)
            );
      }
      
      // Note that we never get to loop, since setup above loops forever.
      void loop()                     
      {
      }
      

      上面的程式在ATmega328處理器的編譯大小為510bytes,比起用C語言撰寫的版本少了一半左右(但實在很難懂)。

      非常感謝你的揪錯與建議,我下週會整理一份按照章節排列的勘誤表。

      have fun!
      jeffrey

    2. 謝謝你的回應。。。看了你的書,在電子零件與軟體的組合之間,又有初學程式設計時的興奮。。。

    1. 啊~的確是,diy14_1的程式碼如下:

      #include <SoftwareSerial.h>
      SoftwareSerial BT(10, 9); // 接收, 傳送
      
      const byte ledPin = 13;
      char val;     // 儲存接收資料的變數
      
      void setup() {
        pinMode(ledPin, OUTPUT);
        BT.begin(9600);
        // 藍牙連線成功後,發佈「準備好了」訊息。
        BT.println("BT is ready!");
      }
      
      void loop() {
        if (BT.available() ){
          val = BT.read();
          switch (val) {
            case '0':  // 若接收到0...
              digitalWrite(ledPin, LOW); // 關閉LED
              break;
            case '1':  // 若接收到1...
              digitalWrite(ledPin, HIGH); // 點亮LED
              break;
          }
        }
      }
      

      非常感謝!

      thanks,
      jeffrey

  16. 這幾天在動手作第九章的 LCD 電路,一直出奇怪的問題,我用的是 1602 LCD,其他的都跟書上一樣,程式常常剛剛開始正常,過一陣子 LCD 螢幕就出現亂碼,或有幾個字跑到其他的地方。按 reset 也無法恢復正常。到底發生什麼狀況??

    - 零件品質不良
    - 雜訊
    - 程式的問題?cursor 使用不正確? 可是每一個 loop 都有設定 cursor 啊。。。
    - 程式庫的問題? (目前用的是 LiquidCrystal_SR)
    - LCD 跟不上程式的速度?

    有人能告訴我可能的問題在哪裡???

    1. 應該是受雜訊干擾,請在74LS164的Vcc(第14腳)和接地(第7腳),接上一個100nF(104)的電容試試看。

      thanks,
      jeffrey

    2. 好了,太厲害了。。。

      目前正在作 diy9-4, 按照你的解法,是 74LS164 受到雜訊影響(它有這麼嬌弱嗎?),還是整個電路的原因?

      這個電路這麼小,雜訊哪裡來的? 一般雜訊的處理方式,用你的方法就可以了嗎???

    3. 在電路中傳遞的訊息以外的電子訊號,稱為雜訊。

      電路中的導線(訊號線)可視同天線,在其中流動的高速開、關脈衝訊號,可能會透過導線向外輻射出去;而鄰近的導線則像接收天線一樣,會感應到這些「雜訊」。如果導線的長度和訊號的波長一致(或等比例),感應到訊號就越強(請參閱「低成本、超簡單之DVB-T數位電視天線製作」)。

      數位IC採直流電(單方向,平穩的電流)運作。請參閱2-3頁的電流圖說,如果水源朝單一方向平穩的流動,管路中的負載也會平順地運轉;但如果水源受到外力影響,像潮汐一樣波動,當水的壓力被往上牽引時,管路裡的水也將往反向流動,負載將會逆轉或停止。

      雜訊干擾就像讓水源波動一樣,訊號電壓乎高乎低,雖然可能只有幾10mv的微小變化(例如,在4.95V~5.05V之間波動),但電流卻是在順流和逆流之間轉變。像半導體(如:二極體)這種零件,唯有順向電流才能運作,逆向就截止,所以整個系統就不停地開開關關,導致誤動作。

      接在IC電源旁邊的100nF (104)電容,又稱為「旁路電容」,相當於小型的蓄水池,用來平穩管路間的水流波動,旁路電容要盡量靠近IC才有效果,不然IC仍舊會受到導線感應到的雜訊干擾。

      Arduino的微處理器電源接腳,同樣也有連接一個100nF (104)電容,其他周邊IC也能比照辦理。

      thanks,
      jeffrey

  17. 沒有 index!!!給你的書上個 index 吧!!!

    我對台灣出版的書籍最大的不滿,就是沒有 index。尤其是技術書籍沒有 index。

    當我覺得有一本書不錯,值得放在當參考書時,卻發現我沒辦法用它。譬如,我剛剛想查一個 date / time 相關的函數或做法,似乎在書裡或哪裡有看到過,卻發現我找不到,也不知書裡有沒有提到相關內容。除非我從頭到尾翻一遍。。。

    你的書寫的不錯,給它上個 index 吧。。。

    1. 我也有相同的疑問。我請教了本書的編輯黃昕暐先生,他回覆:「主要是語言差異的問題,尤其是科技書籍,中文詞彙在不同的語境中常會變化成不同的詞,導致中文語詞通常很難索引。目前我做過的書,若是有索引,應該也都是我自己手工整理。」

      下次出版類似的書籍時,我會再跟編輯研擬解決方案,謝謝!

      thanks,
      jeffrey

  18. 正在作 diy10-6,幾個問題情教:

    - 如何決定 L298N 模具外接電源的大小。譬如 diy10-6 接了一顆普通的玩具馬達,一顆玩具四驅車馬達時,用 4 顆勁量電池當外接電源,結果普通馬達會動,四驅車馬達不會動。用 2 顆自走車用的特殊大電池(3.7V,4800mA),四驅車馬達才會動。可是我直接用 1 顆勁量電池,就能使普通馬達或四驅車馬達動起來啊。是程式的問題,還是其他什麼原因。照我直接想法,頂多 2 顆電池就應該能動了才對啊。。。有沒有一些通用的經驗法則顆用啊,書裡的公式看不懂。。。

    - 在用 L298N 模組的自走車上,並沒有看到在馬達上接 104 電容,是 L298N 模組本身就能防止 back EMF 嗎???

    1. hi sam:

      如10-29頁提到的,L298N的馬達輸入電壓最高46V,最大輸出電流2A。

      馬達上的100nF電容並非強制性的,但是為了避免馬達的雜訊干擾到其他電路,建議焊接上去。預防Back EMF是二極體的工作。

      L298N原廠技術文件的第6頁底下,包含一個連接直流馬達的範例(圖6),IC的腳4和腳9都有連接一個100nF電容,它們都屬於旁路電容(第7頁的圖7比較明顯)。

      建議先把問題簡化,用一個簡單的程式確認能否控制馬達轉動和停止,或者修改10-11頁(動手做10-3)的PWM調光器程式,控制單一馬達的轉速。不知道你的馬達控制模組是哪一種類型,假設你採用的是如10-31頁上方的控制器,底下的程式應該可以讓銜接在L298N控制器輸出A1和A2腳的馬達轉動:

      /*
      L298N控制腳位訊號,請參閱10-30頁的表10-5。
      Arduino腳5,接L298N板ENA腳
      Arduino腳3,接L298N板IN1腳(輸入1A腳)
      Arduino腳4,接L298N板IN2腳(輸入1B腳)
      */
      const byte ENA_PIN = 5;
      const byte IN1_PIN = 3;
      const byte IN2_PIN = 4;
      byte pwm = 100;
      
      void setup() {
        pinMode(ENA_PIN, OUTPUT);
        pinMode(IN1_PIN, OUTPUT);
        pinMode(IN2_PIN, OUTPUT);
      }
      
      void loop() {
        digitalWrite(IN1_PIN, HIGH); 
        digitalWrite(IN2_PIN, LOW);
        analogWrite(ENA_PIN, pwm);
        delay(1000);
      }
      

      thanks,
      jeffrey

  19. 老師好久不見:
    你這本書一發售我就趕快買來看了,不過一直沒空實作.
    Arduino板接藍芽模組,可以板對板進行藍芽互傳資料嗎?若是可以又該如何作呢?
    我之前在搜尋Arduino板資料,有發現一個Arduino板的軟體模擬器,
    在此分享給老師推廣給同好使用:fritzing

    1. hi dull-boy:

      關於主從藍牙相連,請參閱「執行AT命令(AT-command)修改藍芽模組的資料傳輸速率」這篇貼文的回應。

      fritzing並不是Arduino模擬器,它是繪製和分享麵包板電路的好工具。我所知道的Arduino模擬器(simulator,也譯作「仿真器」)軟體如下:

      have fun!
      jeffrey

  20. diy12-4:

    我用一顆紅外線發射 LED (不知頻率),抄襲家用電視的遙控器電源鍵,由 IRrecvDump 知道它是 NEC 32 bits 的協定及其按鍵值,在 diy12_4_RAW 程式中用 38KHz 可以正常開關電視。可是在 diy12_4 程式卻無法開關電視,出了什麼錯了???

    diy12-2:

    紅外線感測器受到太陽光照射後,一直跳出無法解析協定 0,是正常現象嗎???

    1. 我用Canon攝影機的遙控器測試,也是NEC格式,發射解碼或RAW格式都沒問題,我不確定其中的原因。我沒有試過用太陽光照射,我相信是正常的。

      thanks,
      jeffrey

  21. 如果世界上有像Arduino板那麼小台且價廉的電腦主機,就能輕鬆用來作藍芽資料傳輸該有多好,
    覺的老師這本書,好像比較適合對電子有些基礎的人比較能懂~
    應該說Arduino本身,還是需要對電子有些基礎的人比較能懂,
    就拿歐姆定律~我鄰居有一個會修冷氣~但是始終搞不清楚歐姆定律的道理一樣
    有些電學知識不是三言兩語就能搞清楚,但是我相信老師出這本書,絕對造福很多對電子領域似懂非懂的人
    我就是其中一個對LCD似懂非懂的人0.0~還有老師書中教學的雙迴圈,讓我能突破對這部分的理解,
    謝謝老師的回答^^

    1. 有廠商販售事先配對好的藍牙模組,通電之後就會自動相連。

      如果你只是需要透過無線方式串連Arduino,不妨使用2.4GHz, 315MHz, 433MHz等無線收發模組,使用簡便,價格也比較低廉。

      have fun!
      jeffrey

  22. 老師你好,我之前買了一顆新的MEGA328晶片,用arduino版燒入十,他總是寫燒入失敗
    我是照書裡的方法做

    avrdude: stk500_getsync(): not in sync: resp=0×00
    這是編譯器顯示的錯誤
    請摁這是代表什麼意思
    謝謝老師為我解惑

    1. hi handy0911:

      “avrdude: stk500_getsync(): not in sync: resp=0×00”
      錯誤訊息代表Arduino沒有回應。請問你是用附錄B那一頁的方式來燒錄?

      thanks,
      jeffrey

    2. 謝謝老師的回覆
      第二頁,我先接了線,再參照書本的方式燒入

      會不會是晶片本身就壞掉呢?

    3. 我認為晶片沒有損壞。最可能的原因是選錯板子,請從Arduino的「工具→板子」選單,選擇要燒錄的bootloader版本,以B-2的範例而言,請選擇Arduino Duemilanove w/ATmega328

      另外,如果用Arduino 1.0版軟體燒錄,需要修改一些參數,我當初是用Arduino 1.0.3燒錄。

      thanks,
      jeffrey

    4. 謝謝老師的回覆
      我剛剛改了一下,但還是不行…

      我適用1.0.5版燒入

      在對arduino板燒入ISP的時候就已經出現:avrdude: stk500_getsync(): not in sync: resp=0x00
      是否是一開始就有問題,但她寫說燒入完畢

      最後燒晶片也有出現:avrdude: stk500_getsync(): not in sync: resp=0x00

      🙂

    5. 請在Arduino控制板的5V和Reset腳位(註:位於3.3V插孔的左邊)之間連接一個10µF電容(耐電壓10V以上,請注意極性,’+’接5V),或者120Ω電阻再試試看。

      thanks,
      jeffrey

  23. 老師請問我將超音波距離感測器用來偵測水位,

    如果要將LCD顯示的數據進行遠端傳送,是要用無線收發模組作嗎?

    1. 對,在實驗階段,可以先用有線序列連線,試驗成功後,再換成無線模組即可。

      have fun!
      jeffrey

  24. 老師,書上寫說電容是接在reset腳和GND,但5V插孔已被佔去

    請問老師可以在講詳細一點嗎?有關5V插孔和reset是要怎麼接((我對電子的東西才剛剛碰:))

    謝謝老師的回覆

    1. 在arduino.cc官方論壇,這兩種電容接法都有人用;你可以使用導線把Reset腳接到麵包板,再銜接電容,今天稍晚我再補上不同的接線圖(註:先上傳ISP程式之後再接電容)。

      thanks,
      jeffrey

    2. 感謝告知,抱歉之前沒有將步驟說明清楚,那我就不另外補圖了。

      thanks,
      jeffrey

  25. chapter 14:

    本章的操作都是針對 windows 系統,能否介紹 mac OS X 10.7 下的檢查及連線測試的方式? mac 下有沒有免費的類似 AccessPort 軟體?

    1. hi sam:

      Mac用的序列埠終端軟體有:

      …以及其他。我平常主要在Windows系統上做硬體實驗,這個月之內我會貼文介紹Mac序列埠終端軟體和Arduino連線。

      thanks,
      jeffrey

    2. chapter 14:

      謝謝。。。chapter 14 之前的所有的章節在 mac OS X 10.7 下,全都沒問題!!!

  26. 老師請問flash全螢幕化,因為安全上的問題,鍵盤按鍵只能特定幾個按鍵能在全螢幕下使用,

    那如果經過Arduino板,是否就不會有這問題?

    (例如我要用flash去做快打旋風的遊戲,用Arduino板充當搖桿與按鈕去控制flash裡面人物的動作)

    1. Flash偵測的是按鍵的鍵碼,所以外接的USB裝置仍會被封鎖。我覺得不用花心思在解決全螢幕的問題,因為它不是遊戲的核心。

      thanks,
      jeffrey

  27. 您好~這本書真的寫的超棒的~

    我找到一個小錯誤了
    在 page 10-9

    PWM 頻率設定

    timer 2 部分,應該是數位3和11腳
    然後 語法應該是 TCCR2B=TCCR2B & 0b11111000 |0x02;

    我參考這邊的http://forum.arduino.cc/index.php/topic,16612.0.html

    希望作者能出本從Arduino 玩到AVR嵌入式開發的進階書~
    感謝

    1. hi EECS God:

      非常感謝您提供的資訊,我稍晚再更新內文,謝謝!

      thanks,
      jeffrey

  28. 趙老師您好
    從書中感覺到您真是個全方位的作者,不僅程式設計,連電子學實作都寫得清楚明白,尤其是圖文並茂,學習起來真過癮。我也正在研讀您這本超圖解,想請教一個問題:
    我有一個外部的計數裝置,數完後會顯示在七段顯示器(兩顆,十位數與個位數),我想將此裝置和ARDUINO連結,讓ARDUINO能夠讀入計數值,並將數值顯示在LCD上(或序列監控視窗上)。
    基本想法將計數裝置的八支腳(負責輸出0與1,各組成個位數與十位數的BCD碼)接到ARDUINO的數位輸入腳,再來程式應該怎麼將這八支腳的狀態轉換成十進位的數字去顯示呢?問題冗長,煩請賜教,謝謝

    1. hi tanj:

      感謝你喜歡這本書。看來你需要的主要是二進位轉十進位的程式,請參閱底下的程式片段:

      byte in;  // 二進位輸入
      int out;  // 十進位輸出
      
      // 二進位轉十進位
      // 請參閱:http://forum.arduino.cc/index.php?topic=1695.0
      int binary2decimal(byte b)
      {
      
        int dec = 0;
        int power = 1;
        byte mask; 
        int weight;
        
        for (mask = 0x01; mask; mask < <= 1)
        {
          if (b & mask)
          {
            weight = 1;     
          }
          else
          {
            weight = 0;     
          }
          
          dec = dec + (power * weight);   
          power = power * 2; 
          
       }
        
        return dec;
       }
      
      void setup() {
       Serial.begin(9600);
       
       in = 0b00100111;   // 請改成你的輸入值
       out = binary2decimal(in);
       
       Serial.print("result: ");
       Serial.println(out);
      }
      
      void loop() {
      }
      

      thanks,
      jeffrey

    2. 趙老師您好:
      我研究了許久,關於binary2decimal函數部分,請問以下解釋是否正確:
      關於此行 for (mask = 0x01; mask; mask < <= 1)
      表示mask初始值為0000,0001
      再來的mask不了解其意
      最後 mask < <= 1表示將mask每位元向左移一位元

      接下來此行
      if (b & mask)
      {
      weight = 1;
      }
      else
      {
      weight = 0;
      }
      是說將b和mask作逐個位元比較
      如果結果為1,就進行將weight設為1,如果不是就將weight設為0

      最後這兩行就神啦
      dec = dec + (power * weight);
      power = power * 2
      照著上面計算,就會將十進位值算出來了
      不知解釋得對不對,請教老師在if語法中第二個mask含意為何?謝謝
      再者小弟自行寫了個轉碼的片段程式:
      大意是將8個輸入值放進in這個陣列,再將in陣列值一一取出,將各位元乘上相對應的權值,就轉成十進位值了,是否這樣可行?
      程式如下:(初學者程式寫法,還請見諒)
      boolean in1=2;
      boolean in2=3;
      boolean in3=4;
      boolean in4=5;
      boolean in5=6;
      boolean in6=7;
      boolean in7=8;
      boolean in8=9;
      int DEC=0;

      void setup(){
      Serial.begin(9600);
      pinMode(in1,input);
      pinMode(in2,input);
      pinMode(in3,input);
      pinMode(in4,input);
      pinMode(in5,input);
      pinMode(in6,input);
      pinMode(in7,input);
      pinMode(in8,input);
      }
      void loop(){
      boolean in[8]={digitaiRead(in1),digitaiRead(in2),digitaiRead(in3),digitaiRead(in4),digitaiRead(in5),digitaiRead(in6),digitaiRead(in7),digitaiRead(in8)};
      DEC=in[0]*2*2*2*2*2*2*2+
      in[1]*2*2*2*2*2*2+
      in[2]*2*2*2*2*2+
      in[3]*2*2*2*2*+
      in[4]*2*2*2+
      in[5]*2*2+
      in[6]*2+
      in[7]*1+
      Serial.print("result: ");
      Serial.println(DEC);
      }

    3. 二進位轉十進位的計算方式如下:

      二進位轉十進位的運算方式

      for迴圈的第二個參數若不是0,迴圈內容將繼續執行。當mask往左移出第8位元之後,mask就變成0,從而停止for迴圈。
      因此,第一次計算時,十進位值是1:

      第一次轉換

      第二次計算時,十進位值是3:

      第二次轉換

      以此類推…

      have fun!
      jeffrey

  29. 感謝您如此詳盡的說明,我終於了解for迴圈中間那個MASK的意義了,運算的方式跟我理解的一樣,感謝您的說明。

  30. 趙老師您好
    最近在研讀您的超圖解,半夜都會睡不著,進入了RFID這章節,但您的書只介紹到READER模組,底下是一個利用WRITER模組寫入TAG的程式,可是執行完只會在序列視窗上顯示”Data written succesfully!”,完全不知道他將CODE寫到哪裡去了(大概知道的事TAG裡面有位址,在3-31區是可以寫入的),其中void loop開始那幾行(mySerial.print…)可否請老師解說一下,再者,我們如何知道他把資料寫到哪去了呢?再次求教,煩請指點,謝謝

     #include <SoftwareSerial.h>
     #define RFID_WRITE 0x02
     #define txPin 6
     #define rxPin 8
    
     #define whichSpace 4
    
     #define first 1                 // first, second, thrid, and fourth are four arbitrary values which will be written to the RFID tag at address whichSpace
     #define second 26
     #define third 3
     #define fourth 27
    
    SoftwareSerial mySerial(rxPin, txPin);
    
    void setup()
    {
      Serial.begin(9600);
      Serial.println("RFID Write Test");
      mySerial.begin(9600);
      pinMode(txPin, OUTPUT);     
      pinMode(rxPin, INPUT);      
    }
    
    
    void suppressAll()                                      //Keeps error code & the "write confirmation" codes from being printed in the serial monitor       
    {
        if(mySerial.available() > 0)
        { mySerial.read();
          suppressAll();
        }
    } 
    
     void loop()
    {
      int val;
    
      mySerial.print("!RW");
      mySerial.write(byte(RFID_WRITE));
      mySerial.write(byte(whichSpace));
      mySerial.write(byte(first));
      mySerial.write(byte(second));
      mySerial.write(byte(third));
      mySerial.write(byte(fourth));
    
    
    if(mySerial.available() > 0) {        
        val = mySerial.read();
        if (val == 1)                                        //If data was written successfully
          { Serial.println("Data written succesfully!");
            suppressAll();
          }
        else suppressAll();                                  //If an error occured during writing, discard all data recieved from the RFID writer
        }
    delay(250);
    }

    上例引用自http://playground.arduino.cc/Learning/ParallaxRFIDreadwritemodule

    1. 我手邊的RFID模組僅具備讀取功能,加上大多數的RFID應用只需要讀取資料,所以我沒有準備相關的範例。

      你提供的示範網頁,採用的是Parallax的RFID模組,根據它的技術文件第4頁指出,寫入資料的指令編碼是’0x02’,後面跟著 1 位元組的位址(有效值為十進位的1~33),再加上 4 位元組的資料。寫入完成後,它會傳回 1 位元組長度的狀態碼。

      因此,上面的程式開頭,定義了下列常數:

      「寫入資料」:RFID_WRITE
      「資料位址」:whichSpace
      「資料位元組1」:first
      「資料位元組2」:second
      「資料位元組3」:third
      「資料位元組4」:fourth

      然後再透過 mySerial.write() 敘述寫入。

      thanks,
      jeffrey

  31. 感謝趙老師的說明,大概知道他把資料寫去哪裡,再來就要想想如何驗證寫入的資料,我真該好好讀讀技術文件,無奈英文普通。

  32. diy14-2:

    對你完成的藍牙遙控 “田宮六足昆蟲” 實際成品很感興趣,尤其是組裝細節。把它的照片放上來給大家參考一下好嗎?

    1. 這是用樂高積木結合田宮線控六腳昆蟲和馬達控制器的模樣:

      田宮線控六腳昆蟲和馬達控制器

      藍牙序列通訊模組、自製的Arduino控制板和電池盒:

      藍牙序列通訊模組、自製的Arduino控制板和電池盒

      全部組合在一起的樣子:

      組合Arduino、藍牙序列通訊模組、電池盒以及田宮線控機械昆蟲的模樣。

      thanks,
      jeffrey

    2. 最近在網路上找到一只田宮六足昆蟲,想把這個試驗再做一次,尤其是自製 Arduino 板很有趣。。。請教幾個問題。

      – 四顆電池加上其他的板子,會不會太重,田宮六足昆蟲的馬達動的起來嗎???
      – 你的 L298N 板子是不是有改過接腳,以配合自製的 Arduino 板子?
      – 參考附錄 B 應該可以做的到自製 Arduino 的板子吧。

    3. 不會重。

      對,我的L298N板子有修改接頭,方便用杜邦線連接,但是用原本的接頭也行。

      可以,在麵包板上拼湊一個自製的Arduino很容易;焊接到PCB板時,可能需要練習一下,若不刻意做成迷你的尺寸,其實也不難。

      have fun!
      jeffrey

  33. diy14-2:

    我的藍牙模組在移除電源後,就必需從新 “配對”,然後才能 “連線”。即使之前已 “配對” 過也一樣。這樣是正常的嗎???

    1. 我認為是系統的問題,跟藍牙模組無關。我在Android手機上測試,並不需要重新配對,只需要從之前記憶的選單中,挑選藍牙序列埠裝置,即可連線。

      thanks,
      jeffrey

  34. 您好:

    有關於補充資料、勘誤及目錄大綱問題:

    =================================
    出版日期:2013年7月;CD日期:2013.07.19
    購書日期:2013.08.14
    =================================
    我買的版本是2013年7月出版的新書,未更正上列的錯誤如下:

    【2013/04/27 更新】
    B-7頁:第一段倒數第二行,「參閱動手做 B-2」,正確是「動手做 B-1」。
    PS.參閱動手做還是印 B-“2”

    【2013/05/13 更新】
    影響的內文(頁數):…..和9-23。
    PS.9-23頁的設定接腳還是印 (12, 11, 5, 4, 3, 2)

    【2013/06/29 更新】
    B-4頁補充:使用UNO板燒錄Bootloader(開機啟動程式),在插上10uF電容之前,請先上傳B-13頁說明的ISP程式。上傳ISP之後,執行燒錄之前,請從Arduino軟體的「工具→板子」選單,選擇要燒錄的bootloader版本,以B-2的範例而言,請選擇Arduino Duemilanove w/ATmega328。
    PS. 看不懂您的敘述,因為書本內沒有B-13頁耶!

    可以麻煩您找書商拿一本最新版的書再次校稿一次。謝謝!
    PS.這…..真是一本好書,感謝您的貢獻!

    1. hi chiko:

      感謝您的留言,我已經跟編輯索取新版的樣書。
      的確沒有B-13頁,正確是B-3頁,謝謝!

      thanks,
      jeffrey

  35. 老師好
    百忙之中打擾,太精彩了一口氣把您的書看過一遍

    在下想要達成下列功能,能否請老師建議選用的平台方案?

    1.量測透明體移動的距離 精度0.0001mm,(0.1um) 採樣頻率20ms

    2.量測物體表面電位(靜電量)精度1vot 採樣頻率0.1s

    3.讀取2d code

    4.將上述資料紀錄在板上(可自動存檔)並將當下讀取值顯示在簡單的led or lcd上

    5.將上述資料無線傳送到pc上

    平台選用arduino,raspberry pi, beaglebone哪一個為佳呢

    感謝您

    1. hi jimmy:

      第二點我不確定,第一點可以搜尋”transparent object detection sensor”(透明物體偵測感測器)關鍵字,就能找到相關的感測器,但我不確定國內是否能買到。
      讀取2D條碼,在Android平台有相關的App能夠達成,在Windows上也有條碼掃瞄器可用,Linux一定也有。
      Raspberry PI平台的資料比較齊全,但考慮到性能∕價格比,我覺得PCduino比較划算,國內的網拍也買得到。
      除了這些平台,還有許多採用ARM處理器的嵌入式系統板子可用,而且也能執行Android和Linux系統,有些還附帶觸控LCD面板,在網拍上搜尋”ARM開發板”關鍵字即可找到。

      have fun!
      jeffrey

  36. 謝謝老師的回覆
    平台的選擇若有像您一樣高深功力的專家指點
    可以讓我們這些新進減少摸索的冤枉路

    我會去搜尋看看
    謝謝您

  37. 第3-18頁,表3-1,類型boolean佔用記憶體大小寫著「1位元」,

    雖然可用1位元表達boolean類型,但Arduino官方文件也寫著:
    http://arduino.cc/en/Reference/BooleanVariables
    A boolean holds one of two values, true or false. (Each boolean variable occupies one byte of memory.)

    所以,boolean會佔用1 byte的記憶體。

  38. 5-1頁是「序列埠通信」,5-2頁卻是「序列埠通訊」,或許全部統一改成通訊比較好。

    第4-20頁,倒數第三段,「源流(Source Sink)」是不是應該改成「源流(Source Current)」?

  39. 你好:

    真的是非常的感謝你的這本書,一出版我就買來看了,真的是收穫太多了。也重捨起自小對電子 diy 那份莫名的興奮感。

    也感謝這世界現在有 google ,可以在網路上找到太多的資源了,像 adafruit、instructables 之類的,真的是看了半夜都會睡不著啊

    我參考了下列這二篇網址,再加以變化一下,自製了一個最小系統的 arduino,總費用才150 元以內(其實費用不是重點,重點是爽啊 ~~,自製的最小系統都很正常 work)
    http://www.instructables.com/id/YABBAS-Yet-Another-Bare-Bones-Arduino-on-Stripb/?ALLSTEPS
    http://tinkerprojects.blogspot.tw/2012/06/minimal-arduino-on-small-stripboard.html

    完成圖:http://goo.gl/56Oupy

    另外,我也分享一下使用經驗;我按照書本中動中做 B-1 的教學,燒錄 ATmega328 韌體到自製的 arduino上,沒有接 10 μF 的電容,也是可以成功燒錄的(奇怪的是接了反而會出現錯誤訊息)
    板子是 Arduino Uno R3,IDE 版本:1.0.5

    再分享一個網址,是最近想要照著做的,難度其實真的不高,但完成後應該是非常有趣的啊
    網址:http://english.cxem.net/mcu/mcu2.php (android 上的程式都寫好了,真是太佛心了)

    另外這個網址,根本是神人之作!網址:https://sites.google.com/site/0miker0/gps-board

    不知道您有沒有計畫,再出一本更深入講解 arduino 的書呢?或者是更多 project 的書呢?因為實在是太多模組可以玩了,如果你能出本書來講解的話,一定會有更多人愛上 arduino 的。(像上面 GPS 及 OLED模組之類的)

    1. 讚!

      每當看到那些有趣的DIY作品,我也會有自己也來做看看的念頭,感謝分享!

      thanks,
      jeffrey

  40. diy8-6: 奇怪的問題???

    我用的是 Duemilanove w/ Atmega328 的板子(所謂的 “給力板???”),執行 diy8_6_Progmen.ino 沒問題,但是執行 diy8_6.ino 無法成功,8×8 LED 全黑。

    在 setup() 最開頭加上 Serial.begin(9600); Serial.println(“setup begin…”); 也沒訊息,抓不出錯誤在哪裡???

    chapter 8 的其他程式可正常執行。。。

    1. hi sam & lucan:

      我是先完成PROGMEM(程式記憶體)的範例(diy8_6_PROGMEM),
      再改寫成diy8_6,當時只認為程式邏輯正確,
      因此沒有實際上傳到Arduiono板測試。

      剛剛的測試結果,就如同你的測試一樣,
      我認為是fonts.h檔定義的256 x 8byes資料,
      佔用太多主記憶體。

      為了節省記憶體用量,
      我將diy8_6範例的fonts.h檔,
      刪除了前32個字元,
      以及’~’後面的控制字元,
      總共保留95個字元。

      因為fonts.h檔裡的字元編號順序改變了(全部往前挪移32個字),
      所以主程式loop()裡的「取出要捲動的字元編號」敘述,
      要減掉32,才能對應到fonts.h裡的正確字元:

      scroll(chr - 32);

      請在此下載更新後的捲動文字範例(diy8_6)

      抱歉造成您的困擾,也感謝您的糾正!

      thanks,
      jeffrey

    2. 好了,可以執行了。。。但是為什麼???

      我改過 diy8-3,#include “fonts.h” 到 diy8_3.ino,把所有 256 個字元都秀出來,也沒問題。而且 UNO R3 不是有 32k 的程式空間嗎? diy8-3 編譯過也才 5.3k 而已???

    3. 我又做了幾遍,還是怪怪的,下面是我的試驗。。。

      1. 將光碟 diy8_6 的 fonts.h 複製到 diy8_5,修改程式把 256 個字元每隔一秒秀一個字元,編譯成功 5,084 bytes,程式執行成功。

      2. 手工鍵入 diy8_6,使用原始光碟 diy8_6 的 fonts.h,刪除前 32 字元及後 128 字元,編譯成功 3,xxx bytes,執行失敗。

      3. 拷貝你修改過的 fonts.h (有刪除前 32 字元及後 128 字元的) 到 2. 程式,覆蓋我修改過的 fonts.h,編譯成功 2,126 bytes, 執行成功。

      好像越來越怪了。。。

  41. 請問老師

    arduino-Due 的TX該怎麼接收資料呢?
    我是在使用藍芽模組的時候發現這個問題的,打AT指令(AT+INQ和AT+INQC)時RX的燈會亮資料也有傳給藍芽,但藍芽模組回傳的資料(MAC位址與RSSI)卻無法顯示在串列埠上??
    一開始以為是串列埠的問題,所以我用下面這個程式去測試:
    int n = 0;
    void setup() {
    Serial.begin(115200);
    }
    void loop() {
    if (Serial.available()) {
    Serial.read();
    Serial.write(‘N’);
    Serial.println(++n);
    }
    }

    有貼出資料,所以我判斷應該是TX腳的問題,Arduino-Due的TX腳是要開啟才能使用嗎?我買來還沒看過TX腳的燈亮。

    1. hi 肌肉隊長:

      我看了Arduino Due控制板的資料,它具有四組序列埠(RX是「接收」腳;TX是「傳送」腳):

      • Serial: 0 (RX) 和 1 (TX)
      • Serial 1: 19 (RX) 和 18 (TX)
      • Serial 2: 17 (RX) 和 16 (TX)
      • Serial 3: 15 (RX) 和 14 (TX)

      所以你可以嘗試連接其他序列埠試試看,例如,連接Serial1(序列埠1):

      int n = 0;
      void setup() {
        Serial1.begin(115200);
      }
      void loop() {
        if (Serial1.available()) {
          Serial1.read();
          Serial1.write('N');
          Serial1.println(++n);
        }
      }

      have fun!
      jeffrey

  42. 謝謝老師
    我還有一個問題:
    本來藍芽連接UNO的時候會收到這些資料:
    +INQ:84:00:d2:0e:58:49,5a0204,-51
    +INQ:84:00:d2:0e:58:49,5a0204,-54
    +INQ:84:00:d2:0e:58:49,5a0204,-47
    +INQ:84:00:d2:0e:58:49,5a0204,-47
    +INQ:84:00:d2:0e:58:49,5a0204,-46
    +INQ:84:00:d2:0e:58:49,5a0204,-48
    +INQ:84:00:d2:0e:58:49,5a0204,-46
    +INQE
    +INQS
    +INQ:84:00:d2:0e:58:49,5a0204,-45
    +INQ:84:00:d2:0e:58:49,5a0204,-48
    +INQ:84:00:d2:0e:58:49,5a0204,-46
    +INQ:84:00:d2:0e:58:49,5a0204,-46
    +INQ:84:00:d2:0e:58:49,5a0204,-48
    +INQ:84:00:d2:0e:58:49,5a0204,-47
    +INQ:84:00:d2:0e:58:49,5a0204,-48
    +INQ:84:00:d2:0e:58:49,5a0204,-48
    +INQ:84:00:d2:0e:58:49,5a0204,-46
    +INQE

    但換成DUE就只能傳給藍芽AT指令,無法顯示上面的資料,怎麼會這樣?

    1. 咦?是某些傳入的序列資料會遺失,還是只有來自這個模組的序列資料收不到?

      thanks,
      jeffrey

    2. 就是我可以用指令AT+INQ讓藍芽模組搜尋附近的設備,用UNO的時候串列埠會顯示+INQ:84:00:d2:0e:58:49,5a0204,-48
      但用DUE的時候甚麼都不會傳回來(但藍芽模組有收到AT+INQ,因為模組的燈有閃),好奇怪??

  43. 請問老師

    我有一快arduino-due壞了,燒錄程式的時候RX TX會亮,但燒完後程式都不做動跟沒燒一樣,
    請問我要怎用另一快DUE(我有兩塊)把程式燒進去?

    1. 我沒有用過Due,但我想它仍舊是透過RX和TX腳位傳入Arduino程式碼(目前arduino.cc官網正在維護,無法取得資料),如果微處理器的這兩個接腳故障,除非修改原廠的Bootloader(開機啟動)韌體,可能無法讓它接收新的程式碼了。

      不過,如果晶片無法寫入程式碼,Arduino程式應該會顯示錯誤訊息,所以我覺得程式碼應該有燒寫進去。建議先用一個閃爍LED的簡單程式碼測試看看。

      good luck!
      jeffrey

    2. 有耶老師!
      我就是燒LED 13腳的那個程式,都沒有顯示錯誤就燒完了,但就是沒作動,啊~~好煩惱喔1700一塊啊!!
      老師快寫一本DUE的書啦!

    3. ATmega微控器的某些腳位燒毀,並不會危害到整個晶片,或許你可以嘗試店點亮其他腳位的LED。
      我挺好奇的,請問你為何要採用DUE板子呢?

      good luck!
      jeffrey

    4. 因為DUE的處理速度真的比UNO強太多了,最近在寫PID程式很需要執行速度,一秒大概要執行300次積分運算才行。這對DUE來說是游刃有餘!

    5. 原來如此~因為我想到它的價位,可以買一塊具備Arduino相容擴充槽的pcDuino板,才問這個問題。

      thanks,
      jeffrey

  44. #include <SoftwareSerial.h>
    SoftwareSerial BT (10,11);
    void setup(){   
       BT.begin(9600);
       BT.write("AT+INQ");  // AT 指令
       BT.write('\r');
       BT.write('\n');
          
    }
    
    void loop(){
      if( BT.available())
      {    // 如果 BT 有資料,則進入 if
          String s;
          char c;
          while((c = BT.read()) !='\n'){
          s += c;
          }  
         BT.println(s); // 輸出結果到電腦  
      } 
    
      delay(1000);    // 延遲一秒
    }

    這程式是我照著老師書中14-12頁改的,想用它與UNO接收和傳送AT指令,但它只能傳不接收(藍芽模組燈有閃,但打”AT”,OK卻沒傳回來)。
    14-12的程式有時候也會失靈,不知道為什麼??

    1. 我沒有嘗試在兩個Arduino藍牙之間傳送AT指令欸…你是要讓兩個模組執行配對功能嗎?

      thanks,
      jeffrey

    2. 我序列埠控制視窗收到的資料是這樣:

      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41
      +INQ:8c:64:22:66:69:40,5a0204,-42
      +INQ:8c:64:22:66:69:40,5a0204,-41

      8c:64:22:66:69:40,式MAC位址,41 等等最右邊的數字是RSSI(訊號強度),我想利用RSSI來控制LED的明暗,但都不知道該怎麼把數字單獨抓出來使用。

    3. 你可以嘗試使用String程式庫的substring()函數取出子字串(註:請參閱17-21頁)。

      thanks,
      jeffrey

    4. 老師之前說的那本{三井康亘}的壓克力機器人還買的到嗎?
      我本來有一本,但淹水的時候被泡壞了。

    5. Syntax

      string.substring(from)
      string.substring(from, to)
      請問老師
      from, to 的值是要寫甚麼?
      是設定範圍的意思嗎?要怎麼設定?

    6. 沒錯!from是起始字元(從0起算),to是結束字元,但結束字元可省略。若省略結束字元,它就會從起始字元擷取到最後一個字元。

      thanks,
      jeffrey

    7. 這是我的程式,我希望substring在截取到”OK”這個字時,貼出”It’s an html file”,但都失敗~
      老師可以幫我看看哪裡寫錯嗎?

      #include
      SoftwareSerial BT (10,11);
      char s = 0;
      void setup(){
      BT.begin(9600);
      Serial.begin(9600);
      // while (!Serial)
      // Serial.println(“Start…”);
      BT.write(“AT”);
      BT.write(‘\r’);
      BT.write(‘\n’);

      }

      void loop(){
      if (BT.available())
      Serial.println(readLine3());
      if (Serial.available())
      BT.write(Serial.read());

      }
      String readLine3(){ // 讀取一整行
      String s = “”;
      char c;
      while((c = BT.read()) !=’\n’){
      s += c;

      }
      return s;
      if(readLine3().substring(1,100) == “OK”)
      {
      Serial.println(“It’s an html file”);

      }

    8. 程式的主要需求應該是「取出輸入字串的最後兩個字元」,程式必須先知道整個字串的字元數,才能取得最後兩個字元。我把程式簡化如下:

      String str = "";         // 暫存序列輸入字串的變數
      
      void setup() {
        Serial.begin(9600);
      }
      
      void loop() {
        while (Serial.available()) {
          char _in = Serial.read(); 
          
          // 若非「新行」字元,則連結新字元
          if (_in != '\n') {
            str += _in;
          } else {
            int total = str.length();
            // 顯示最後兩個字元    
            Serial.println(str.substring(total-2)); 
            str = "";
          } 
        }
      }

      thanks,
      jeffrey

    9. 謝謝老師
      不過我現在最大的問題是不知道該怎麼用substring來判斷TX接收到的資料,
      因為輸入AT指令是從RX,藍芽傳送訊息給Arduino是從TX,
      請問老師TX接收到的資料該怎麼判斷?
      譬如:
      輸入(RX):AT+INQ

      Arduino得到(TX):+INQ:84:00:d2:0e:58:49,5a0204,-48
      該如何把48抓出來”運算”?

      因為”+INQ:84:00:d2:0e:58:49,5a0204,-48″這筆資料是從”藍芽”傳過來的,
      判斷的方法好像比較不一樣。

    10. 不管是從藍牙或是有線序列埠,傳入的資料都是「字元」,所以都可以看待成字串資料,處理方式是一樣的。

      thanks,
      jeffrey

    11. 請問老師
      從”TX”腳接收到的資料要怎麼用SubString判斷呢?
      老師可不可以示範一下該怎麼寫。
      謝謝

    12. “TX”是「傳送」腳位,我不知道你為何要用它來「接收」資料,我也不知道要怎麼寫。
      底下是改寫上次的序列程式,只要是從”RX”腳位輸入字串的最後兩個字是”48″,例如:
      “+INQ:84:00:d2:0e:58:49,5a0204,-48”
      ,它就會顯示”Yes”:

      
      String str = "";         // 暫存序列輸入字串的變數
      
      void setup() {
        Serial.begin(9600);
      }
      
      void loop() {
        while (Serial.available()) {
          char _in = Serial.read(); 
          
          // 若非「新行」字元,則連結新字元
          if (_in != '\n') {
            str += _in;
          } else {
            int total = str.length();
            str = str.substring(total - 2);
            // 顯示最後兩個字元    
            Serial.println(str); 
            
            if (str == "48") {
              Serial.println("Yes");
            } else {
              Serial.println("No");
            }
            str = "";
          } 
        }
      }
      

      thanks,
      jeffrey

    13. TX當接收是因為
      我用arduino做藍芽的usb轉TTL
      不知到為什麼TX收到的資料都不能用substring判斷?
      老師知道是什麼問題嗎?

    14. 老師的程式我收到了,執行結果如下

      都是NO代表沒讀到嗎?
      為甚麼個位數字會出現在後面?
      8

      No
      7

      No
      7

      No
      7

      No
      8

      No
      8

      No
      0

      No
      7

      No
      0

      No
      7

      No
      6

      No
      E

    15. 請把底下這兩行:

      str = str.substring(total - 2);
      // 顯示最後兩個字元    
      Serial.println(str);

      改成:

      Serial.println(str);
      str = str.substring(total - 2);
      // 顯示最後兩個字元    
      Serial.println(str);
      

      這樣才能知道Arduino所接收到的完整內容,以便進一步除錯或者修改判斷條件敘述。

      thanks,
      jeffrey

    16. 老師
      if的部份我小改了一下,這樣成功機率比較高。

      if (str == “38”||str == “37”||str == “36”||str == “35”||str == “34”||str == “39”||str == “40”) {
      Serial.println(“Yes”);
      } else {
      Serial.println(“No”);
      }

      加上老師新改的部份,收到的資料如下:
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-38

      8

      No
      +INQE

      E

      No
      +INQS

      S

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No
      +INQ:8c:64:22:66:69:40,5a0204,-39

      9

      No

    17. 老師

      明明有收到資料,是不是要把0X96 0X55這種東西寫進去才行?
      程式怎麼都不會顯示yes?

    18. 我之前是依照你提供的數據“+INQ:84:00:d2:0e:58:49,5a0204,-48″來測試,如果實驗的結果都無法正常運作,那應該要先參閱規格書,釐清藍牙模組傳回的數據格式。

      thanks,
      jeffrey

    19. 老師
      老師知不知道有沒有類似我這個問題的範例程式可以下載,
      就是用substring判斷RX接收到的資料,
      這幾天一直失敗,試了好多方法。

      其實不一定要是substring啦!
      if case 都是一樣的意思。
      感謝
      O-(/// ̄皿 ̄)☞ ─═≡☆゜★█▇▆▅▄▃▂_ 

      Ps.老師, “jeffrey”是甚麼意思?

    20. 我想你需要的並不是範例程式,而是確定藍牙模組的訊息格式內容。

      另外,”Jeffrey”這個字源自於”Geoffrey”,其原意出自由兩個德語Gott(上帝)和fried(和平)組成的”Gottfried”,大概就是神愛世人、天下為公、世界和平、四海一家的意思。

      簡單的說,”jeffrey”是小弟的英文名字啦~

      thanks,
      jeffrey

  45. 趙老師,您好

    電子系畢業30年了,在退休生涯中發現了Arduino(兩週前),從新燃起做小實驗的興趣,努力K了一些網站的資料,還有您的大作 “Arduino互動設計入門“,確實是一本好書。但因為多年未曾寫程式了,不知是不是自己弄錯了(我買的是2013/07版的書):

    7-6頁中段 digital port (group D: pin0~7) 上方的seven segment的編號
    xgfedcba
    00111111
    是不是標反了?是不是應該標是成
    (xabcdefg)
    01111110

    這樣才會和7-3頁 seven segment 設定值(以及右側LEDs[0]的 B011111110 ) 以及 7-5頁的電路接線圖一致?

    因為在7-1節中還沒有用到74HC595,所以應該沒有LSB First 或 MSB First 的問題。

    不好意思!請您指正。

    謝謝!

    Gogolover

    1. Gogolover前輩您好:

      應該是我畫錯了,我晚上再確認一下。感謝糾正!

      thanks,
      jeffrey

  46. 老師好
    我接觸了mcu一段時間
    整理相關資源如下

    a1.中文論壇&資源
    1.極客工坊 http://geek-workshop.com/forum.php
    2.arduino指令說明 http://www.game7777.net/doku.php

    a2.中文網誌
    1.葉難 http://yehnan.blogspot.tw/2013/01/arduinortcds1307.html
    2.copper http://coopermaa2nd.blogspot.tw/2011/04/pulsein-button.html

    a3.各晶片大廠也推出同型的mcu,
    1.ti http://www.ti.com.tw/product/analog/msp430.asp
    2.nxp http://www.tw.nxp.com/products/microcontrollers/
    3.freescale http://www.freescale.com/zh-Hans/webapp/sps/site/taxonomy.jsp?code=KINETIS_E_SERIES&tid=FSHBNRZH-HANS_20131022
    4.intel http://arduino.cc/en/ArduinoCertified/IntelGalileo

    另外,由本次ios 7.0看到其sensor vp(把sensor部門掛到副總等級 可見sensor的重要性)發表m7晶片,可知後續sensor的應用是相當重要,
    a.4sensor中文論壇
    傳感器專家網 http://www.sensorexpert.com.cn/Products/SM-PWM-01A.html

    以上

    請問老師是否有其他的資源(您推薦值的一去的網站論壇等等)可以分享給大家?
    謝謝

    1. hi jimmy:

      非常感謝您的分享!!

      我並沒有留意MCU的相關資源,因為從高階的角度(如:C語言)來看,用哪一種MCU對DIY並沒有太大的影響,除非是特別要求效能,或者連接特定介面的情況,像是模擬USB鍵盤、滑鼠時,就會用到採ATmega32u4的Arduino Leonardo,否則ATmega328對我就很夠用了。

      但如果某個我想要製作的東西,已經有人用PIC或8051等微控器完成了,我就會去購買相同的零件來製作看看,並不一定要用Arduino。

      有問題時,就直接用關鍵字搜尋,畢竟DIY的領域太廣泛了,前一陣子蠻常逛紙模型的網站(關鍵字:papercraft)。

      因為我很容易分心,若不節制,就會漫無目的到處走馬看花,所以我也不用Facebook,那花花世界太吸引人了!(我收到很多朋友的Facebook邀約,可是,Facebook的來信竟稱我是”Vivi”,而且是越南文~這些人到底是要找Vivi還是找我啊??)

      在DIY的過程,我遇到比較多麻煩是硬體和機械構件的整合,比方說,想要做一個放在戶外的Arduino,外型要輕巧、外殼要防水,然後還要能方便替換電池…或者,固定馬達時,要用木條還是壓克力板,或者去裁切鋁板…

      就好像做出一桌料理,準備的材料很重要,但是更重要的是,怎麼把這些素材調配在一起。

      底下是最近把樂高齒輪固定在伺服馬達的樣子。因為樂高積木有固定的尺寸,為了配合其他積木,在製作的時候,要稍微費工夫去琢磨積木;在齒輪上鑽孔時,也要留意前後螺絲孔能對齊、吻合。

      與樂高積木整合的伺服馬達

      製作完成後,發現其中一個齒輪太凸出了一些…這是我平常在傷腦筋的事 😛

      thanks,
      jeffrey

  47. 您好

    我用UNO接上一個3G Shield(SIMCOM 5218A晶片組),apple mac os 10.8.5環境
    使用serial port在Both NL& CR模式下,輸入AT後按下send,可得到ok的回覆
    [img]http://sensor.free.sahost.cc/image/cn2.png[/img]
    想請問,改用no line ending模式的話,AT之後要接什麼東西,按下send也可以得到ok的回覆?謝謝

    我已經用以下方法(AT\r\n)試過也不行,
    [img]http://sensor.free.sahost.cc/image/cn1.png[/img]

    1. 拍謝~我沒用過3G擴充板…可能要麻煩你查閱擴充板的技術文件。

      thanks,
      jeffrey

發佈留言

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

Related Posts

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

Back To Top