2013/08/31

Raspberry Pi木質外殼Pibow Timber(開箱文)

我的Raspberry Pi板子很可憐,一直是裸機狀態,雖然我曾利用小磚塊與水泥打造一間非常笨重既不炫也不潮的外殼,但那只是搞笑用的吧,哈哈。

市面上的外殼,一般價位大約300元,一直沒下手,雖然也想用樂高積木拼湊一個外殼出來,但也不知道去哪兒買零散的積木,看著網路上許許多多有趣好看的外殼,終於下定決心砸錢買一個,原本打算買七彩繽紛的Pibow,但剛好發現新產品Pibow Timber,哇賽,木頭的耶。

這是包裝,雖然Pibow Timber是Pimoroni的產品,但我是向Adafruit買的


包裝的背面。


裡頭有兩片透明塑膠材質,大概是壓克力吧,作為外殼的上下外層,以及七片木頭,作為外殼的主體,另外有四個螺絲與螺帽,以及一個鎖螺絲用的木質扳手。


撕開透明塑膠片的白色保護膜。


組裝非常容易,每片木頭都有編號,按照順序疊上去即可,先疊兩片木頭,放入Raspberry Pi板子。


然後疊上其他片木頭與透明上蓋,插入螺絲。


翻過來在底部鎖上螺帽。


完成囉,這是底部。


每個連接埠都有留孔,這是耳機插孔與RCA端子。


電源插座,USB Micro B。


HDMI插座。


網路線插座與USB埠。


完成囉,還不錯看吧,可惜我拍的不好看。


還是看看專業級的照片吧,真漂亮啊。


非常不錯,每一個連接埠都有留孔洞,包括GPIO與相機模組,相當專業。

2013/08/27

讓Arduino Uno變成USB鍵盤

最早期的Arduino板子使用序列埠與電腦溝通,但現今一般電腦上已經找不到序列埠了(9針或25針),後來Arduino的板子採用FTDI公司的USB轉序列埠的晶片,讓電腦的USB埠化身變成虛擬序列埠;而Uno板改用Atmega8U2或Atmega16U2(R3),其實它就是一顆具有USB功能的微控制器,只不過在出廠時它預先燒錄具有「USB轉序列埠」功能的韌體,於是可作為電腦USB埠與Arduino板微控制器序列埠之間的中介橋樑。但我們可以讓8U2/16U2進入DFU(Device Firmware Update)模式,便可更新韌體,燒錄別的功能,譬如變成USB鍵盤,從Arduino板子傳送「按鍵」給電腦。

所謂DFU是USB規格的其中一項標準,讓USB裝置韌體更新的功能予以標準化,在Atmega8U2/Atmega16U2裡已含有DFU bootloader,我們從電腦將韌體傳給DFU bootloader,進行燒錄動作。

我的環境:電腦是Windows XP、開發板是Arduino Uno R3、Arduino軟體開發環境是1.0.5版。底下提到「韌體」時,若無特別註明,皆指8U2/16U2的韌體。

下圖紅圈處便是Uno R3的Atmega16U2,旁邊2x3針腳是它的ICSP接頭。


我們要做的事情有:

  • 下載並安裝電腦端的DFU燒錄軟體,Atmel Flip。
  • 讓Arduino Uno進入DFU模式,安裝它的DFU模式驅動程式。
  • 燒錄「不斷送出hello world按鍵」的草稿碼到板子的微控制器晶片裡。
  • 燒錄8U2/16U2的新韌體,變成USB鍵盤。
  • 在電腦上看到從Arduino Uno不斷傳來的「hello world」。
電腦端的DFU燒錄軟體,我們將使用Atmel提供的Flip這套軟體(需要Java),可到Atmel網站下載,有Windows版,安裝過程很簡單,一直按下一步即可,在此不贅述。Mac與Linux可使用dfu-programmer,此處不介紹。

然後請連接Arduino板電腦,可在裝置管理員裡找到代表板子的連接埠。下圖顯示出我的板子Arduino Uno R3。


