Arduino如何使用Serial序列埠與Unity溝通。
0x0 環境
- Arduino Uno v3
- Unity 2018.1.4f1 (64bit)
- Visual Studio C#
0x1 前置設定
Unity設定需將Api Compatibility Level
設為Net2.0
.
按照教學, 還需要更改Scripting Runtime Version
設為.Net 4.x Equivalent
.
具體設定的路徑為Edit > Project Settings > Player > (Inspector) > Other Settings > Configuration
.
如果沒有做好以上兩點設定, 在Script中將無法using System.IO.Ports
.
0x2 Arduino 程式碼
1 2 3 4 5 6 7 8 9 10 11 12
| void setup() { Serial.begin(9600); }
void loop() { Serial.write("1"); if (Serial.avaliable()) { String data = Searil.read(); ... } }
|
0x30 Unity 程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| using System.IO.Ports;
public class ArduinoControl : MonoBehaviour {
private SerialPort sp; private int readTimeout = 1;
void Start () { sp = new SerialPort("COM7", 9600); if (!sp.IsOpen) { sp.Open(); sp.ReadTimeout = readTimeout; } }
void Update () { if (sp.IsOpen) { sp.Write(....); try { sp.Read(....); } catch (System.TimeoutException e) { } } }
public void Teardown () { if (sp.IsOpen) sp.Close(); }
}
|
0x31 SerialPort
Arduino的部份比較容易, 基本上依樣畫葫蘆就可以了。
比較困難的集中在C#中。
1
| SerialPort sp = new SerialPort("序列埠號", 鮑率);
|
Arduino跟C#的程式必須使用相同的鮑率, 否則讀取速度不一致, 資料會呈現亂碼。
0x4 Confusions
這本來是幫朋友做的一個裝置溝通的部份程式碼。
有遇到關於Slow reading
的問題。
也就是Arduino端已經送出了Serial資料,但是Unity卻沒有即時收到資料的狀況。
得花很久之後才會收到。
目前是暫時用下面的程式碼去處理。
有需要的朋友可以參考看看,如果有找出原因也拜託留言跟我說一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int sw, lastSend; int debounceDelay = 5;
void setup() { Serial.begin(9600); pinMode(2,INPUT); }
void loop() { sw = digitalRead(2); if (sw != lastSend) { lastSend = sw; Serial.println(lastSend); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| using UnityEngine; using System.IO.Ports;
public class ArduinoController : MonoBehaviour {
public SerialPort sp; public int readTimeout = 1000; public float readDelay = 0.4F;
private float leftPeriod; private string arduinoData;
void Start() { this.leftPeriod = this.readDelay; this.sp = new SerialPort("/dev/tty.usbmodem14101", 9600); if (!sp.IsOpen) { sp.Open(); sp.ReadTimeout = readTimeout; } }
void Update() { leftPeriod -= Time.deltaTime; if (leftPeriod < 0 && sp.IsOpen) { try { string tempData = sp.ReadLine(); if (!tempData.Equals(arduinoData)) { arduinoData = tempData; Debug.Log(arduinoData); } } catch (System.TimeoutException e) { throw; } leftPeriod = readDelay; }
}
public void Teardown() { if (sp.IsOpen) sp.Close(); } }
|
0x5 Others
使用Arduino的開關,除非有特地挑選過使用的開關種類,
不然大多會有彈跳(bounce)
的問題,在這邊不多贅述,
有機會開篇來講何謂彈跳以及其去彈跳(debounce)
的設計方法。
0x6 Reference
Microsoft Docs - System.IO.Ports
Arduino Serial