我想通过蓝牙将我的Unity 3D 游戏与Arduino等微控制器连接起来,为此我正在使用(HC-05)蓝牙模块。
为此,资产商店中有一个名为Arduino 蓝牙插件 链接的插件。收费是 19 美元。
有没有其他方法可以通过使用免费功能和编码来做到这一点?
你绝对可以通过自己编码来做到这一点。
我无法在 C# 部分为您提供帮助,但我已经编写了代码以通过 HC-06 模块为 arduino 发送数据,并通过蓝牙和蓝牙低功耗与 Android 应用程序进行通信。
归根结底,它与 Socket 编程非常相似。
所以对于 C# 部分,这个用户有一个基本的工作 C# BT 通信示例
对于 Arduino 方面,我使用了这个草图:
/**************************************************
*
* Using the BUILT-IN Serial.
*
* CONFIGURATION:
*
* ARDUINO NANO - HC-06
* YELLOW TX RX
* GREEN RX TX
* RED 3V3 VCC
* BLACK GND GND
*
**************************************************/
void setup() {
// Init the Built-In Serial.
Serial.begin(9600);
}
void loop() {
// Send the message
Serial.println("MISSATGE PER UN LINUX!!!");
delay(2000);
}
因此,在将 arduino 与我的笔记本电脑配对并使用命令收听传入消息后
$ cat /dev/rfcomm0
我开始在控制台上看到输出:
因此,您可以发送从 Arduino 输入中读取的任何内容,然后在 C# 端重新解析它,而不是发送字符串。
我希望我对您有所帮助;祝你好运!!!
Arduino 通过 USB 连接到 PC,因此可以通过Serial I/O
和访问Port
。您首先需要在您的统一Start()
方法中初始化串行并定义端口,以便它可以侦听。在我的代码中,我正在从Update()
方法监听端口。如果您想发送input
到 arduino,请参阅SerialCmdSend(string data)
将参数作为string
值的方法。您可以根据需要定义它或在 arduino 代码中更改它。
统一 C# 代码:
using UnityEngine;
using System.Net;
using System.IO;
using System.IO.Ports;
using System;
public class Controller : MonoBehaviour
{
SerialPort serial = new SerialPort();
void Start()
{
InitializeSerial();
}
void InitializeSerial()
{
try
{
serial.PortName = "Your Port";
serial.BaudRate = 9600;
serial.Handshake = System.IO.Ports.Handshake.None;
serial.Parity = Parity.None;
serial.DataBits = 8;
serial.StopBits = StopBits.One;
serial.ReadTimeout = 20;
serial.WriteTimeout = 50;
serial.DtrEnable = true;
if (!serial.IsOpen)
{
serial.Open();
}
}
catch (Exception e)
{
print("Error: " + e.Message);
}
}
void Update()
{
//check serial
if (serial.IsOpen)
{
try
{
//print("serial " + serial.ReadByte());
if (serial.ReadByte() == 0)
{
//Do something here
}
else
{
// Do something else
}
}
catch (Exception e)
{
print("Error: " + e.Message);
}
}
}
public void SerialCmdSend(string data)
{
if (serial.IsOpen)
{
try
{
byte[] hexstring = Encoding.ASCII.GetBytes(data);
foreach (byte hexval in hexstring)
{
byte[] _hexval = new byte[] { hexval };
serial.Write(_hexval, 0, 1);
Thread.Sleep(1);
}
}
catch (Exception ex)
{
print(ex);
}
}
}
}
Arduino代码:
首先在 Arduino IDE 中检查您的端口,选择 Tools >> Ports >> The number that your Arduino is connected to and copy and paste this port in Unity code above.
const int RELAY_PIN1 = 3;
const int RELAY_PIN2 = 4;
const int buttonPin = 2;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
int incomingByte = 0;
bool onLight = false;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(RELAY_PIN1, OUTPUT);
pinMode(RELAY_PIN2, OUTPUT);
Serial.begin(9600);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter++;
}
if (buttonState == LOW) {
Serial.write(0);
Serial.flush();
}
// Delay a little bit to avoid bouncing
delay(20);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
if(onLight)
{
digitalWrite(RELAY_PIN1, HIGH);
digitalWrite(RELAY_PIN2, HIGH);
delay(500);
digitalWrite(RELAY_PIN1, LOW);
digitalWrite(RELAY_PIN2, LOW);
delay(500);
}
else
{
digitalWrite(RELAY_PIN1, LOW);
digitalWrite(RELAY_PIN2, LOW);
}
if (Serial.available() > 0)
{
char ltr = Serial.read();
if(ltr == 'r')
{
onLight = true;
}
else if(ltr = 'g')
{
onLight = false;
}
}
这是我根据需要的代码。您可以完全更改它或编写自己的代码。重要的是您希望如何接收从 Arduino 到 Unity 的输入。我正在使用Serial.write(0)
从 Arduino 接收作为整数值的输入。您可以使用Serial.println("on")
. 您应该在此处查看 Arduino 文档以获取更多信息。
如果您需要进一步的帮助,请告诉我。
是的。
不是 100% 肯定,但我认为蓝牙的工作方式与 USB 连接非常相似。这是 Unity 中适用于 Arduino 的 C# 控制器的示例,适用于 Arduino USB 连接:
using System;
using System.IO.Ports;
using UnityEngine;
using UnityEngine.UI;
public class ArduinoController : MonoBehaviour
{
[Header("Messages")]
[SerializeField] private String m_MessageReaded = "";
[SerializeField] private String m_MessageSended = "";
[Header("SerialPort values")]
[SerializeField] private String m_COM = "COM7";
[SerializeField] private int m_baudrate = 115200;
[SerializeField] private int m_readTimeout = 10;
[SerializeField] private int m_writeTimeout = 10;
[SerializeField] private float m_delay = 0.05f;
private SerialPort m_serialPort;
private float m_lastSentTime;
//Initialize and open SerialPort, set timers
void Start()
{
m_serialPort = new SerialPort(m_COM, m_baudrate)
{
ReadTimeout = m_readTimeout,
WriteTimeout = m_writeTimeout
};
OpenPort(m_serialPort);
m_lastSentTime = Time.time;
}
// Update is called once per frame
void Update()
{
ManageArduinoCommunication();
}
//Encapsulated try-catch to open the port
void OpenPort(SerialPort port)
{
try
{
port.Open();
print("Open Port " + port.PortName);
}
catch (Exception e)
{
print("Do not open Port " + port.PortName);
}
}
public void ManageArduinoCommunication()
{
if (m_serialPort != null)
{
if (m_serialPort.IsOpen)
{
//WRITE TO ARDUINO
WriteToArduino();
//READ FROM ARDUINO
ReadFromArduino();
}
}
else
{
OpenPort(m_serialPort);
}
}
private void WriteToArduino()
{
m_MessageSended = "";
if (!Input.GetKeyDown(KeyCode.LeftShift))
{
if (Input.GetKeyDown(KeyCode.Alpha2))
{
m_MessageSended = "openGate";
m_serialPort.WriteLine(m_MessageSended);
}
if (Input.GetKeyDown(KeyCode.Alpha4))
{
m_MessageSended = "closeGate";
m_serialPort.WriteLine(m_MessageSended);
}
}
}
private void ReadFromArduino()
{
if (Time.time - m_lastSentTime >= m_delay)
{
try
{
m_MessageReaded = m_serialPort.ReadLine();
}
catch (TimeoutException e)
{
// no-op, just to silence the timeouts.
// (my arduino sends 12-16 byte packets every 0.1 secs)
}
m_lastSentTime = Time.time;
}
}
private void OnApplicationQuit()
{
m_serialPort.Close();
}
}
然后你需要 Arduino 端的代码,看起来类似于:
//define PINS
#define DOOR_PIN_OPEN 26
#define DOOR_PIN_OPEN_2 27
#define DOOR_PIN_CLOSE 30
#define DOOR_PIN_CLOSE_2 31
//declare variables
bool isOpen = false;
String message = "";
void setup() {
//Set pinModes
pinMode(DOOR_PIN_OPEN,OUTPUT);
pinMode(DOOR_PIN_OPEN_2,OUTPUT);
pinMode(DOOR_PIN_CLOSE,OUTPUT);
pinMode(DOOR_PIN_CLOSE_2,OUTPUT);
//Set initial values
digitalWrite(DOOR_PIN_OPEN, HIGH);
digitalWrite(DOOR_PIN_OPEN_2, HIGH);
digitalWrite(DOOR_PIN_CLOSE, LOW);
digitalWrite(DOOR_PIN_CLOSE_2, LOW);
Serial.begin(115200);
}
void loop() {
if(Serial.available() > 0){
ReadSensorsStates();
//CheckSerialInputs();
ReadFromUnity();
UpdateSensorsStates();
}
else{
//Serial.println("not available");
}
}
void ReadSensorsStates(){
//Start the sensors reading
isOpen = ( digitalRead(DOOR_PIN_OPEN) == LOW );
//Serial.println(isOpen);
}
void CheckSerialInputs(){
}
void ReadFromUnity()
{
message = Serial.readString();
message = message.substring(0,message.length() -2); //purge \0\n
if( message == "openGate" ){
Serial.println(message);
delay(500);
digitalWrite(DOOR_PIN_OPEN, HIGH);
digitalWrite(DOOR_PIN_CLOSE, LOW);
}
if(message == "closeGate"){
Serial.println(message);
delay(500);
digitalWrite(DOOR_PIN_OPEN, LOW);
digitalWrite(DOOR_PIN_CLOSE, HIGH);
}
//reset variables
message = "";
delay(200);
}
void UpdateSensorsStates()
{
//code to update sensorsStates
}
有了所有这些信息,您就可以确定蓝牙是否需要任何额外的配置或修改,如果是这种情况,请告诉我们^^