要進入DFU模式,需重置8U2/16U2,作法是讓下圖的兩個腳位接觸一下(只需一下即可),其中一個是GND接地,另一個是RESET腳位,接觸一下即可重置。


若是R2以前的Uno板,必須在下圖這個位置焊接10K歐姆的電阻,我手上沒有這種板子,所以沒實際試過。


重置後,Windows XP電腦端就會發現硬體。


請選「從清單或特定位置安裝(進階)」。


然後選擇剛剛的Flip安裝目錄裡的usb子目錄,裡頭含有驅動程式。


接下來就稍等一下。


安裝成功囉。


然後在裝置管理員裡便可看到ATmega16U2。您的板子若不是Arduino Uno R3,將會看到別的晶片型號。


接下來,請到這裡下載,裡頭含有能讓Arduino板不斷送出「hello world」的草稿碼(helloworld/helloworld.pde),還有8U2/16U2的新韌體(Arduino-keyboard-0.3.hex),能讓Arduino Uno板變成USB鍵盤。

請拔除板子的電源與USB線進行重置,便可離開DFU模式回到一般的模式,然後燒錄(上傳)剛剛下載的helloworld/helloworld.pde。

接下來要燒錄新韌體,如前所述,讓8U2/16U2的RESET腳位接觸GND接地,一下即可,便可進入DFU模式,然後開啟Flip,出現如下畫面。


點按左上角看起來像是晶片的圖示,或是選「Device-Select...」,以我的例子而言,應選ATmega16U2。您應該選在裝置管理員裡所看到的晶片型號。


然後點按看起來像USB插頭的圖示,然後點按「USB」;或是選「Settings-Communication-USB」。


然後畫面便會從灰色變成彩色。


然後請選「File-Load HEX File...」,選擇剛剛下載的Arduino-keyboard-0.3.hex韌體,點按左下「Run」進行燒錄,然後點按右下的「Start Application」重置。

此時Arduino板便會是USB鍵盤,不斷地送出「hello world」,請隨便開啟一個文字編輯器,便會看到類似下圖的樣子。


若沒看到,可能板子並未重置成功,請手動拔掉板子的電源與USB線,再插入。

以上便上讓Arduino Uno變成USB鍵盤的過程,若你想讓板子回復到原來的樣子,只需重新燒錄原本的「USB轉序列埠」功能的韌體,位於Arduino目錄裡的hardware\arduino\firmwares\atmegaxxu2\arduino-usbserial\Arduino-usbserial-atmega16u2-Uno-Rev3.hex,這支是我Arduino Uno R3板的韌體,您應該找找適合你的板子的韌體,燒錄後即可還原,再以一般方式燒錄其他草稿碼即可。


參考資料:

2013/08/26

Arduino練習:四合一的七段顯示器

之前曾以四個七段顯示器製作時鐘,這篇則是介紹四合一的七段顯示器,目標是讓它從0000開始計數,然後每秒加1,0001、0002、0003、依此類推。

電路圖與原始碼可到GitHub下載,按「Download ZIP」即可全部下載,本篇程式碼位於子目錄SevenSegment4in1內。

底下是我買的共陰極、四合一型七段顯示器,每個七段顯示器含小數點。


底下是腳位圖,共有12個腳位,其中8個的功能就是控制七段顯示器,另4個腳位則代表想要控制哪一個七段顯示器,當腳位0為LOW、而腳位1、2、3為HIGH時,代表想要控制最右邊的七段顯示器,依此類推。


控制七段顯示器的8個腳位,a、b、c、d、e、f、g、h(dp),如下所示,本篇不使用h(dp)小數點。


因為有4個七段顯示器,我們必須使用掃描的方式不斷地顯示每一個七段顯示器,只要掃描速度夠快,基於視覺暫留原理,人眼便無法察覺,以為所有數字皆為同時顯示。

電路圖,沒什麼特別的,順著接即可,將在程式碼裡定義腳位的功能。

