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

Posted B612灯夫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity和智能硬件交互系列:互动风车相关的知识,希望对你有一定的参考价值。

项目场景:

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

技术点:

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

硬件清单:

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

接线图 :

风车尺寸:风车到手需要进行改造,将正负极引出。这个需要一丢丢动手操作(建议多买几个备用~)。

此处黑色按钮位置,替换为上面引出的两极~如果发现没有效果,可能是接反了。

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:

互动展示2:
启动,通过吹气来触发操作

Unity动效:

互动拓展:

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

相关硬件:

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

以上是关于Unity和智能硬件交互系列:互动风车的主要内容,如果未能解决你的问题,请参考以下文章

Unity和智能硬件交互系列:MPU6050

Unity和智能硬件交互系列:MPU6050

蓝桥杯国赛11Scratch旋转风车 少儿编程scratch蓝桥杯国赛真题和答案讲解

数学传奇2——格林的风车

抖音直播间小风车跳转微信安全吗

抖音小风车引流到微信