2016年12月31日 星期六

[玩轉光立方] LED Cube 4x4x4 for Arduino UNO -- 組裝教學

自從當了 Maker 之後,一直都覺得 LED Cube 光立方是一個非常酷炫的裝置,當它發光時視覺上不僅炫耀奪目,而且其中還隱藏了不少的數學原理,非常建議老師、家長和同學一起來玩玩。



我們先來看看影片 https://www.youtube.com/watch?v=XIb07gRdHn8


準備


材料
1. 電路板 *1
2. 公排針 *40P
3. 圓孔母排針 *20
4. 3mm 長腳 藍色霧面 LED *64


工具
1. 烙鐵 + 焊錫
2. 斜口鉗
3. 尖嘴鉗
4. 鑷子
5. 厚紙板
6. 電鑽 + 3mm 鑽頭
7. 原子筆或細簽字筆
8. M3*14mm 螺絲+螺帽 *4
9. 電阻 100~220R *1
10. 麵包板


開始動手做


一、檢查所有的 LED 是否有正常發亮

您購買的 LED 即使廠商如何口沫橫飛地述說它們品質是如何地好,建議您也必須要自己詳細查驗,否則您可能有機會遇到懊惱的時候。

1. 計算限流電阻。

藍色 LED 順向電壓約 3.0~3.4V (注意:顏色不同,可承受的電壓也不同),我們取 3.2V 來計算:

(5 - 3.2) / 15mA = 120R

可採用 100R 或 110R 電阻。

2. 將電阻與 5V 電源插入麵包板,逐一插入 LED,檢查 LED 是否正常發光。
將 LED 插入麵包板時要注意 LED 的正負極。



二、彎折 LED

1. 取出尖嘴鉗輔助彎折 LED,我們需要彎折出 3 種型式的 LED,圖面右側是未彎折前。
在彎折時須注意 LED 的正負腳,正腳在彎 2 折後仍保持與燈珠同方向,並且每一彎折應盡量保持90度角,如下:

Type A * 48只


Type B * 12只


Type C * 4只


小聲地說...這個工作我是一邊看電視一邊彎折的,不然要彎折 64 只 LED 還真是挺無聊的事情。


三、製作固定 LED 的模板

這個模板可以用來插入 LED,如此可以讓 LED 排列整齊,在焊接時不會移位。

1. 準備一張厚約 1~3mm 的硬紙板。我隨手找了個 68x68mm 的蛋糕盒。



2. 在上面畫上間距 14mm 的九宮格。14mm * 3 = 42mm,九宮格邊長是 42mm。
我先畫上交叉線找出盒子中心點,再由中心點往外畫出九宮格。


3. 用電鑽在交點處鑽出 16 個 3mm 圓孔。


四、將圓孔母排針焊到電路板上

1. 將 20 支圓孔母排針插到電路板上。板子有兩面,要注意方向。


2. 為了焊接前翻轉電路板,避免排針掉落,我將 Arduino UNO 板子疊上去,用 M3*14mm 螺絲+螺帽 *4 將他們鎖在一起。
在將螺絲鎖緊前可用手指頭輕敲電路板讓排針垂直站立,邊敲邊觀察哪支排針沒有垂直,此時可用鑷子調整排針。


這是翻轉後的樣子


3. 由於有少數幾支排針與螺帽非常接近,因此我先焊接中央部分的排針,待焊到螺帽旁的排針時再移除螺帽焊接排針。
您的焊接接技術一定比我好,就不必移除螺帽可直接焊接。



五、焊接公排針

1. 用斜口鉗將公排針剪出

6P * 2只
8P * 2只


2. 將上述排針(長)插入 Arduino UNO。注意圖片中排針的位置。


3. 對準公排針孔位,放上 LED Cube 電路板,須注意電路板正反面。
底下圖片是焊接好的樣子。




六、焊接 LED

先來看看我們要做出怎樣的東西


我把紙模寫上座標以利辨識


1. 將 Type A 插到座標(0,0)~(3,2)之間區塊,共 12 只。
注意 LED 的腳位方向。


2. 將 Type B 插到座標(0,3)~(2,3)之間直線,共 3 只。
注意 LED 的腳位方向。



3. 將 Type C 插到座標(3,3),共 1 只。
注意 LED 的腳位方向。


4. 將 LED 所有的負腳全部焊接在一起。
圖片中是焊接好取出的樣子。


5. 您需要做 4 組(L0~L3)上面圖片的 LED 層面。