Arduino數位腳位2接到顯示器的0,
Arduino數位腳位3接到顯示器的g,
Arduino數位腳位4接到顯示器的c,
Arduino數位腳位5接到顯示器的h,
Arduino數位腳位6接到顯示器的d,
Arduino數位腳位7接到顯示器的e,
Arduino數位腳位8接到顯示器的b,
Arduino數位腳位9接到顯示器的1,
Arduino數位腳位10接到顯示器的2,
Arduino數位腳位11接到顯示器的f,
Arduino數位腳位12接到顯示器的a,
Arduino數位腳位13接到顯示器的3。

在下圖裡的四合一型七段顯示器擁有16個針腳,因為我找不到12個針腳的。




照理說,應該要串聯電阻220歐姆,不過我沒加也沒事orz。另外有些文章說Arduino輸出的電流不夠無法驅動,需加入NPN電晶體,不過我沒用也ok。

底下是程式碼:

// 定義腳位
#define PIN_0 2
#define PIN_g 3
#define PIN_c 4
#define PIN_h 5
#define PIN_d 6
#define PIN_e 7
#define PIN_b 8
#define PIN_1 9
#define PIN_2 10
#define PIN_f 11
#define PIN_a 12
#define PIN_3 13

// 共有4個七段顯示器,分別由針腳PIN_0、PIN_1、PIN_2、PIN_3控制
// 七段顯示器裡有8個LED(包含小數點)
#define POS_NUM 4
#define SEG_NUM 8
const byte pos_pins[POS_NUM] = {PIN_0, PIN_1, PIN_2, PIN_3};
const byte seg_pins[SEG_NUM] = {PIN_a, PIN_b, PIN_c, PIN_d, PIN_e, PIN_f, PIN_g, PIN_h};

// 底下定義由七段顯示器顯示數字時所需要的資料
#define t true
#define f false
const boolean data[10][SEG_NUM] = {
  {t, t, t, t, t, t, f, f}, // 0
  {f, t, t, f, f, f, f, f}, // 1
  {t, t, f, t, t, f, t, f}, // 2
  {t, t, t, t, f, f, t, f}, // 3
  {f, t, t, f, f, t, t, f}, // 4
  {t, f, t, t, f, t, t, f}, // 5
  {t, f, t, t, t, t, t, f}, // 6
  {t, t, t, f, f, f, f, f}, // 7
  {t, t, t, t, t, t, t, f}, // 8
  {t, t, t, t, f, t, t, f}, // 9
};

// 一支方便的函式,以格式字串輸出到序列埠
void pf(const char *fmt, ... ){
    char tmp[128]; // max is 128 chars
    va_list args;
    va_start (args, fmt );
    vsnprintf(tmp, 128, fmt, args);
    va_end (args);
    Serial.print(tmp);
}

// 設定某個七段顯示器所顯示的數字,
// 參數pos為0~3,指出想要更新哪一個七段顯示器,
// 參數n為0~9,顯示數字
void setDigit(int pos, int n){
  if(pos < 0 || 3 < pos){
    pf("error pos=%d\n", pos);
    return;
  }

  // 控制想要更新哪一個七段顯示器,將其腳位設為LOW
  // 其他腳位則設為HIGH,代表不更新。
  for(int p = 0; p < POS_NUM; p++){
    if(p == pos)
      digitalWrite(pos_pins[p], LOW);
    else
      digitalWrite(pos_pins[p], HIGH);
  }
  
  // 寫入數字
  if(0 <= n && n <= 9){
    for(int i = 0; i < SEG_NUM; i++){
      digitalWrite(seg_pins[i], data[n][i] == t ? HIGH : LOW);
    }
  }
  else{
    for(int i = 0; i < SEG_NUM; i++){
      digitalWrite(seg_pins[i], LOW);
    }
    digitalWrite(PIN_h, HIGH);
    pf("error pos=%d, n=%d\n", pos, n);
  }
}

// 設定整個四合一型七段顯示器想要顯示的數字
// 參數number的範圍應是0~9999
void setNumber(int number)
{
  int n0, n1, n2, n3;
  n3 = number / 1000;
  number %= 1000;
  n2 = number / 100;
  number %= 100;
  n1 = number / 10;
  n0 = number % 10;

  // 求出每個位數的值後,分別更新
  // 注意,此處以delay(5)隔開每個位數的更新
  setDigit(0, n0); delay(5);
  setDigit(1, n1); delay(5);
  setDigit(2, n2); delay(5);
  setDigit(3, n3); delay(5);
}

