5

我想通过蓝牙将我的Unity 3D 游戏Arduino等微控制器连接起来,为此我正在使用(HC-05)蓝牙模块。

为此,资产商店中有一个名为Arduino 蓝牙插件 链接的插件。收费是 19 美元

有没有其他方法可以通过使用免费功能编码来做到这一点?

4

3 回答 3

4

你绝对可以通过自己编码来做到这一点。

我无法在 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);
  
}

使用此接线: 接线

该模块的图像也可能对您有用,因此您可以看到引脚: 引脚排列 HC-06

因此,在将 arduino 与我的笔记本电脑配对并使用命令收听传入消息后

$ cat /dev/rfcomm0

我开始在控制台上看到输出:

控制台输出

因此,您可以发送从 Arduino 输入中读取的任何内容,然后在 C# 端重新解析它,而不是发送字符串。

我希望我对您有所帮助;祝你好运!!!

于 2021-01-21T01:04:46.490 回答
2

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 文档以获取更多信息。

如果您需要进一步的帮助,请告诉我。

于 2021-01-24T06:43:12.480 回答
2

是的。

不是 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
}

有了所有这些信息,您就可以确定蓝牙是否需要任何额外的配置或修改,如果是这种情况,请告诉我们^^

于 2021-01-20T13:07:57.103 回答