作品展示
作品製作步驟
作者曹 永忠@makerdiwo
文曹永忠、許智誠、蔡英德
編王昱夫
智慧型穿戴裝置正夯,那有沒有辦法自己做一隻呢?其實只要利用Arduino,即使沒有很高超的電子機械背景,也可以自己動手做出一個穿戴式裝置喔!這裡筆者要和大家分享的,是在參加「第四屆黑客松(Hackathon Taiwan 4th)」時,與夥伴合力想出的Mr. Bu 互動式手環。
黑客松(Hackathon)是黑客(Hack)與 馬拉松(Marathon)的複合字用來表示一個「馬拉松式的科技創作活動」,這樣的活動作為結交各界英雄好漢的媒合地,非常適合 Maker 參加,大夥可以為了一個理念,一起挑燈夜戰、去光華商場找材料、一起討論,宛如回到大學時代,和同學們同組奮鬥,努力求Pass的那種感覺,在黑客松的日子裡,總是讓大家有時光倒流,重溫舊夢的感覺!
近年來 Arduino 異軍突起,在許多 Maker 專案中,大部份的人都以 Arduino 為控制裝置,整合許多感測器、馬達、機構、手機、平板⋯⋯等,開發出許多創意的互動產品與數位藝術創作。Arduino 強調的不是純技術,而是縮短了創意發想到原型實作的距離,降低了創作者空想的疑惑與恐懼!這樣的情景,讓那些使用高階 Arm 等強大處理器的原創者跌破眼鏡,小兵也可立大功,正證明了 NOKIA 那句「科技始終來自於人性」的初衷,創意發想者不需要高超的技術,也不用害怕那些晶片技術、複雜再複雜的開發軟體,因為等到熟悉、駕御這些科技高峰之後,恐怕人也將被科技化、工程化奴役的不成人形,連原有的創意也會被嚴謹的工程訓練所僵化,再也想不出天馬行空、天外一筆的巧思作品了。
這個主題:穿戴式設備-Mr. Bu 手環,是筆者參加「第四屆黑客松(Hackathon Taiwan 4th)」時,和夥伴合力想出的!運用簡單的 Led 點陣顯式器,整合 MPU-6050模組(三軸陀螺儀 + 三軸加速度)來設計與製作出一個穿戴式手環,讓穿戴者可以透過互動改變顯示內容,算是身為一個 Maker 創意呈現的簡單創意。
實作布手環
對於 Arduino 軟體安裝部份、程式基本語法與函式庫使用與安裝等問題,若讀 者仍有不詳盡之處,使用者可以參考本書「Arduino 程式教學(入門篇):Arduino Programming (Basic Skills & Tricks)」(曹永忠, 許智誠, & 蔡英德, 2015a)、「Arduino 程式教學(常用模組篇):Arduino Programming (37 Sensor Modules)」(曹永忠, 許智誠, & 蔡英德, 2015b)。此外對於 Led 點陣顯式器,整合了 MPU-6050 模組(三軸陀螺儀 + 三軸加速度))等問題,若讀者仍有不詳盡之處,使用者可以參考本書「Arduino 手 搖字幕機開發:The Development of a Magic-led-display based on Persistence of Vision」 (曹永忠, 許智誠, & 蔡英德, 2014a)、「Arduino 光立體魔術方塊開發:The Develop- ment of a 4 * 4 Led Cube based on Persistence of Vision」(曹永忠, 許智誠, & 蔡英德, 2014b)、「Arduino 實作布手環:Using Arduino to Implementation a Mr. Bu Bracelet」(曹永忠, 許智誠, & 蔡英德, 2015c),相信會了解更多。
手環設計
因為在黑客松的場地不如實驗室一樣有許多的設備與器材,所以我們選擇用厚紙板做為手環結構主體,考慮手臂與手關節的活動,我們將手環設計成兩段,手環上段放置 Arduino UNO 開發板、行動電源等設備,手環下段放置四組「Max7219 Led 顯示模組」,圍成環型,如同手鍊一般(圖 1),可以直接套入手臂與手腕之中。
加入動作感測器
為了可以增加手環動作的互動趣樂性,我們加入了音效的效果,同時為了不複雜化,我們只單純使用最簡單的 tone()函數來增加音效。使用 tone()函數時,我們也在裝置上額外加入一個揚聲器(Speaker),如圖 3 所示,我們將超迷你「揚聲器(Speaker)」加入手環的 Arduino UNO 開發板單晶片上。
加入人機互動效果
除了音效,我們還希望這個手環能夠具備人機互動的功能:讓使用者在穿戴「布手環」時,除了揮舞手改變顯示內容速度之外,還可以同時改變顯示內容。
但是慣性感測器:MPU-6050 的感應速度太快,導致無法有效改變文字內容,我們解決的方法是加入一個按鈕模組藏在布手環下方。如圖 4 所示,我們將「按鈕模組」加入布手環之內,由於照相困難,我們先將按鈕模組,置於外部讓讀者了解。
使用外部插斷達成即時人機互動
使用者在穿戴「布手環」時,除了揮舞手改變顯示內容速度之外,還可以改變顯示內容;但是我們發現,因為檢查按鈕的程式寫在 loop()程式區塊之中,由於整個 Arduino 開發板與微處理機都在處理顯示、音效等眾多的程序,導致「改變文字內容」的效率變得不是很好。
為了能夠有效改變文字內容,我們讓按鈕模組使用硬體插斷:將按鈕模組的訊號接在 Arduino 開發板 0 號插斷(對於「插斷使用」尚不了解的朋友,可以參考「Arduino 實作布手環:Using Arduino to Implementation a Mr. Bu Bracelet」(曹永忠 et al., 2015c)內的外部硬體插斷內容)。
以下提供這款「布手環」的電路接腳列表,只要參照表上的說明,即可完成所有硬體的電子電路配置:
建立好硬體後,只要將下面的手環測試程式鍵入 Arduino Sketch ,完成編譯後,上載到 Arduino 開發板進行測試,如圖 5 所示,就可以看見在揮動布手環之際,使用者還可以按下按紐來改變顯示文字內容。
實作布手環測試程式(Bu21) |
#include <LedControl.h>#include “pitches.h"#include “I2Cdev.h"#include “MPU6050.h"#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE#include “Wire.h"
#endif MPU6050 accelgyro; //MPU6050 accelgyro(0x69); // <– use for AD0 high int16_t ax, ay, az; int16_t gx, gy, gz; #define OUTPUT_READABLE_ACCELGYRO #define DinPin 8 #define CsPin 9 #define ClkPin 10 #define chipno 4 #define chips 4 #define melodyPin 7 #define comtrolBtn 6 //LedControl lc=LedControl(12,10,11,9); LedControl lc=LedControl(DinPin,ClkPin,CsPin,chipno ); /* we always wait a bit between updates of the display */ unsigned long delaytime=1000; String showword[5] = {“Hackathon","BruceTsao","Samantha","Jack","Hardy"} ; int melody[] = { NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0, 0, NOTE_G6, 0, 0, 0, NOTE_C7, 0, 0, NOTE_G6, 0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0,NOTE_C7, NOTE_D7, NOTE_B6, 0, 0, NOTE_C7, 0, 0, NOTE_G6, 0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0,NOTE_C7, NOTE_D7, NOTE_B6, 0, 0 }; //Mario main them tempo int tempo[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, }; // music for mario int mariolen= 0 ; int mariopos = 0 ; int showwordno = 0 ; void setup() { mariolen = sizeof(melody) / sizeof(int) ; mariopos = 0 ; attachInterrupt(0, BtnPressed, RISING); #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif accelgyro.initialize(); Serial.begin(9600) ; Serial.println(“Mr. BU Start Here"); Serial.println(accelgyro.testConnection() ? “MPU6050 connection successful" : “MPU6050 connection failed"); for(int i=0;i<4;i++) { lc.shutdown(i,false); /* Set the brightness to a medium values */ lc.setIntensity(i,8); /* and clear the display */ lc.clearDisplay(i); } // lc.setStringFont5X7(0,0,"Mr._BU_Start_Here",6); lc.setStringFont5X7(0,0,showword[showwordno],6); //FontWidth=6 lc.LeftRotate(10); } void loop() { int px,py,pz ; accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //LShift();// writeArduinoOnMatrix(); MPU6050_Get_Angle(ax,ay,az,&px,&py,&pz) ; Serial.print(“****" ) ; Serial.print(px) ; Serial.print(“t") ; Serial.print(py) ; Serial.print(“t") ; Serial.print(pz) ; Serial.print(“t") ; Serial.print(“n") ; lc.LeftRotate(map(px, -90, 90, 1, 8)); MarioPlaying() ; delay(50); } void MPU6050_Get_Angle(float x,float y,float z,int *rx, int *ry, int *rz) { *rz=(int)(atan(sqrt((x*x+y*y))/z) * 180/3.14); *rx=(int)(atan(x/sqrt((y*y+z*z))) * 180/3.14); *ry=(int)(atan(y/sqrt((x*x+z*z))) * 180/3.14); // return res*1800/3.14;//把弧度转换成角度 } void MarioPlaying() { int noteDuration = 1000/tempo[mariopos]; tone(melodyPin, melody[mariopos],noteDuration); //buzz(melodyPin, melody[mariopos],noteDuration); if (mariopos >= mariolen) { mariopos = 0 ; } mariopos ++ ; } void BtnPressed() { showwordno ++ ; if (showwordno >=5) { showwordno= 0 ; } lc.setStringFont5X7(0,0,showword[showwordno],6); //FontWidth=6 Serial.print(“Change Display:(“) ; Serial.print(showwordno) ; Serial.print(“)n") ; } |
手環測試程式五(pitches.h) |
/********* Public Constants********* /#define NOTE_B0 31#define NOTE_C1 33#define NOTE_CS1 35#define NOTE_D1 37#define NOTE_DS1 39
#define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978
|
大家也可以在作者的YouTube頻道中,或直接至影片連結中,看到本文的實作影片!
筆者在Arduino相關領域,也出版過許多書籍,往後希望透過本專欄,能將自己更多的想法、創意,實作等和讀者分享,相信大家能更在Maker自造者運動中,創造出更多有趣、創新與創意的萌物,作者會更衷心地希望永遠在這條Maker路上與大家同行。

創點活動!「創與匠」-鋼鐵人沒告訴你的自造義肢故事,職能治療與創客精神:更詳細的資訊和報名