unsigned long time_previous;
void setup() {
  Serial.begin(115200);
 
  for(int i = 0; i < POS_NUM; i++){
    pinMode(pos_pins[i], OUTPUT);
    digitalWrite(pos_pins[i], HIGH);
  }
  for(int i = 0; i < SEG_NUM; i++){
    pinMode(seg_pins[i], OUTPUT);
    digitalWrite(seg_pins[i], LOW);
  }
 
  time_previous = millis();
}

int number = 0;
void loop() {
  // 經過一秒後就讓number加1
  unsigned long time_now = millis();
  if(time_now - time_previous > 1000){
    number++;
    time_previous += 1000;
    pf("number=%d\n", number);
  }

  // 不斷地寫入數字
  setNumber(number);
}

成功的話,一開始會顯示0000,然後是0001、0002、0003、等等。

可修改的地方:

  • 可使用4511減少腳位數量,但4511只能搭配共陰極七段顯示器。
  • 處理大於9999的情況。 
  • 修改setNumber函式裡delay(5)的延遲值,改成10或50,試試看有何效果。
參考資料:

Raspberry Pi情報彙整(3)

我將網路上看到的、感興趣的、跟Raspberry Pi相關的資訊收集如下。

將玩具熊送上高空Ted Bull Stratos: Babbage's leap of faith,並且照相,哇,不僅飛到距地表約40公里的高空,還可以在地面隨時監控啊,真厲害,最讓我驚訝的是,最後居然能夠回收,嘿嘿,更多照片請到這裡


氣象與污染觀測站AirPi,兩位年輕人打造出這套歐元55的觀測系統,功能卻可與現有的產品相提並論,相當厲害,可記錄氣溫、濕度、紫外線、等等資料,並且上傳到網路上,即時觀察。目前正募集資金中。


花園栽培控制系統HyGrowBot,此控制模組可以操控感測器、相機、幫浦、調節閥門,灑水、燈光、施肥,通通可按照你的需求逐一建構。


卡拉OK歡唱系統Karaoke,唱破你的喉嚨吧。


樂器專案Nintendo audio - on analogue instruments,操控鋼琴與鼓,演奏出瑪莉歐與薩爾達的音樂。


數位家庭自動化系統RaZberry,以Raspberry Pi為中心,加上一塊小小的附加硬體板穿上Z-Wave無線傳輸功能,然後便有各種軟體開發介面可用,控制家裡的電子裝置。


讓Arduino或Raspberry Pi連接2G/3G電信網路的擴充板SparqEE CELLv1.0,在全世界各地暢行無阻,群眾募資中。


關於Raspberry Pi板子的電源開關Add a power switch to your Raspberry Pi!,各種形式的產品,形形色色,滿足你的需求。


2013/08/25

Arduino IDE 1.5字串翻譯工作需要您的幫忙

之前我曾將Arduino IDE 1.0.1的字串翻譯成正體中文,現在1.5版的翻譯工作正在進行中,您也可以出一份力喔。

請到翻譯工作的管理網站,我已經初步將所有字串都翻譯成正體中文,但我手上沒有DUE板子,所以許多字串在不了解原意的狀況下,可能無法翻的很貼切,您可以註冊帳號(免費),然後便能編輯修改並審閱字串。

小小抱怨一下,其實1.5版裡很多字串也都是取自先前的版本,那麼為什麼Arduino官方團隊不先沿用呢?

2013/08/21

Raspberry Pi的硬體亂數產生器

還記得在C語言標準程式庫裡的int rand()與srand(unsigned int seed),可產生虛擬亂數(pseudorandom number,或稱假亂數),為了每次都能得到不同的序列,通常需先srand(time(NULL))然後再呼叫rand()得到亂數,但畢竟只是假亂數了,不是真真正正的亂數,真亂數必須以類比元件的熱雜訊(thermal noise)作為熵源(entrypy source),

