這次將為大家介紹一個使用Arduino制作的獨特電子作品,將會分【前篇】和【后篇】兩部分進行介紹。為我們介紹這個非常有趣的電子制作項目的是平原真先生,他是一位以事物之間的關系為主題進行探索的藝術家。平原先生同時也是大阪藝術大學的副教授,迄今為止,他使用計算機和電子器件制作了很多媒體藝術作品。在Device Plus上,平原先生也發表了一些極具意義的電子作品,例如“用Arduino制作的太陽能電池板供電數字生態箱”和“用Arduino和TOF距離傳感器制作甜甜圈播放器”。下面,讓我們來看看這次會是什么樣作品。
前言
大家好!我叫平原。這個問題可能有點突然:您有沒有玩過巨大的迷宮?這通常是一種景點,玩家進入一個由比人高的墻壁組成的迷宮,通過克服旋轉門和岔路等重重關卡,最后到達終點。這種游戲在1980年代風靡日本全國,但現在貌似只剩下屈指可數的幾處了。我在小時候曾經玩過,當時曾經想:“要是能從天上往下看就好了!”
這次我想制作一個能夠實現這樣的童年夢想的作品。希望制作出一個當實物迷宮傾斜時,屏幕中的迷宮也會傾斜并且小球會滾動的裝置,玩家需要交互確認和比較實物迷宮和屏幕中的迷宮才能到達終點!
本項目的組成
本項目共分為六個部分:
作品規劃和制作準備
電子電路
Arduino程序
制作迷宮外殼
創建迷宮的3D模型
Unity程序
本文是前篇,將介紹1到3的內容,最后我們會測試電子電路的工作情況。在后篇中,我們將使用激光加工機制作迷宮外殼,并使用Unity完成3D迷宮游戲。
1. 作品規劃和制作準備
整體規劃
在這項作品中,如果您傾斜實物迷宮,屏幕中的迷宮也會傾斜,里面的小球也會隨之滾動。這個項目的亮點在于,通過實物迷宮可以看到整個迷宮,但無法知道小球的位置,在屏幕上只能看到小球周圍的區域,所以必須交互確認實物迷宮和屏幕中的迷宮。
盒子里面是包括用來檢測傾斜的加速度傳感器和微控制器開發板Arduino UNO,通過USB數據線連接到電腦。當您傾斜盒子時,傾斜數據會被發送到名為“Unity”的軟件,該軟件用來在電腦上顯示運行的3D迷宮。Unity根據接收到的數據傾斜3D迷宮,小球會根據物理運算滾動。
另外,我還希望實現更換實物迷宮后3D迷宮也隨之切換這一目標,這樣可以使游戲更加富有妙趣。此外,當玩家成功到達終點時,還還需要通過振動來表示一下喜悅之情。
系統構成
下面,我們繪制一個實現整體規劃所需設備的簡圖,并構思整體的設備構成。
首先,需要用加速度傳感器來讀取傾斜度。然后,還需要用來讀取迷宮切換情況的反射式光電傳感器和用來產生振動的振動電機。另外,還需要通過微控制器開發板Arduino來控制這些電子器件并與電腦進行通信。用USB數據線連接Arduino和電腦,在電腦上運行Unity,并與Arduino通信和顯示迷宮。
接下來,需要根據電壓、耗電量、所使用的引腳、通信方式、實物尺寸、作品的炫酷程度等因素,來選擇具體部件。如果您從主要部件和選項較少的部件開始著手,會更容易理清思路。
加速度傳感器
加速度傳感器包括將加速度輸出為電壓的模擬類型,以及通過I2C等進行通信的數字類型。最近,數字型加速度傳感器已成為主流。這次,我們將使用ROHM的加速度傳感器模塊“KX224-1053”和可以通過Arduino輕松使用的傳感器擴展板“SHIELD-EVK-001”。
羅姆傳感器評估套件
反射式光電傳感器
反射式光電傳感器是一種照射紅外線并讀取對象物反射光線的裝置。在這里,我們利用光反射量會因對象物的顏色而變化這一特點,來讀取迷宮的類型。如果有兩個反射式光電傳感器,那么就可以分辨出四種迷宮。這次我們將使用常用的“RPR-220”。
振動電機
振動電機是一種通過使偏心塊旋轉而產生振動的裝置,也稱為“偏心電機”。這次為了簡化電路,我們將使用工作電壓在2.0v ?3.0v,工作電流在大約50mA、可直接通過Arduino控制的振動電機。
Serial Port Utility Pro
Unity與Arduino之間的通信僅通過標準功能也能實現,但這次我們將使用名為“Serial Port Utility Pro (SPUP)” 的工具。使用SPUP進行通信時,您可以不必擔心運行環境的差異。這個工具在資源商店的售價為79美元,不過您可以從其官網下載試用版。試用版需要在通信量達到一定程度時重新啟動Unity。我們可以在開發過程中使用試用版,在想長期使用時購買它。
迷宮外殼結構
根據整體規劃和所需功能來考慮外殼的結構。比較有效率的做法是先手繪草圖,等大框架定好后再用CAD等進行設計。這次是一個簡單的盒子,所以我是用Illustrator設計的。
這次要考慮的要點是:適合用雙手拿著的尺寸、可以更換迷宮、可以用反射式光電傳感器讀取迷宮的背面。我決定設計成盒狀,將電路收納在盒子中,將迷宮配置在盒蓋上。在盒蓋的背面做黑色和白色標記,用反射式光電傳感器來讀取標記。
材質采用椴木單板,用激光加工機切割,用木材專用膠粘合。如果想要看得見內部,也可以使用透明的亞克力板。請根據自己的喜好選擇。
零部件清單
我在下面匯總了要使用的物料,價格和購買網址為截至撰寫本文時的數據。運費另計。
產品名稱 | 購買鏈接 | 數量 | 參考價格(日元) |
Arduino UNO | http://akizukidenshi.com/catalog/g/gM-07385/ | 1 | ¥2,940 |
USB數據線A-B | http://akizukidenshi.com/catalog/g/gC-07605/ | 1 | ¥130 |
傳感器擴展板(SHIELD-EVK-001) | https://www.rohm.co.jp/distribution/-/dinventory/SHIELD-EVK-001/sample/0 | 1 | ¥5,523 |
加速度傳感器模塊(KX224-1053) | https://www.rohm.co.jp/sensor-shield-support/accelerometer | 1 | ¥2,740 |
面包板 | http://akizukidenshi.com/catalog/g/gP-00315/ | 1 | ¥270 |
振動電機 | http://akizukidenshi.com/catalog/g/gP-15315/ | 1 | ¥110 |
電阻器(39Ω) | http://akizukidenshi.com/catalog/g/gR-14274/ | 1 | ¥100 |
反射式光電傳感器(RPR-220) | http://akizukidenshi.com/catalog/g/gI-11401/ | 2 | ¥100 |
電阻器(150Ω) | http://akizukidenshi.com/catalog/g/gR-25151/ | 2 | ¥100 |
電阻器(10kΩ) | http://akizukidenshi.com/catalog/g/gR-25103/ | 2 | ¥100 |
跳線(公對公) | http://akizukidenshi.com/catalog/g/gC-05371/ | 適宜 | ¥180 |
椴木單板(450m x 300m x 4m) | https://shop.woodworks-marutoku.com/products/shinafree/item/shina002.php | 2 | ¥360 |
Serial Port Utility Pro(串口通信庫) | https://assetstore.unity.com/packages/tools/utilities/serial-port-utility-pro-125863?locale=ja-JP | 1 | $79 |
分發文件
創建示例所需的數據請從以下鏈接下載。其中包括Arduino程序和用于切割椴木單板的形狀數據等。
>> 數據下載(50.4MB)
CutBox.ai
外殼盒體部分的激光加工用數據
CutMaze.ai
外殼迷宮部分的激光加工用數據
ArduinoApp
Arduino用程序
UnityApp
Unity的項目
BreadboadHolder.stl
用來提高面包板高度的部件
MazeLv1.obj、MazeLv2.obj、MazeLv3-A.obj、MazeLv3-B.obj
迷宮的3D模型
2. 電子電路
布線圖與電路圖
我們需要一邊確認電子部件的技術規格書一邊設計電路。同時,在考慮實際物體的大小和位置關系的同時,還要考慮布線的長度等因素。
加速度傳感器模塊可以安裝在傳感器擴展板上并固定在Arduino UNO上面,因此布線很簡單:將反射式光電傳感器和振動電機配置在面包板上。
布線圖
電路圖是表示電氣連接關系的圖,布線圖是考慮到表示實際尺寸和位置關系等因素而繪制的接線圖。在您還不能熟練使用的階段,完全按照布線圖制作更容易一些,但是當您習慣于制作并能夠自己繪制電路或嵌入他人的電路時,通過電路圖進行思考更容易理解。
電路圖
組裝
下面我們組裝電子電路。這次我沒有采用焊接的方式,而是用跳線將其連接到面包板上,因此無需擔心失敗。在作業的時候,請對照布線圖和照片進行。作業步驟如下:
加速度傳感器模塊和傳感器擴展板
反射式光電傳感器
振動電機
布線
步驟1:加速度傳感器模塊和傳感器擴展板
傳感器擴展板自帶的插座可以安裝共8個傳感器模塊。加速度傳感器模塊適用“I2C”的通信標準,因此請將其插入標有“I2C_1”的插座。請調整角度,使模塊處于水平狀態。
接下來,將傳感器擴展板連接到Arduino UNO。請確保所有引腳都牢牢地插入內部,以便使加速度傳感器模塊處于水平狀態。另外,請垂直施加力量,以防止長引腳彎曲。雖然后續也可以拔除,但由于長引腳容易彎曲,所以還請謹慎處理。
步驟2:反射式光電傳感器
反射式光電傳感器有4根引腳。由于4根引腳的長度不同,所以請按照最短的引腳切齊。用鉗子切斷時,切除掉的余腳的可能會飛濺,請注意防護。
將電阻器從根部彎曲成直角,并在距離根部約1厘米處切割。
接下來,請參考布線圖將其插入面包板。注意反射式光電傳感器按45度切割時的角度位置。如果切角在右上方,則反射式光電傳感器的左半部分是紅外LED,右半部分是光電晶體管。紅外LED側(左側)的電阻為 150Ω,光電晶體管側(右側)的電阻為10kΩ。由于電阻器沒有極性,因此它的朝向無所謂。跳線如果使用硬跳線,布局效果會給人清爽的感覺。跳線的顏色可以是任意顏色,但為了使布線圖清晰易懂,通常電源(5V)用紅色,地線(GND)用黑色。
步驟3:振動電機
將振動電機的引出線皮膜剝去約1厘米,然后將其插入面包板。如果導線很細而且難以插入,請將電阻引腳切掉的部分焊接到引出線上。用兩面膠將振動電機牢固地固定在面包板上。這個振動電機的標準電壓是3V,標準電流是55mA,電源是來自Arduino的5V電源,所以按照(5v-3v)/0.055A=36.4Ω,使用的電阻是39Ω。
步驟4:布線
用跳線連接配置在Arduino UNO上的傳感器擴展板與面包板。如果在您將其放入盒子里時跳線造成干涉,將端部的引腳彎曲90度就可以整齊地收納在盒子里面了。
3. Arduino程序
現在讓我們看一下Arduino程序。這次的項目需要以下四個功能:
從加速度傳感器模塊讀取值
讀取反射式光電傳感器的值
通過串行通信發送讀取到的傳感器值
接收和處理來自Unity的命令
在對每一個功能進行解說后,將會給出整個程序。
從加速度傳感器模塊讀取值
為了與加速度傳感器模塊“KX224-1053”進行通信,需要使用專用的庫。首先,請從產品介紹頁面的軟件部分下載ZIP文件。然后,從Arduino IDE菜單中選擇 [Sketch] > [Include Library] > [Add .ZIP Library],并選擇下載的ZIP文件。
另外,您也可以從這個頁面下載產品手冊供參考。
>>加速度傳感器模塊產品介紹
在Arduino程序中,首先加載I2C庫和加速度傳感器模塊的庫。
然后創建KX224類的對象(Object)。可以從該對象讀取加速度傳感器的值。
#include //I2C庫 #include //加速度傳感器庫 KX224 kx224(KX224_DEVICE_ADDRESS_1E);//創建加速度傳感器的對象
在setup函數中,啟動I2C庫并初始化KX224對象,如果失敗,則通過串行通信發送消息。。
byte rc;//啟動檢查變量 Wire.begin();//I2C庫啟動 rc = kx224.init();//加速度傳感器對象的初始化 if (rc != 0) {//加速度傳感器對象的啟動檢測 Serial.println(F("KX224 initialization failed")); Serial.flush(); }
當將float數組傳遞給KX224對象的get_val函數時,傳感器的值將會輸入。如果返回值為0,則讀取成功。
byte rc;//用于確認傳感器讀數。 float acc[3];// rc = kx224.get_val(acc);//將加速度代入acc,如果可以讀取則返回 0。
讀取反射式光電傳感器的值
將反射式光電傳感器連接到引腳A0和A1并通過analogRead函數讀取。盒子背面的標記是白色和黑色的,通過Unity軟件更改模擬讀取閾值。
int photoRef1 = analogRead(A0);//讀取反射式光電傳感器 int photoRef2 = analogRead(A1);
通過串行通信發送讀取到的傳感器值
將加速度傳感器的三個值和兩個反射式光電傳感器的值用逗號分隔并作為字符串發送。最后,發送換行代碼。Unity將接收到的字符串以逗號分隔并返回到數組中使用。
Serial.print(acc[0]);//X軸 Serial.print(","); Serial.print(acc[1]);//Y軸 Serial.print(","); Serial.print(acc[2]);//Z軸 Serial.print(","); Serial.print(photoRef1);//反射式光電傳感器1 Serial.print(","); Serial.print(photoRef2);//反射式光電傳感器2 Serial.println("");
接收和處理來自Unity的命令
當來自Unity的命令發送過來時,將執行串行通信接收事件。連接接收到的字符串,當收到換行代碼時,將接收完成標志設置為True。
void serialEvent() {//接收到串行通信的事件 while (Serial.available()) { char inChar = (char)Serial.read(); // 將接收到的數據轉換為字符串 inputString += inChar; // 添加到inputString if (inChar == 'n') {// 當接收到換行代碼時,設置接收完成標志。 stringComplete = true; } } }
檢查loop函數中的接收完成標志,如果為True,則檢查命令的內容并進行相應的處理。在這次的項目中,當字符串是“start”時,振動電機旋轉,當字符串是“stop”時,則電機停止。
if (stringComplete) {//設置了接收完成標志時的處理 String is = inputString;//復制接收到的字符串 is.trim();//刪除換行代碼 if ( is.equals("start") ) //當收到start 時 { digitalWrite(2, HIGH);//使電機運轉 } if ( is.equals("stop") ) //當接收到stop時 { digitalWrite(2, LOW);//使電機停止 } inputString = "";//清除接收到的字符串 stringComplete = false;//清除接收到的標志 }
整體草圖
請在Arduino IDE中輸入以下源代碼并將其寫入Arduino UNO
#include ///I2C庫 #include //加速度傳感器庫 KX224 kx224(KX224_DEVICE_ADDRESS_1E);//創建加速度傳感器的對象 String inputString = "";//保存接收數據的變量 bool stringComplete = false; //判斷接收是否完成的標志 void setup() { byte rc; Serial.begin(57600);//串行通信開始 while (!Serial); Wire.begin();//I2C庫啟動 rc = kx224.init();//加速度傳感器對象的初始化 if (rc != 0) {//加速度傳感器對象的啟動檢測 Serial.println(F("KX224 initialization failed")); Serial.flush(); } pinMode(2, OUTPUT); pinMode(A0, INPUT); pinMode(A1, INPUT); } void loop() { // ============================================ // 加速度傳感器的讀取和發送 // ============================================ byte rc;//用于確認傳感器讀數。 float acc[3];// int photoRef1 = analogRead(A0);//反射式光電傳感器的讀取 int photoRef2 = analogRead(A1); rc = kx224.get_val(acc);//將加速度代入acc,如果可以讀取則返回 0。 if (rc == 0) { Serial.print(acc[0]);//X軸 Serial.print(","); Serial.print(acc[1]);//Y軸 Serial.print(","); Serial.print(acc[2]);//Z軸 Serial.print(","); Serial.print(photoRef1);//反射式光電傳感器1 Serial.print(","); Serial.print(photoRef2);//反射式光電傳感器2 Serial.println(""); } // ============================================ // 處理接收到的命令 // ============================================ if (stringComplete) {//設置了接收完成標志時的處理 String is = inputString;//復制接收到的字符串 is.trim();//刪除換行代碼 if ( is.equals("start") ) //當收到start 時 { digitalWrite(2, HIGH);//使電機運轉 } if ( is.equals("stop") ) //當接收到stop時 { digitalWrite(2, LOW);//使電機停止 } inputString = "";//清除接收到的字符串 stringComplete = false;//清除接收到的標志 } delay(10); } // ============================================ // 串行通信的接收 // ============================================ void serialEvent() {//接收到串行通信的事件 while (Serial.available()) { char inChar = (char)Serial.read(); // 將接收到的數據轉換為字符串 inputString += inChar; // 添加到inputString if (inChar == 'n') {// 當接收到換行代碼時,設置接收完成標志。 stringComplete = true; } } }
工作測試
我們已經創建了電子電路和Arduino程序,現在讓我們確認一下工作情況。用USB數據線連接Arduino UNO和電腦后,請打開Arduino IDE的串口監視器,將通信速度設置為57600bps。先會顯示消息“KX224_WHO_AMI Register Value = 0x2B”,從下一行開始會出現用逗號分隔的五個數字。
前三個是加速度傳感器模塊的X、Y、Z值。當傳感器模塊水平放置時,X和Y輸出0,Z輸出1。當傳感器模塊傾斜時,值在-1~1的范圍內變化。請傾斜Arduino UNO并確認值的變化情況。
后兩個數值是反射式光電傳感器得值。當附近沒有任何東西時,輸出個位數的值,當物體接近至距離5mm左右時,該值會超過500。請用手指等確認實際的反應情況。
接下來,確認接收命令后振動電機是否工作。在串口監控器的輸入字段中輸入“start”,然后按回車鍵。如果振動電機工作,則意味著成功了。如果電機不動,請確認面包板接線和接收程序命令的位置是否有錯誤。然后請鍵入“stop”來確認電機是否停止。
如果可以確認加速度傳感器模塊、反射式光電傳感器、振動電機的工作都沒問題,那么第一部分(前篇)就完成了。大家辛苦了!在后篇中,我們將完成實物迷宮的制作,并用Unity創建一個3D迷宮,敬請期待!
本系列連載一覽
前篇:用Arduino和加速度傳感器制作數字滾球迷宮(本章)
后篇:用Arduino和加速度傳感器制作數字滾球迷宮
審核編輯黃宇
-
電機
+關注
關注
142文章
9046瀏覽量
145835 -
加速度傳感器
+關注
關注
12文章
473瀏覽量
55176 -
Arduino
+關注
關注
188文章
6472瀏覽量
187378
發布評論請先 登錄
相關推薦
評論