6. 將 4 組 LED 層面的正腳都焊起來。
注意正腳搭接長度大約是 8mm 左右,盡量讓你的 LED 排列呈現出正方形。



7. 在 L0~L3 每一層的負腳(上圖黑色導線)各焊上一條導線。



8. 先將光立方電路板插入 Arduino UNO,再將整組 LED Cube 小心地插入圓孔排針,並且將 4 條導線另一端也插入圓孔排針,至此大功告成。



程式

//2017-01-01 LED_Cube4_01.ino
//從頂層到底層逐一點亮 LED

#define CUBE_SIZE 4
#define PLANE_SIZE CUBE_SIZE*CUBE_SIZE
#define PLANE_TIME 20
#define LED_TIME 500

int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1};
int PlanePin[] = {A2 , A3, A4, A5};

void setup()
{
  int pin;
  for (pin = 0; pin < PLANE_SIZE; pin++) {
    pinMode(LEDPin[pin], OUTPUT);
    digitalWrite(LEDPin[pin], LOW);
  }
  for (pin = 0; pin < CUBE_SIZE; pin++) {
    pinMode(PlanePin[pin], OUTPUT);
    digitalWrite(PlanePin[pin], HIGH);
  }
}

void loop()
{
  for (int plane = 0; plane < CUBE_SIZE; plane++)
  {
    digitalWrite(PlanePin[plane], LOW);
    for (int led = 0; led < PLANE_SIZE; led++)
    {
      digitalWrite(LEDPin[led], HIGH);
      delay(LED_TIME);
      digitalWrite(LEDPin[led], LOW);
    }
    digitalWrite(PlanePin[plane], HIGH);
    delay(PLANE_TIME);
  }
}

程式說明

1. UNO 腳位 D0~D13 & A0~A1 分別控制每一顆 LED,D0 控制的 LED 是靠近 D0 腳位那一顆,A1 腳位則是控制距離 D0 最遠的那一顆 LED。A2 控制頂層 LED,A5 則是控制底層 LED。

2. 把所有的腳位都設定成 OUTPUT,才可以指定它要 HIGH 或 LOW。當指定它為 HIGH 時電位是 5V;當指定它為 LOW時電位是 0V,相對於 5V 而言可以把它視為是 GND。

3. 在初始階段為了讓所有的 LED 都不亮,所以在 setup() 階段將 16只 LED 腳位都設為 LOW,並且將控制層面的 4 只腳位都設為 HIGH。

來看看影片




相關連結

1. LED 限流電阻計算 http://gc.digitw.com/Program/Resistor4LED/Resistor4LED.htm
2. Arduino UNO 開發板 https://www.arduino.cc/en/Main/ArduinoBoardUno
3. 玩轉光立方 LED Cube 4x4x4 -- 程式2 http://pizgchen.blogspot.tw/2017/01/led-led-cube-4x4x4-2.html
4. 圖形編輯器 https://www.robota.nl/en/blog/led-cube-4x4x4-pattern-designer/led-cube-simulation-and-pattern-generator.html
5. 免費的專業圖形編輯器 http://www.solderlab.de/index.php/software/glediator


採購資訊

光立方 LED Cube 4x4x4 http://goods.ruten.com.tw/item/show?21652958873589




2016年12月17日 星期六

DIY 音樂門鈴

這是一款非常簡單的音樂門鈴套件,除了適合國中小學生工藝課之外,也適合親子在假日一起動手做。


準備材料與工具


材料

088BD 音樂模塊 * 1
電晶體 S9013 * 1
電容 103 * 1
8R 小喇叭 * 1
按鈕 * 1
電池盒 * 1
電線 長度約 1M
外殼 * 1
電工膠帶 少許


工具

斜口鉗
尖嘴鉗
烙鐵 + 焊錫
M3十字起子


開始動手做

電源部分

1. 將鐵片置入背蓋的電池盒內。背蓋上方是 1 個大鐵片,下方是 2 個小鐵片,注意彈簧那個小鐵片是安裝在右側。


2. 翻轉背蓋,將突出的鐵片往外彎曲90度固定,以防止鐵片脫落。


3.注意正負極位置,將電源線焊上。(圖上的"+ -"符號是我用簽字筆寫上去的)



按鈕部分

1. 將白色電線夾入簧片。簧片裏面有尖齒,只要用尖嘴鉗緊壓簧片,尖齒會穿透電線膠皮進而導電。

為以防萬一,我多做了一小段裸露電線伸到簧片圓圈裏,待會兒再用螺絲鎖上時可接觸形成導通。