Raspberry Pi的主晶片裡頭其實擁有硬體亂數產生器(hardware random number generator),而新版的韌體加入了此功能,請以底下指令更新韌體(最好先備份記憶卡),

$ sudo rpi-update
(我使用2013-07-26-wheezy-raspbian.zip,便不需要作此動作。)

然後載入硬體亂數的模組,

$ sudo modprobe bcm2708-rng

便可從/dev/hwrng取得亂數。

若想要讓系統自動載入該模組,請修改/etc/modules,加入底下這行:

bcm2708-rng

另外,可安裝rng-tools這個套件,

$ sudo apt-get install rng-tools

它裡頭也包含了rngd這個亂數服務,安裝後便會自動啟動,

Starting Hardware RNG entropy gatherer daemon: rngd.

rngd會利用熵源(/dev/hwrng)將亂數放進/dev/random與/dev/urandom。

以底下指令可進行測試(根據FIPS 140-2標準)是否為真亂數,

$ sudo cat /dev/hwrng | rngtest -c 1000
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 20000032
rngtest: FIPS 140-2 successes: 999
rngtest: FIPS 140-2 failures: 1
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 1
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=75.254; avg=1068.674; max=1953125.000)Kibits/s
rngtest: FIPS tests speed: (min=843.573; avg=4171.791; max=8247.994)Kibits/s
rngtest: Program run time: 23315840 microseconds

但因為資料的亂數特性,有可能得到少量的failures。

嗯,有了真亂數,可以幹些什麼呢?


參考資料:

2013/08/20

Raspberry Pi情報彙整(2)

當紅炸子機Raspberry Pi火紅到不行,又有哪些有趣值得關注的消息呢,請看。

影片EEVblog #507 - The First ARM Computer - Acorn Archimedes A3000 - YouTube,現今智慧型手機大都是ARM架構,Raspberry Pi也是ARM架構,但你知道第一台以ARM架構打造出來的家用電腦是哪一台嗎?讓EEVblog Crazy Dave將它大卸八塊,好好檢視一番。哇,裡頭有RISC OS的ROM耶。


站立外殼Very Berry Pi-Case 3000,呵呵,居然以raspberry水果為造型,真有趣啊。嗯,把各個連接埠引到底座。


外殼PiCE,可容納Raspberry Pi板子與相機模組,以鋅合金與聚碳酸酯製造,相當耐撞,每一個連接埠,包括GPIO,都詳加考慮。正在群眾募集資金中,9月1日分曉。既然加入相機模組,看起來應該主打戶外使用的情境。


錄音帶外殼,Cassette is not dead inspired Raspberry Pi case,我也想做一個,不過家裡已經找不到錄音帶了吧。


Raspberry Pi小改造:連接Moto Atrix Lapdock變形成Linux小筆電,自己動手做,樂趣無窮,這個底座有螢幕、鍵盤、觸控板、電池、USB埠。不過,我感興趣的還是那個可愛的外殼與裝飾品。


七彩繽紛PiGlow,簡簡單單的LED,閃爍發亮,看起來真炫啊。太漂亮了,教你如何不愛上PiGlow。


創意專案Wearable Pi With 3D Printing,3D成型+可穿戴式電子+Pi,充滿濃濃的steampunk科幻題材風。嘿嘿,真有人敢穿出去嗎?


彈珠台專案The Making of Fireball HD Pinball,我對彈珠台沒什麼感情。


教育相關Learning Python using Codecademy and Raspberry Pi Minecraft: a resource of great note,Raspberry Pi+Minecraft+Python,絕妙的學習環境。


運算叢集Whitepaper: Creating a Raspberry Pi-Based Beowulf Cluster,未來(其實已經開始了)的趨勢是平行運算,那麼該如何學習呢,看看這篇把一堆Pi集合起來,透過網路連線,再加上某種平行處理軟體,讓每一台Pi可以互相溝通並存取資料。


從你的iPhone控制Pi拍照BerryCam,嘿嘿,可以想想如何運用。