依章節排序的《超圖解Arduino互動設計入門》勘誤與內文補充

本文將按章節,列舉《超圖解Arduino互動設計入門》書籍的內容勘誤與補充說明,技術文件資料與相關軟體下載說明,請參閱另一篇文章

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

2-3頁,第二段最後的單位”mA”,正確中譯為「毫安培」。

第三章 Arduino互動程式入門

3-18頁,表3-1,類型boolean佔用記憶體大小寫著「1位元」,實際是佔用8位元。

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

4-16頁,程式碼當中的"++"運算子語法補充說明:

“++”代表「加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;

以上這些運算子統稱為指定運算子(assignment operator)

4-20頁,倒數第三段第二行,「源流(Source Sink)」正確是「源流(Source Current)」。

第五章 序列埠通信

5-4頁,第一行「序列埠通訊視窗」,正確是「序列埠監控視窗」。

5-10頁,中間的圖說「封包(package)」,正確是「封包(packet)」。

第七章 LED七段顯示器

7-3頁,儲存七段顯示器數字代號的陣列,更正為底下紅色字體部分:

儲存七段顯示器數字代號的陣列

補充說明:使用shiftOut()函數傳輸序列資料

Arduino程式開發工具提供一個shiftOut()序列資料輸出函數(應該說「資料位移輸出」比較妥當),能一次傳送一個位元組(8個位元)資料傳給74HC595,而我們只需負責打開和關閉74HC595的並列資料輸出閘門,不用理會其他細節。

shiftOut()函數的語法如下:

shiftOut()函數指令圖說

其中的「位元順序」代表資料位元的傳送順序,以傳遞虛構的ledData變數值為例,這兩者的差異請參閱下圖。至於要用哪一種方式傳送,取決於74HC595資料輸出端的電路接法(參閱下文說明)。

LSBFIRST與MSBFIRST比較

根據本單元的七段顯示器資料設定,應該以"LSBFIRST"(最低位元先傳送):

設定"LSBFIRST"(最低位元先傳送)

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

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

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

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

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

組裝MAX7219 LED矩陣電路麵包板

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程式,序列監控視窗將顯示負值,代表記憶體空間不足:

剩餘的記憶體數量

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

剩餘的記憶體數量

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

9-25頁:第二段,600µs (毫秒…,正確的單位名稱是微秒。

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

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

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

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

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

9-10頁,設定日文片假名文字的程式碼,要加上NULL結尾(請參閱5-14頁說明):

在LCD模組上顯示日文

9-16頁的串列連接LCD顯示模組,最好在74LS164 IC的電源和接地端,加上一個100nF (104)的電容,以便濾除雜訊干擾。

串列連接LCD顯示模組麵包板

9-18頁,串接式LCD模組的程式宣告當中的接腳設定,需改成底下的紅色字體:

序列LCD模組的腳位設定

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

10-9頁,timer 2 對應的腳位是數位311腳,其PWM頻率設定語法為:

TCCR2B=TCCR2B & 0b11111000 | 0×02;

10-22頁,NPN型的電晶體將負載接在C腳(集極),PNP型電晶體…,應改成「NPN型的負載接在電源端;PNP型的負載接在接地端。

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

10-31頁,第一段第一行中的「表 10-4 」,正確是「表 10-5」。

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

13-4頁:表13-1上方的說明文字,「對照表(單位.png) Hz)」,當中的 ".png)" 是多餘的。

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

14-10頁,實驗說明裡的「序列埠通訊視窗」,正確是「序列埠監控視窗」。

14-12頁:內文提到的AccessPort軟體,並未收錄在書本DVD光碟,請讀者到AccessPort的官網(sudt.com)下載

光碟裡的diy14_1.ino程式內容誤植成diy15_2,diy_14_1.ino的程式碼如下(請參閱14-12頁):

#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;
    }
  }
}

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

15-27頁:底下的程式片段:

錯誤的HTML片段

正確是:

正確的HTML片段

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

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);

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

18-10頁,RFID麵包板電路組裝圖中的蜂鳴器元件是多餘的。

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

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

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

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

B-12頁,圖片中的”DTS”標示,正確是”DTR”。

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

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

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

更新後的調光器電路圖:

交流電調光器電路圖

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

D-13頁,4N25的橋式整流電路正確是:

4N25零交越檢測電路

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

4N25零交越檢測電路

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

D-13頁,修正交流電調光器,燈泡閃爍的問題,請參閱「使用TimerOne程式庫改寫Arduino交流電調光器程式」說明。

附錄E 使用App Inventor開發Android App

"BTRobotControl.apk"(藍牙遙控機器人APP)無法送出「左轉」訊息,請參閱這篇文章,下載修正之後的APP和原始檔。

Posts created 468