2. 用螺絲將一個簧片鎖入按鈕帽後,放到白色按鈕盒的洞口,並插入 2 個彈簧。



3. 用螺絲將簧片和長鐵片鎖上。



喇叭部分

1. 取 2 條電線分別焊到喇叭的正負極。



電路板部分

這是簡易電路圖,您可以注意一下圖中並沒有標示出 103 電容的位置。


由於這個套件是使用一只 -088BD 音樂 IC,我找到另一個比較詳細的電路圖,它有標示 103 電容的位置,您可以將這兩張圖互相對照一下。


如果材料包裏面的電晶體不是 S9013 而是 S8050,如此也沒有影響。其中 S9013 和 S8050 都是 NPN 型電晶體,而且集極電流最高都可以承受到 500mA,在一般情況下這兩款電晶體可以互相替用。

在將電晶體插入電路板時要注意電晶體的腳位。


我按照上面電路圖焊接後出現 2 個問題,一個是裝上電池後即使沒有按下按鈕,音樂也會一直響個不會停;另一個問題是這樣的接線方法電池會一直耗電。

於是...以下是我修改後的方法,在沒有按下按鈕時整體電路是不會耗電的。

1. 將電晶體和電容如下圖插入電路板並焊接。注意 103 電容腳位沒有正負極之分,它其中一隻腳與電晶體的 C 腳是插在同一個孔。


2. 將電源負極線焊到電路板的負極,也就是電晶體 E 腳。
3. 將電源正極線與按鈕任意一條線焊接,然後用絕緣帶纏繞以防短路。
4. 將按鈕另一條線與喇叭正極線焊到電路板的正極。
5. 將喇叭負極線焊到電路板上電晶體 C 腳。


底下是網友「海陸健兒」提供的接線方式。(感謝海大)



組裝

1. 將喇八輕輕壓入前蓋,如果覺得不夠緊固可以在喇叭與前蓋交界處周圍塗佈一圈快乾膠或熱熔膠。



2. 裁一小片紙膠帶貼住電路板焊接部位,以避免跟其它電線碰觸導致短路。

3. 將電路板放入喇叭旁的空間,按鈕電線從前蓋角落的小缺口穿出,將前蓋與背蓋闔上並用螺絲鎖緊,最後蓋上電池蓋。



這是完成圖




相關連結

S9013 Datasheet http://html.alldatasheet.com/html-pdf/311426/DAYA/S9013/94/1/S9013.html
S8050 Datasheet http://html.alldatasheet.com/html-pdf/154210/WEITRON/S8050/292/1/S8050.html
祝你生日快樂電子蠟燭 http://www.ttfanwen.com/info_10/fw_2350307.html


採購資訊

音樂門鈴套件 http://goods.ruten.com.tw/item/show?21630190930598



2016年11月13日 星期日

自製紅外線遙控器

這裡我們不講硬體如何製作,而是說明如何用 Arduino 發射特定的紅外線編碼,藉以模擬出家裏的遙控器。


材料清單

接收部分
1. Arduino 開發板 *1
2. 紅外線接收模塊 *1
3. 杜邦線 *3P

發射部分
1. Arduino 開發板 *1
2. R1電阻 100R *1
3. 紅外線發射LED2 *1
4. 杜邦線 *2P


紅外線接收電路

電路接線和程式碼詳 http://pizgchen.blogspot.tw/2016/11/blog-post_13.html


紅外線發射電路

有三種電路方式,都可以作為紅外線發射電路,如下圖:


為方便起見我們採用左側那個電路,但實際應用時最好採用右側電路,因為發射信號的距離會比較遠。實際電路接線如下圖:




讓 Arduino 發射 38KHz 的信號

請您先將下列程式碼 Upload 到 Arduino,然後將紅外線發射管對準紅外線接收器,並開啟接收器的 Serial Monitor:

#include <IRremote.h>
IRsend irsend;

void setup() { }

void loop() {
  for (int i = 0; i < 3; i++) {
    irsend.sendSony(0xa90, 12); // Sony TV power code
    delay(100);
  }
  delay(1000);
}

您應該可以看到大概如下圖所示的畫面,在接收端的確有收到來自發射端發出的信號「A90」。



如果您夠仔細的話,應該會發現到雖然我們使用 D3 腳位作為發射紅外線信號,但我們並未在 setup() 區段內指定 D3 腳位的 pinMode 為 OUTPUT,那麼為什麼還可以正常發射 38KHz 信號呢? 因為 IRRemote Library 使用 Timer2 中斷,而 Timer2 是設定在 D3 腳位。

