Unity和智能硬件交互系列:互动风车

项目场景:

试想一下,在商场进行产品推广过程中,一般的大屏/宣传板/传单已经远远不能满足当前年轻人的需求,那么我们是不是可以通过一些小创意来增加用户的体验呢?
本文我们将使用Unity3D 配合Arduino硬件开发,创作一个互动程序,用户通过风车与大屏上的动画进行交互。

技术点:

  • Unity 3D与Arduino串口通信
  • Arduino与主机串口通信
  • 风车数据读取

硬件清单:

  • 风车一个(需改造):tb地址
  • Arduino Nano 一个;
  • USB线一条;
  • 跳线若干;
  • 烙铁等;

接线图 :

风车尺寸:风车到手需要进行改造,将正负极引出。这个需要一丢丢动手操作(建议多买几个备用~)。
Unity和智能硬件交互系列:互动风车_第1张图片

此处黑色按钮位置,替换为上面引出的两极~如果发现没有效果,可能是接反了。
Unity和智能硬件交互系列:互动风车_第2张图片

Arduino 代码:

Arduino硬件侧需要读取风车的实时电讯号,并将其转换为数值即(0-1023)发送到串口,Unity 3D程序读取串口数据,并根据不同数值,在程序中呈现不同效果。
void setup() {
   // 初始化串行通信速率为115200bit/s:
   Serial.begin(115200);
}

void loop() {
   // 读取模拟引脚A0的输入数据
   int sensorValue = analogRead(A0);
   // 将模拟信号转换成电压
   float voltage = sensorValue * (5.0 / 1023.0);
   // 打印到串口监视器,可以根据实际需要,改成各种形式
   Serial.println(voltage);
}

Unity 3D效果:

  • Unity 3D模块需要连接计算机串口,对数据进行解析

    关键代码:
using UnityEngine;
using System.Collections;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Collections.Generic;
using LitJson;
using System;

public class SerialControl : MonoBehaviour {
    public static SerialControl instance;
	//处理实时上传的数据
    public delegate void DataIn(string text);
    public SerialPort serialPort = null;
    public  string strIn;
//创建线程,监听数据
    Thread myThr;
	//创建线程,检查串口状态
    Thread myCheck;
    string portName;
    bool run = false;
   public DataIn dataHandle;
    void Awake()
    {
        instance = this;
    }
    void Start()
    {
		//场景跳转不销毁
        DontDestroyOnLoad(gameObject);
		//此处根据项目需要可以配置,测试时候可以直接写死
        portName = "COM3";//File.ReadAllText("Data/config.txt");
        OpenConnection();    
        myCheck = new Thread(new ThreadStart(CheckConnect));
        myCheck.Start();
    }
    void Update()
    {
     /*   if (serialPort.IsOpen)
        {    
        }*/
    }
    void CheckConnect()
    {
        while (true)
        {
            string[] portNames = SerialPort.GetPortNames();
            bool connect = false;
         //   bool needConn=false;
            for (int i = 0; i < portNames.Length; i++)
            {
                if (portName == portNames[i])
                {
                    connect = true;
                    break;
                }
            }
          
            if (!run && connect||!connect)
            {
             
                serialPort.Dispose();
                serialPort = null;
                run = false;
                try
                {
                    OpenConnection();
                }
                catch (Exception e)
                {
                    Debug.Log(e.Message);
                }
            }
            Thread.Sleep(3000);
        }
    }
   void ReadThread()
    {
        while (run)
        {
           if (serialPort.IsOpen)
                {
                    string dataLine = serialPort.ReadLine();

                    JsonData data = JsonMapper.ToObject(new JsonReader(dataLine));
                    string rate = data["rate"].ToString();
                    dataHandle.Invoke(rate);
                 //   Debug.Log(id);
                 //   Debug.Log(dataLine);
                }
//            Debug.Log("dataLine");
            Thread.Sleep(50);
        }
    }
    public void OpenConnection()
    {
        serialPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
        if (serialPort != null)
        {
            if (serialPort.IsOpen)
            {
             //   serialPort.Close();
                Debug.Log("Closing port, because it was already open!");
            }
            else
            {
                try{
      serialPort.Open();
         //  serialPort.ReadTimeout = 50;
                run = true;
                Thread  myThr = new Thread(new ThreadStart(ReadThread));
                myThr.Start();
                Debug.Log("Port Opened!");
                }catch(Exception e){
                    
                }
            }
        }
        else
        {
            if (serialPort.IsOpen)
            {
                print("Port is already open");
            }
            else
            {
                print("Port == null");
            }
        }
    }

    void OnApplicationQuit()
    {
		//结束记得清理
        if(serialPort!=null)
        serialPort.Close();
        myCheck.Abort();
        Debug.Log("Port closed!");
    }
}

最终效果:

互动展示1:
Unity和智能硬件交互系列:互动风车_第3张图片
互动展示2:
启动,通过吹气来触发操作
Unity和智能硬件交互系列:互动风车_第4张图片
Unity动效:
Unity和智能硬件交互系列:互动风车_第5张图片

互动拓展:

1、Unity 3D种的动效可以进行扩展,比如吹动柳絮、控制模型等可以进行更多的拓展; 2、Arduino硬件设备,在量产的情况下,可以通过专业设计,替换成更便宜的单片机; 3、输入设备,可以替换为压力传感器、声音传感器、滑动电阻、测距模块等

相关硬件:

  • 声音传感器:tb声音传感
  • 滑动电阻:tb滑动电阻
  • 重量感应:重量传感
    等等其他各种简单的硬件互动

可以进行互动的硬件设备还有很多,如果有好玩的应用想法,欢迎交流。

你可能感兴趣的:(Unity3D,Arduino,传感器,arduino,unity3d,人机交互)