151 thoughts on “依章節排序的《超圖解Arduino互動設計入門》勘誤與內文補充

    1. 1、我用Arduino Ethernet Shield(Arduino ETHERNET – shield V5)与Arduino Uno – R3安装到一起采用堆叠接插,运行15-25的例子正确。
      2、但是我用电线对应连接10、11、12、13的两块板卡的引脚,并把Arduino Ethernet Shield的5v电压和旁边的接地电压接到Arduino ETHERNET – shield V5的电压输出口,这是ping例子中指定的ip地址无回应,找不到主机。
      3、MAC和ip地址不冲突。
      4、这是什么原因呢?是不是要把10号引脚写上语句:pinMode(10, OUTPUT); digitalWrite(10, LOW);?

    2. hi firebug:

      请参阅Arduino Ethernet扩展卡电路图的中间上方。你可以看到此扩展卡的SPI介面,并不是连到11~13脚,而是通过板子上的ICSP引脚相连(SS脚仍是通过第10脚),这些脚位如下:

      Arduino Ethernet Shield ICSP

      你可以直接将它接到Arduino板的ICSP脚座,或者11~13脚。

      have fun!
      jeffrey

    3. http://www.shieldlist.org
      这个网址应该连接到此,不敢独享。When stacking shields, make sure that no shield uses the same digital or analog pins
      used by another shield at the same time. If you share pins between shields that use the
      same pin(s) for different functions, you may damage your entire creation, so take care.
      The supplier of each shield should provide information showing which pins are used
      by their shields. You can find a great, community-supported list of shields and shield
      pins used at http://www.shieldlist.org/.

  1. 作者你好!
    上個禮拜在書店看到您到書
    真的寫得非常好,學了很多東西,非常感謝 🙂

    想問一下,動手做6-3的程式是不是有問題呢?
    我執行之後拍手,LED會點亮,但是再拍LED不會熄滅

    1. hi tony:

      我剛剛測試,可以點滅LED。不過,我覺得程式可以稍加改良。

      diy6_3的判斷條件後面,或可加上0.5秒左右的延遲,避免微處理器在極短的時間內重複收音,產生誤動作(請參閱13-36頁的圖說):

      if (toggle) {
        digitalWrite(ledPin, HIGH);  // LED 點亮
      } else {
        digitalWrite(ledPin, LOW);   // LED 熄滅
      }
      delay(500);
      

      此外,toggle的值不是0就是1,因此以上幾行可以簡化成:

      digitalWrite(ledPin, toggle);  // 依toggle的值,點滅LED。
      delay(500);
      

      謝謝!

      have fun!
      jeffrey

  2. 您好:
    我看到8-16及8-17頁的圖
    IC的第7角沒有接線,但8-15頁的電路圖標示應該是接LED矩陣12腳
    應該是圖畫錯了
    跟您說一下

  3. 作者您好

    請問您有用紅外線遙控冷氣的經驗嗎?
    我本來無法錄到正確的紅外線Raw值,後來修改IRremote/IRremote.h的#define RAWBUF 200以後就可以了
    但是我用sendRaw回傳我收到的資料仍然無法成功遙控冷氣,不知道還需要注意什麼地方?
    我用同樣的方式控制電視機是可以的

    謝謝

    1. 我尚未嘗試遙控冷氣機,本週我會找時間測試看看。另外,根據arduino.cc論壇上的”Mitsubishi IR AC remote decoding Problem“(三菱冷氣紅外線遙控解碼問題)這篇討論,有可能是因為RAW資料太龐大,請嘗試修改底下三個地方:

      1. IRremote.h的#define RAWBUF 100敘述,請改大一點。例如:240。
      2. IRremoteInt.h的「廠牌位元」,以Panasonic為例,原本是:

      #define PANASONIC_BITS 48

      改成112或更大的值。

      3. IRremoteInt.h裡的uint8_t rawlen類型,請改成uint16_t rawlen。

      thanks,
      jeffrey

  4. 附錄B
    我燒錄一個LED閃爍的程式測試
    一直不會閃爍
    可是燒錄過程都 顯示燒錄成功
    好奇怪

    1. 煩請參閱B-7頁的ATmega328晶片的接腳,把LED接在其他腳位,例如,12或8,同時修改程式的LED_PIN定義再測試看看。說不定是處理器的13腳燒毀了。

      thanks,
      jeffrey

  5. 您好,我是初學者,很棒的一本書,今天做了中斷處理那部分,找不到h11a1,用了4N25,接電後1N4004都會爆開,已經爆三次了,是我接錯了嗎?還是有電子元件在第一次爆掉時已壞了?您會出進階的書嗎?謝謝

    1. hi jason:

      非常抱歉,那個4N25的橋式整流電路畫錯了,正確是:

      4N25零交越檢測電路

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

      4N25零交越檢測電路

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

      4N25裡的光二極體應該已經燒毀了,再次對您說聲抱歉,真的拍謝啦~
      目前沒有Arduino進階書籍的規劃。

      thanks,
      jeffrey

  6. 好棒的一本書, 圖文並茂
    寫程式幾年來第一次看到這麼令人”賞心悅目”的專業書籍^^
    想請問連書中的圖也是您親自繪畫的嗎??

    1. 謝謝~從封面插圖到最後一頁都是自己畫的,所以才會畫得頭昏眼花~ :-p

      thanks,
      jeffrey

  7. 老師請問書中12-2,我用夏普電視遙控器

    卻顯示一堆如下

    0
    0
    0
    0
    0
    這算正常嗎?

    1. 不正常,IRremote程式庫本身有支援Sharp協定,以12-15頁的程式為例,”sendNEC”指令要改成”sendSharp“。

      根據這份Sharp的LIRC(一種紅外線編碼格式)文件指出,Sharp紅外線遙控訊號資料長度為15位元,而電源開關的編碼是:0x41A2

      因此,底下的敘述將發出遙控Sharp開關的紅外線訊號,請測試看看:

      irsend.sendSharp(0x41A2, 15);

      thanks,
      jeffrey

  8. 老師我現在的問題是卡在12-2章節的地方

    當我在Arduino板接上,38KHz的紅外線遙控接收元件

    開啟序列埠監控視窗,按下夏普電視遙控器的按鈕,

    序列埠監控視窗出現如下訊息

    0
    0
    0
    0
    按一下出現一個0,請問該如何解決這個問題

    1. 老師我用一個投影機的紅外線遙控器,有解出編碼了,
      但是有時候按一下會出現正確編碼,有時候會出現全部是FFFFFF?

      按壓時間過短會出現0,按壓時間過長會出現FFFFFF,只有按壓時間適中才會出現正確編碼

    2. 接收值為0,代表IRremote不認得(unknow)該紅外線編碼,我之前用蘋果日報的壹通機遙控器,也遇到相同的情況。

      thanks,
      jeffrey

  9. 老師您好!

    第9-5頁的圖似乎接線有誤,圖上看起來是接3.4.5.6腳,但依照程式應該是接2.3.4.5腳

    另外我測試的時候似乎要將11.12腳接線對調才能運作,謝謝

    1. 阿阿,不好意思,PO完才看到9-6頁有更正了,謝謝老師

  10. 老師自從拜讀你這本書以後,我覺得各類自動控制變的好簡單,一樣的控制比起8051卻需要寫一堆繁瑣的程式,我覺得Arduino真的是太棒了

    舉例控制伺服舵機就好,Arduino輸出的信號好精準,用8051單晶片要做到輸出使伺服舵機不抖動,卻需要大量的程式.

    老師請問下例,我要讓這個固定在兩個角度之間轉動的舵機,外部開關輸入信號就另外改變角度,是要用到中斷嗎?
    該如何修改?

    #include <Servo.h&gt
    Servo servoX;
    void setup() {
      servoX.attach(8);    // 設定伺服馬達的接腳
      servoX.write(83);// 設定伺服馬達的旋轉角度
       delay(10000);
    }
    void loop() {
      servoX.write(30); // 設定伺服馬達的旋轉角度
      delay(500);
      servoX.write(120);// 設定伺服馬達的旋轉角度
      delay(500); // 延遲一段時間
    }
    1. 8051的keil c應該有伺服馬達的程式庫可用。由開關訊號改變伺服馬達的角度,只要加入判斷條件即可:

      #include <Servo.h>
      Servo servoX;
      
      const byte swPin = 7;
      
      void setup() {
        pinMode(swPin, INPUT);
        
        servoX.attach(8);    // 設定伺服馬達的接腳
      }
      void loop() {
        if (swPin) {
          servoX.write(30); // 設定伺服馬達的旋轉角度 
        } else { 
          servoX.write(120);// 設定伺服馬達的旋轉角度
        }
        delay(15); // 延遲一段時間
      }

      thanks,
      jeffrey

  11. 您好,我用了IRremote和LiquidCrystal_SR寫了一段程式,只要用它接收來自遙控器的訊號,他就會把我按下的按鈕的名稱顯示在LCD上,我以前在用74H595N以3線式接法都可以用,但是換用74LS164N加上LiquidCrystal_SR就整個程式一點反應都沒有,連續列桿通訊視窗都沒顯示東西,怎麼會這樣?

    1. hi daniel:

      請問你有引用74LS164N所需的序列LCD程式庫嗎?
      建議先測試一段文字輸出到LCD,好釐清問題出在哪一個環節。

      have fun!
      jeffrey

    2. 有啊,我拿LiquidCrystal_SR的範例跑,也什麼都沒顯示出來。

    3. 咦?請問初始化程式部分,有改成上文的敘述嗎?

      LiquidCrystal_SR lcd(8,7, TWO_WIRE);

      或者調整一下控制LCD對比的可變電阻試試看。

      thanks,
      jeffrey

    1. 對不起,我的問題已經解決了。
      經過檢查後,我發現原來是1N4148燒到了,換一個新的之後就正常運作了
      麻煩您一陣,真不好意思!

  12. 老師請問哪裡可以找到8051keil c伺服馬達程式庫的相關資料?

    網路上和市面上的書籍,沒有這部份資訊

  13. 我在大陆通过台湾的网站买了您的书籍《超圖解Arduino互動設計入門》,您的书十分经典,非常好,前几年您出得《flash编程宝典》、《flash动画宝典》我也买了,后来旅行书丢失,希望您的书两岸同步发行,多出好书,一定捧场。

  14. 老師請問我用Arduino板燒錄ATMEGA 328 IC的bootloaber時一直出現如下錯誤

    avrdude: stk500_getsync(): not in sync: resp=0x00

    我很確定照書中的接線圖正確接好線路,換了兩顆IC燒錄都出現相同錯誤?

  15. 我的板子是UNO R3

    我在你這邊爬文其他讀者和老師的問答如下: 我照做出現的錯誤一樣?

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

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

    thanks,
    jeffrey

  16. 老師我找到錯誤原因了

    原來是B-3頁的步驟1和2沒做到

    一樣還是要把燒錄bootloaber的程式,先上傳到Arduino板子裡

    因為B-5頁會讓人誤以為按下>工具/燒錄 bootloaber 就能燒錄
    bootloaber了

  17. 請問趙老師無線通信WI-FI library只支持Wi-Fi chip (HDG104) 晶片的無線網卡?這個網卡在大陸比較難以買到。如果用無線通信,您推薦什麼網卡?它是否支持官方wi-fi library呢?有別的無線通信方案?

    1. 趙老師您書裏提到橋接器,我用一下這個惠普的橋接器是否能行?您書裏說的橋接器是這類東西?r如果我把這個東西拆開,改一下電路然後接到ARDUINO板卡上供電,再與板卡上的RJ45接口連接應該是能連上無線網了哦?
      ============================================================
      品牌: HP/惠普型号: GR112路由器类型: 无线无线传输速度: 150M有线传输率: 10/100Mbps无线传输速率: 150Mbps网络标准: 802.11b 802.11g 802.11a 802.11n无线网络支持频率: 2.4G路由器应用: 宽带VPN路由器 宽带路由器 迷你无线路由器 家用路由器USB接口数量: 不支持支持VPN: 支持内置防火墙: 是WDS: 支持WPS: 支持无线天线: 不可拆售后服务: 全国联保价格: 小于150元成色: 全新
      http://detail.tmall.com/item.htm?spm=a230r.1.14.232.iaccBF&id=17944458962
      ===========================================================================

    2. 我沒有用過Arduino的WiFi擴充板,主要是沒有這方面的需求。

      一般的無線路由器都有橋接器(bridge),像水星(Mercury)的迷你便携式路由器MW150RM,也有提供bridge模式(註:根據廠商的規格說明,自己沒用過),一個約40元人民幣,提供你參考。

      thanks,
      jeffrey

  18. 作者您好
    書中9-5頁的圖中,LCD的D4~D5接在板子的pin3~pin6
    而arduino官網是接在pin2~pin5
    若照您的接法只修改

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
    行嗎?還是需要修改LiquidCrystal.h其他地方?
    謝謝

  19. 老師請問書中B9頁,使用市售的Arduino板充當USB介面卡之二

    麵包板圖22uF電解電容旁邊那條黑線是否畫錯?

    我覺得好像要接+電壓才對是嗎?那條黑線和22uF電容並連,好像不合理

  20. 老師您好,我照著附錄B自製Arduino版時,照著動手做B-2的四種方法上傳程式檔
    都會顯示avrdude: stk500_getsync(): not in sync: resp=0x00耶
    我是使用Arduino Uno板,請問是什麼原因呢?

    1. hi tony:

      那個錯誤訊息代表Arduino板子沒有回應。另外,在燒錄之前,你有選擇”Arduino Duemilanove”這個板子嗎?雖然你用的是UNO,但是「燒錄目標」是”Duemilanove”板。

      thanks,
      jeffrey

    2. 老師您好!
      我想我可能是燒成UNO了,不知道有沒有辦法覆蓋呢?
      因為我重新燒錄他都會顯示Error : Double check connections and try again, or use -F to override this check.
      線路是照動手做B-1的線路,檢查很多次,應該是沒接錯

    3. hi tony:

      Bootloader可以反覆燒錄。
      如果你的UNO板的Reset端子有連接10μF電容,請先將它取下。
      把UNO板連接電腦USB埠之後,等待數秒,執行燒錄之前再接上10μF電容。

      thanks,
      jeffrey

    4. 老師您好!
      我去買了一個新的ATmgega328,燒錄Duemilanove的bootloader進去,可以使用第一種方式上傳程式了。
      可是TTL線的方法還是不行,我想可能是TTL線壞了…

    5. 請試試看把TTL線接到你燒錄好的ATmega328,看能不能透過它上傳Arduino程式,或者收發「序列埠監控視窗」的訊息。

      have fun!
      jeffrey

  21. diy8-2:

    如果要用 “共陽極 8×8 LED 矩陣”,8-15 頁的圖可以用嗎? diy8-3 的程式要怎麼改?

    1. 可以,請參閱8-21頁「顯示單一矩陣圖像」的圖說,若是共陽極,點亮的部份要標示成0。

      因此,原本第一行的數據:

      B01100000

      要改成:

      B10011111

      以此類推。

      thanks,
      jeffrey

    2. 這樣子好像不行???譬如在掃描 D0 行時,D0 的電位為 LOW,而 D0 行為 “共陽極”,LED 應該不會亮。max7219 能改變掃描時的電位嗎???

    3. 那個,我手邊只有一顆共陽極 8×8 LED 矩陣,我要用那個編號的 IC,來代替 max7219。。。謝謝

    4. 我昨晚再看一次MAX7219的規格書,它的「一般說明」(第一段文字)就寫著:”common-cathode display drivers”(共陰極)驅動器。

      抱歉,之前沒有仔細看說明書。

      thanks,
      jeffrey

  22. 老師請問超音波模組,有什麼辦法可以防水蒸氣和沼氣之類,這些有侵蝕性的氣體嗎?

    我們公司裡有鍋爐排出來的水到一儲存水槽,但是用傳統浮球開關來偵測滿水位,
    常常這些侵蝕性的氣體,破壞浮球開關裡面的彈簧而造成故障,
    我想說能不能用超音波模組來做偵測,以便取代浮球開關,
    用玻璃來隔絕侵蝕氣體,超音波好像也無法穿透,不知道有什麼好方法?

    感謝老師能出這本書,讓我能學習到很多這輩子可能都無法學到的技術.

  23. 救led矩陣跑馬燈的問題 關於互動設計入門書中的範例好像不能work?請問有能成功了?或程式有問題 謝謝

  24. 範例動手做8-6 P8-35 我直接把範例的程式碼貼上 沒有work! 不知道是我laqbrary沒導入成功 還是程式碼有問題
    謝啦!感謝 : )

  25. B-9頁電路更新接法, 上傳範例給麵包板 Arduino 時, 總會出現
    avrdude: stk500_getsync(): not in sync: resp=0x00
    還請老師指教

    1. hi jrbill:

      我現在手邊沒有足夠的零件可以組裝麵包板Arduino,我下週內購齊之後再測試看看,這期間煩請先用B-8頁的方案,謝謝!

      thanks,
      jeffrey

    2. B-8頁的方案, 一樣出現「avrdude: stk500_getsync(): not in sync: resp=0×00」。
      乾脆拆了Uno Rev3上的ATmega328P-PU,換上已燒錄bootloader的新328P-PU,直接Upload程式。 orz

    3. 我剛剛測試了B-9頁的電路,沒有問題。請問你有在Arduino的IDE裡面選擇「工具→板子→Arduino Duemilanove w/ATmega328」選項嗎?

      thanks,
      jeffrey

  26. 請問如果我照超圖解Arduino互動設計的第15章往崁入式網站伺服製作,是不是可以架設一個可以把網頁放在製作的硬體裡面,並可以在google、yahoo..搜尋可以搜尋到?
    我用的網頁製作軟體是用KompoZer製作網頁的他要求要上傳至ftp上。

    1. hi condy:

      Arduino網路卡的主要用途是,提供一個方便透過瀏覽器存取的遠端監控介面,例如,顯示溫濕度值,或者開關控制按鈕,並不適合用來架設一般性質的網頁。

      如果你想要建置一個小型網站,可考慮購買可刷入OpenWRT等韌體的無線網路基地台(維基百科有完整的自訂韌體專案列表)。

      thanks,
      jeffrey

  27. 老師您好,我在閱讀時發現,4-27頁void loop{}的程式碼中 if 條件式是否應該改成index < (total -1),不然我自己心中模擬時發現照書上的程式碼會讓13腳也會亮了以後,才將index歸零。

    經您回復和提醒:跑馬燈的腳位記錄在LEDs陣列裡面,
    index是陣列的索引,
    讀取LEDs裡的元素值,
    所以不會控制到13腳。

    讓我了解果然是如此,不過我還是有個問題就是

    這樣的條件式,程式還是會對LEDs[5]輸出高電位,只是沒有這個陣列元素,對嗎?

    1. 確實錯了,正如你說的,4-27頁的loop()程式區塊應改成:

      void loop() {
        for (byte i=0; i
      

      感謝告知!

      另外,LEDs[5]未定義,它可能是任何值,如果剛好是控制腳位的編號值,它就會被點亮。

      thanks,
      jeffrey

  28. 老師您好,在閱讀時發現在6-8頁,光敏電阻的程式碼裡,定義了CdS常數等於A0,不過後面的程式碼並未利用此常數來代替A0。

  29. 老師您好:D-3頁最下方的表D-1中的Mega 2560板,根據ATmega2560的Arduino Pin Mapping,它的中斷編號INT0~INT5對應的腳位順序好像應該是21,20,19,18,2,3。

    1. hi charles:

      根據MEGA 2560官方資料,表D-1的中斷編號是正確的:

      External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2)

      thanks,
      jeffrey

  30. 使用 WED 伺服器的時候 使用迴圈

    好像要等他跑完回圈才可以執行其他動作,在執行迴圈這段時間,在網頁上執行指令他會無反應

    請問有解決的方法嗎?

    要等他執行完三次

    才能使用其他指令

    for (int i=0; i <= 3; i++){

    digitalWrite(LED_PIN, HIGH);

    delay(12000);

    digitalWrite(LED_PIN, LOW);

    delay(12000);

    1. 這不是 Web 伺服器程式的問題,請參閱13-38頁說明,在delay()期間,微處理器會呈現「放空」狀態,不做任何事。所以,如果你需要以12秒為週期,點亮和熄滅LED,應該改用「計算時間差」來完成,例如:

      // 以3秒為週期,點滅LED。
      const int ledPin =  13;		// LED接腳	
      boolean ledState = LOW;		// LED狀態
      
      unsigned long startTime;	// 儲存起始時間
      
      void setup() {
        pinMode(ledPin, OUTPUT);
        startTime = millis();		// 儲存目前的時間(微秒數)
      }
      
      void loop()
      {
        if(millis() - startTime > 3000) {	// 若目前時間和起始時間相差超過3秒,則:
          ledState = !ledState;		// 反轉LED狀態
          
          digitalWrite(ledPin, ledState);	// 依據LED狀態值點滅LED
          startTime = millis();		// 重設起始時間
        }
      }
      

      底下程式則是以3秒為週期,點滅LED六次(註:點亮和熄滅各算一次,因此實際看起來是閃爍3次):

      const int ledPin =  13;
      boolean ledState = LOW;
      byte blinkTimes = 6;	// 閃爍總數
      byte counter = 0;	// 閃爍次數計數器
      
      unsigned long startTime;
      
      void setup() {
        pinMode(ledPin, OUTPUT);
        startTime = millis();
      }
      
      void loop()
      {
        if (counter < blinkTimes) {	// 如果未達閃爍次數,則:
            if(millis() - startTime > 3000) {
              ledState = !ledState;
          
              digitalWrite(ledPin, ledState);
              startTime = millis();
              counter ++;		// 閃爍之後,增加閃爍計數器值
          }
        }
      }
      
  31. 老師您好,請問有哪些積體電路可以減少紅外線接收器所佔的腳位呢?與Arduino連接的電路、程式碼以及積體電路的運作又是如何呢?

  32. 需要用到六個紅外線接收器,用來當作模擬打靶的靶子用的

    謝謝老師的回覆

    1. 我也曾想製作一個雷射槍標把,我有買一個Wii控制器的槍枝套,附帶一個紅光雷射瞄準器。這個老外用Nerf玩具槍,加上雷射簡報筆修改,標把上的感測器則是用光敏電阻(接Arduino的類比埠,正好可以接6個,Leonardo板則可以接12個):

      使用紅外線編碼的標把,也有不少現成的案例:

      最近在Kickstarter眾籌平台上,也有一款「開放原始碼」的紅外線生存遊戲玩具槍成功募集到近10萬美金,提供你參考:
      Skirmos: Open Source Laser Tag

      採用紅外線的好處是,光束(數據)經過編碼,因此不容易受到干擾,而且能允許多人同時對戰(每一把槍枝發射的編碼不同)。但如果在室內一個人玩,用雷射光束加光敏電阻,製作起來簡單多了。

      thanks,
      jeffrey

  33. 你好 我造您給的 程式碼修改了一下
    但是 我修改後不會動了 可以幫我看一下嗎 謝謝

  34. 改成以下這樣 他時間不會跳耶

    void postCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
    {
      char name[16], value[16];
      server.httpSuccess();
    
      if (type == WebServer::POST)
      {
        server.printP(htmlHead);
        while (server.readPOSTparam(name, 16, value, 16)){
    
          if (strcmp(name, "light") == 0) {
            server << "燈光已經";
            if (strcmp(value, "ON") == 0) {
              server << "打開。";
              for (int i=0; i <= 255; i++){
                 digitalWrite(LED_PIN, HIGH);
                 delay(60000);
                 digitalWrite(LED_PIN, LOW);
                 delay(300000);
              }  
            }  
          } else {
             server << "關閉。";
             digitalWrite(LED_PIN, LOW);
          }
        }
      }
      server.printP(htmlFoot);
    }
    
    1. 如同之前的留言提到的,在delay()期間,微處理器會呈現「放空」狀態。我假設你需要的功能是:

      按下「開燈」按鈕,LED將點亮10秒(你可以調整成其他秒數),然後自動關閉;按下「關閉」鈕,LED將立即關閉。

      請在程式開頭新增三個變數宣告:

      const byte LED_PIN = 8;
      boolean ledState = LOW;          // LED狀態
      unsigned long ledTimer = 10000;  // 假設點亮10秒
      unsigned long startTime;         // 儲存起始時間
      static byte mac[] = { 0xF0, 0x7B, 0xCB, 0x4B, 0x7C, 0x9F };
      

      處理POST請求的命令改成:

      void postCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
      {
        char name[16], value[16];
        server.httpSuccess();
      
        if (type == WebServer::POST)
        {
          server.printP(htmlHead);
          while (server.readPOSTparam(name, 16, value, 16)){
            if (strcmp(name, "msg") == 0) {
              server << "<h1>" << value << "</h1>";
            }
      
            if (strcmp(name, "light") == 0) {
              server << "<p>燈光已經";
              if (strcmp(value, "ON") == 0) {
                server << "打開。</p>";
                ledState = HIGH;
                startTime = millis();            // 儲存目前的時間(微秒數)
              } else {
                server << "關閉。</p>";
                ledState = LOW;
              }
              digitalWrite(LED_PIN, ledState);   // 開燈或關燈
            }
          }
          server.printP(htmlFoot);
        }
      }
      

      主程式迴圈改成:

      void loop() {
        webserver.processConnection();
        if (ledState) {    // 若LED狀態為1 (HIGH)
           if(millis() - startTime > ledTimer) {// 若目前時間和起始時間相差超過10秒,則:
              ledState = LOW;               // 重設LED狀態
              digitalWrite(LED_PIN, LOW);    // 關閉LED
            }
        } 
      }
      

      thanks,
      jeffrey

  35. 不好意思 在請教一下 如果我要讓剛剛您給的程式 讓他 跑2分鐘然後休息15分鐘 這樣應該如何修改呢?

    1. 你需要找一張紙和一支筆,把自己當成電腦,想像一下loop()函數裡的程式是如何延遲10秒鐘的,從中著手修改即可。

      good luck!
      jeffrey

  36. 您好,想請教如何將感測器讀到的數據經由 com port 傳至以 vb 2010 寫成的程式中,而不是傳至 arduino 內建的序列埠監控視窗?我找了幾個範例都不能成功,會出現無權讀取 com port 的字樣

    1. hi borstquc:

      根據老外這一篇VB 2010控制Arduino UNO的說明,啟動VB程式時,你必須先關閉Arduino的序列埠監控視窗,否則會出現無權讀取com port的錯誤訊息,原文如下:

      WARNING: On my PC I had to close the Arduino IDE Serial Monitor window while runing the VB program, else I run into all sorts of error message about COM port access denied and the program will fail.

      have fun!
      jeffrey

  37. 感謝您的回應,的確關掉監控視窗後就可以了。目前遇到另一個問題,就是我用 PING))) 收進來的資料,在 vb 2010 中以 Timer 每間隔 400 ms 讀取一次 SerialPort 傳進來的資料,然後打算依據「距離」做一些後續處理,但傳進來的資料很難「對齊」,我的意思是:第一次(in 400ms)你可能捉到兩筆 PING))) 傳來的「距離」,但第二次你可能捉到三筆「距離」,這樣很難做後續處理,不曉得您有沒有什麼好主意?謝謝回答。

    1. 拍謝,不太了解這個需求,不能只從中篩選一個或者加以平均嗎?

      have fun!
      jeffrey

  38. 老師你好:
    你書本上 D-13頁: 零位偵測電路(H11AA1元件),IC Pin1 陽極串了一個限流電阻33k 1/2w,如果公式計算
    110V/ 33K= 3.3ma,所以P=V * I =363mW,約0.36w,所以你用33k 1/2w那這樣是沒問題
    我想請教你的,當你發射端電流那樣小,LED會被點亮?,那限流電阻大小應如何設計

    下面是我捷取H11AA1 data sheet 第二頁說明:
    當順向電流 +-20ma, Led 壓降 典型值:1.2v 最大值:1.5v

    ELECTRICAL CHARACTERISTCS (Tamb = 25 °C, unless otherwise specified)
    PARAMETER TEST CONDITION SYMBOL MIN. TYP. MAX. UNIT
    INPUT
    Forward voltage IF = ± 10 mA VF 1.2 1.5 V

    1. 未達額定工作電流,LED仍可被點亮,只是光線比較微弱。光耦合元件的另一邊是光電晶體,如同第13-13頁光電子琴製作單元裡的反射型光電開關實驗,光電晶體(B極)接收的反射光越強,流入C極的電流也越大。

      底下曲線圖取自Motorola公司的H11AA1規格書第3頁,從此圖中間的LED順向電流(IF)曲線可看出,當順向電流為10mA時,光電晶體CE腳位之間的電壓和C極電流,呈現比較線性的變化,而且C極電流可達28mA(註:H11AA1的最大容許順向電流為60mA)。

      集極電流與CE腳電壓比

      但即使LED的順向電流(IF)為2mA,C極仍可流入電流,代表電晶體導通了,只是這個通道太窄,無法流入大量電流(註:H11AA1光電晶體的集極電流放大率為500)。

      底下是H11AA1光電晶體部分的電路,它並不需要驅動LED或馬達等負載,只是在C極連接一個上拉電阻,好讓我們取得高、低電位狀態(亦即,是否偵測到零交越點),因此,只要能讓光電晶體導通就能運作了。

      光電晶體的上拉電阻

      此處的上拉電阻採10K,用20K或更高的電阻值應該也無妨。

      你可以降低H11AA1光二極體側的限流電阻值,以獲得較高的順向電流,但這麼做的話,電阻的發熱量和瓦數也要提高,所以絕大多數的應用電路都採用15K到33K之間的阻值。

      以底下的零交越偵測電路為例:

      H11AA1零交越偵測電路

      其內部光二極體的順向電流約為3.6mA:

      順向電流計算式

    1. 你輸入的HTML標籤被blog系統過濾掉了,
      在此輸入大於符號(>)時,請寫成:&gt;
      小於符號(<)請寫成:&lt;

      我猜想你的意思是:
      <img src="影像路徑和檔名">

      不過你給影像IP格式有誤,所以連不上。

      thanks,
      jeffrey

  39. 最後我改成
    “”
    這樣就可以了(上篇留言的IP我只是舉例而已)
    不過我現在還有個問題想請問一下
    在SW這個表單裡面 如何執行 開燈以後自動轉往只到https://tw.yahoo.com/

    我試過

    “<meta http-equiv=\”refresh\” content=\”停留秒數;url=https://tw.yahoo.com/\”>\n”;

    這樣並不行
    應該如何寫呢?

    1. 若要回應新的網址給用戶端,可透過HTTP 3xx重新導向訊息達成。像底下的HTTP 303訊息,將令用戶端轉到https://swf.com.tw網址。
      HTTP 303重新導向訊息
      我們不需要自行用print()指令輸出上述的HTTP訊息,因為Webduino內建httpSeeOther()指令,就能達到相同的效果。

      請將diy16_4的postCmd()自訂函數改成底下的程式,每當用戶在表單欄位輸入”bye”,並送出表單,瀏覽器將會被重新導向到https://swf.com.tw。

      void postCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
      {
        char name[16], value[16];
        boolean redirect = false;
        
        if (type == WebServer::POST)
        {
          while (server.readPOSTparam(name, 16, value, 16)){
            if (strcmp(name, "msg") == 0) {
      	// 如果用戶輸入"bye"
              if (strcmp(value, "bye") == 0) {
                 redirect = true;
              }
            }
            
            if (redirect) {
      	// 重新導向到 https://swf.com.tw
              server.httpSeeOther("https://swf.com.tw");
            } else {
              server.printP(htmlHead);  
              if (strcmp(name, "light") == 0) {
                server << "<p>燈光已經";
                if (strcmp(value, "ON") == 0) {
                  server << "打開。</p>";
                  digitalWrite(LED_PIN, HIGH);
                } else {
                  server << "關閉。</p>";
                  digitalWrite(LED_PIN, LOW);
                }
              }
            }
          }
        } else {
          // 如果用直接開啟此 /sw 頁面,就顯示底下的訊息。
          server.httpSuccess();
          server.printP(htmlHead);
          server.print("這是SW頁面");
        }
        server.printP(htmlFoot);
      }
      

      thanks,
      jeffrey

  40. 老師您好~~
    我是第一次學arduino 可是專題要做16*16矩陣的跑馬燈
    但我上網查資料不知如何下手
    所以可以麻煩老師 寫16*16矩陣的跑馬燈讓我參考嗎
    謝謝老師~~~~~

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

    書本上的接線圖說明和範例的傳送 ,接收 接法都錯,

    SoftwareSerial BT(10, 9); // 傳送 RxD,接收 TxD

  42. 老師您好~~
    我想問如何控制2個以上的LED矩陣
    書中的LED矩陣只有介紹控制一個而已
    可不可以告訴我呢?

  43. 請敎老師:

    當我在UNO板上同時接了超音波感器(D9,D10)及水位感測器(A3)時,
    水位感測器上的值,會因為超音波感器測量到距離開變時,而影響到水位感測器的回傳值,該如何排除此問題.

    ps : 板子上還有一個繼電器(A5),當水位過高時蜂鳴器會發出聲音.

    謝謝.

    1. hi chen:

      不是很了解你的問題,每個感測器值不是該有獨立的判斷條件式嗎?

      thanks,
      jeffrey

    2. 是的每個都有獨立的判斷條件式沒錯,但不知為何當所有感測器都裝在板子上時,會發現當超音波感器測到有人走近時,在觸發繼電器開啟LED燈,會讓水位感測器的值往上跳多出10以上的值(水位感測器因沒碰到水,理因保持在0,但繼電器一啟動(開燈動作),水位感測器測量回來的值會是10~20間),而當人離開時,水位感測器又恢復正常值,不知是否繼電器會干擾到類比脚位的回傳值呢?

      PS:我確認不會是程式的問題..

      再次謝謝老師撥空回答

    3. 請嘗試在微處理器和繼電器之間,加上一個光耦合器(如:PC817)測試看看:

      光耦合器隔離繼電器電路

      thanks,
      jeffrey

    4. 再次請敎老師:

      我用的是1路繼電器模塊帶光耦隔離,是否本身就有光耦合器,我還須要再加裝嗎,
      我發現,只要繼電器一啟用(ON時),使用analogRead()回傳的值都會加一些,
      如LM35溫度偵測模組也會.

    5. 加了光耦仍會干擾啊……那請把Arduino和繼電器模組分開用不同的電源模組供電試試看。

      thanks,
      jeffrey

發佈留言

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

Related Posts

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

Back To Top