另外要提醒您,tone() 函式也是使用 Timer2 中斷,所以您如果同時使用 tone() 函式讓 Arduino 發出聲音,並且也使用 IRRemote Library 讓紅外線發射 38KHz 信號,您會發現它們無法同時作用。


發射紅外線編碼

Arduino 有內建許多廠商的紅外線編碼函式,如下

void sendNEC(unsigned long data, int nbits);
void sendSony(unsigned long data, int nbits);
void sendRC5(unsigned long data, int nbits);
void sendRC6(unsigned long data, int nbits);
void sendDISH(unsigned long data, int nbits);
void sendSharp(unsigned long data, int nbits);
void sendPanasonic(unsigned int address, unsigned long data);
void sendJVC(unsigned long data, int nbits, int repeat);


其實 KEYES 遙控器是採用 NEC 編碼格式,因此如果您想發出「1」的編碼,可以

irsend.sendNEC(0xFF6897, 32);

如果是未知廠商的編碼,您可以使用下列函式

void sendRaw(unsigned int buf[], int len, int hz);

以發射 KEYES 遙控器為例,如果要發射按鍵「1」的編碼,程式碼如下

unsigned int raw_1[68] = {0xB3,0x5A,0xB,0xC,0xB,0xC,0xB,0xD,0xA,0xC,0xB,0xD,0xA,0xD,0xA,0xD,0xA,0xD,0xA,0x22,0xB,0x22,0xA,0x22,0xA,0x23,0xA,0x22,0xA,0x22,0xB,0x22,0xB,0x21,0xB,0xC,0xB,0x22,0xA,0x22,0xB,0xC,0xB,0x22,0xB,0xC,0xA,0xD,0xB,0xC,0xA,0x22,0xB,0xC,0xB,0xC,0xB,0x22,0xB,0xC,0xA,0x22,0xB,0x22,0xB,0x21,0xB,};

irsend.sendRaw(raw_1,68,38);



進階題目

聲音函式和紅外線發射函式真的無法同時使用嗎? 答案是否定的。只要讓 tone() 函式和紅外線發射函式不使用同一個 Timer 中斷,如此即可解決問題,但此問題不在本文的討論範圍內。


相關連結

Timers and Interrupts http://letsmakerobots.com/node/28278


採購資訊

紅外線遙控器套件 http://goods.ruten.com.tw/item/show?21628077374704



找出紅外線遙控器的編碼

為了避免遙控器互相干擾,各家電器廠商大都會自訂該公司專屬的紅外線編碼,例如 SONY、JVC、PANASONIC...。

如果你家的遙控器壞掉了或是不見了,那該怎麼辦呢? 比較方便的方式就是再去買一支,再不然就是...自己做一支。

找出遙控器的編碼是一個關鍵,本文就是在說明如何找出遙控器編碼。


材料清單

1. Arduino 開發板
2. 紅外線接收模塊



電路接線

Arduino      紅外線接收模塊
VCC         中間腳(橙色線)
GND        「-」(綠色線)
D3            「S」(黃色線)


程式碼

以下程式可以找出大部分紅外線遙控器的編碼,包括 KEYES 紅外線遙控器套件的編碼。

#include <IRremote.h>

int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
}

您可以發現 Serial Monitor 內的資料正是 KEYES 這款遙控器套件的編碼。



後記

南桃園電視盒的遙控器壓一次按鍵似乎會傳出數組編碼,而且好像不是那麼固定,我壓了數次「1」鍵,結果產生如下編碼,個人無法理解這編碼的規則性:



相關連結

IR receiver 1838 Datasheet https://arduino-info.wikispaces.com/file/view/IR-Receiver-AX-1838HS.pdf
紅外線遙控器 http://pizgchen.blogspot.tw/2016/11/blog-post.html


採購資訊

紅外線遙控器套件 http://goods.ruten.com.tw/item/show?21628077374704



紅外線遙控器

市售紅外線遙控器有很多種,硬體上我們在此僅介紹「KEYES」這一款紅外線遙控器套件,至於其它款式的原理及操作,其實也跟「KEYES」大同小異。



紅外線遙控器套件清單:
1. 遙控器 * 1
2. 接收模塊 *1
3. 5mm發射 LED *1
4. 杜邦線母母頭 * 3P


電路接線

這裡要注意的是, 接收模塊的腳位上面只有標示「S」和「-」,沒有標示「VCC」。這裏「S」表信號腳位(黃色杜邦線),「-」表 GND 腳位(綠色杜邦線),而中間那支腳就是 VCC (橙色杜邦線),詳下圖:



Arduino    紅外線接收模塊
VCC         中間腳(橙色線)
GND        「-」(綠色線)
D3            「S」(黃色線)


程式碼

#include "IRremote.h"

/*-----( Declare Constants )-----*/
int receiver = 3; // pin 1 of IR receiver to Arduino digital pin 3

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);           // create instance of 'irrecv'
decode_results results;            // create instance of 'decode_results'
/*-----( Declare Variables )-----*/

void setup()
{
  Serial.begin(9600);
  Serial.println("YourDuino IR Receiver Button Decode Test");
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
//    Serial.println(results.value, HEX);  UN Comment to see raw values
    translateIR();
    irrecv.resume(); // receive the next value
  }
}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/
void translateIR() // takes action based on IR code received
// describing KEYES Remote IR codes
{
  switch(results.value)
  {
  case 0xFF629D: Serial.println(" FORWARD"); break;
  case 0xFF22DD: Serial.println(" LEFT");    break;
  case 0xFF02FD: Serial.println(" -OK-");    break;
  case 0xFFC23D: Serial.println(" RIGHT");   break;
  case 0xFFA857: Serial.println(" REVERSE"); break;
  case 0xFF6897: Serial.println(" 1");    break;
  case 0xFF9867: Serial.println(" 2");    break;
  case 0xFFB04F: Serial.println(" 3");    break;
  case 0xFF30CF: Serial.println(" 4");    break;
  case 0xFF18E7: Serial.println(" 5");    break;
  case 0xFF7A85: Serial.println(" 6");    break;
  case 0xFF10EF: Serial.println(" 7");    break;
  case 0xFF38C7: Serial.println(" 8");    break;
  case 0xFF5AA5: Serial.println(" 9");    break;
  case 0xFF42BD: Serial.println(" *");    break;
  case 0xFF4AB5: Serial.println(" 0");    break;
  case 0xFF52AD: Serial.println(" #");    break;
  case 0xFFFFFFFF: Serial.println(" REPEAT");break;
  default:
    Serial.println(" other button   ");
  }// End Case

  delay(500); // Do not get immediate repeat
}

UPLOAD 程式到 Arduino 後,請開啟 Serial Monitor 並隨意按下遙控器按鍵,您就可以看到 Arduino 已正確接收到紅外線信號,如下圖:


至於程式裏面的紅外線編碼是怎麼來的,您可以參考「相關連結」裏的「找出紅外線遙控器的編碼」這篇文。



進階題目

遙控器上面有 0~9 共 10 個數字鍵,那麼遙控器只能按出 0~9 這樣的數字給 Ardunio 嗎? 答案是否定的。

我們可以在程式上指定一個字串變數用來儲存使用者按下的數字(其實它是字元),使用者每按下一個數字按鍵,便將這個字元結合到該字串變數尾端,一直遇到「#」字(註A),才將整組字串變數傳回,如此相當於遙控器按出一組數字信號。

一組數字信號是由多個字元組成,在傳輸過程中難免發生錯誤,所以我們應該要檢查這組資料的正確性。藉由檢查資料長度以及資料內容,可以確立傳輸的資料是否正確。您可以仿效紅外線編碼格式,指定一個前導字符和結尾字符,然後把固定長度的資料夾在其中,例如

*27584#

「*」表前導字符
「#」表結尾字符
27584 表傳輸的資料,它的資料長度是 5 碼

另外,濾除多次重覆按鍵也是一個課題。

當我們可以正確用紅外線發出一串數字編碼之後,我們可以用它來做哪些應用呢? 建議您可以試著去做一個紅外線遙控器密碼鎖來玩玩。

註:
A. 使用其它按鍵也可以,例如「*」鍵。


後記

1. 紅外線接收器容易受環境光源干擾,因此應避免將紅外線遙控裝置使用於戶外。
2. 如果您使用這樣的遙控器在您家的客廳搖控自走車,您可能會發現電視節目自己胡亂跳台,很明顯地這樣的紅外線遙控會干擾電器設備,因此要審慎使用。自訂遙控器編碼,或許可以解決這樣的問題。


相關連結

IR receiver 1838 Datasheet https://arduino-info.wikispaces.com/file/view/IR-Receiver-AX-1838HS.pdf
找出紅外線遙控器的編碼 http://pizgchen.blogspot.tw/2016/11/blog-post_13.html


採購資訊

紅外線遙控器套件 http://goods.ruten.com.tw/item/show?21628077374704