Communication between Unity and Arduino Yun via WiFi

Hello community,

I got my hands on an Arduino Yun and have been trying to establish a WiFi communication between the Yun and Unity. I set up a scene in Unity with a button and a default image. By pressing the button a LED on the Yun switches on and off. The LED status is displayed in the Unity scene by the color of the default image. Sounds easy, but it turns out it's not that easy. Especially with no prior experience about arduino. Well, google, my old dear friend, helped and found me some sources to build on. Including a thread of @ben_kidd who tried something very similar a few years ago with a wifi shield instead of a Yun.
Link:Here
After a little bit of tinkering and adjusting I got where I am now: At a somewhat frustrating dead end.

Problem:
I got my two main scripts, Network_Script(C#) and YunServer_sketch(err... C/C++) working without compiling errors. But the connection between Yun and Unity doesnt seem to hold. After a few Debug.Log() and Serial.println trial runs I found out that there is communication during start up. Yun seems to get a somewhat initialising byte and Unity is able to Debug.Log() a whole client.println() command from Yun. But immidiatly after the first tradeoff no more further communication happens.

Thoughts

  • in a few examples I saw the use of server.listenOnLocalhost(). But this line caused Unity to be rejected from establishing a connection. So there is either no need for it or some additional part is missing.
  • I have read about the Bridge of Yun and how it establishes a communication between the two cores. And that there is the REST method of sending and getting informations, which I might want to use later. But for now I try to get Unity and Yun communicating by sending strings.
  • The idea is for Unity to send a string, containing "1". Yun reads it, activates a LED and sends another string back, containing "Light on".

Additional Question:
Does #include<Bridge.h> only work with REST and thus should use #include<WiFi.h> instead?

  1. C# - Network_Script
     using UnityEngine;
     using System.Collections;
     using System;
     using System.IO;
     using System.Net.Sockets;
     
     public class Network_Script : MonoBehaviour
     {
         bool socketReady = false;
         TcpClient mySocket;
     
         public NetworkStream theStream;
         StreamWriter theWriter;
         StreamReader theReader;
     
         public String Host = "INSERT the public IP of router or Local IP of Arduino";
         public Int32 Port = 5555;
         public bool lightStatus;
     
         void Start ()
         {
             SetupSocket ();
         }
     // Check the stream for now data and change lightStatus
         void FixedUpdate ()
         {
             while (theStream.DataAvailable) {
                 string recievedData = ReadSocket ();
                 Debug.Log (recievedData);
     
                 if (recievedData == "Light on") {
                     lightStatus = true;
                 }
                 if (recievedData == "Light off") {
                     lightStatus = false;
                 }
     
             }
         }
     // Sets up the Socket
         public void SetupSocket()
         {
             try {
                 mySocket = new TcpClient(Host, Port);
                 theStream = mySocket.GetStream();
                 theWriter = new StreamWriter(theStream);
                 theReader = new StreamReader (theStream);
                 socketReady = true;
             }
             catch (Exception e)    {
                 Debug.Log ("Socket error: " + e);
             }
         }
     
         public void WriteSocket (string theLine)
         {
             if (!socketReady) {
                 Debug.Log ("Socket not ready.");
                 return;
             }
             String tmpString = theLine;
             theWriter.Write (tmpString);
             theWriter.Flush ();
             Debug.Log ("Socket ready and Line sent :" + tmpString);
         }
     
         public String ReadSocket()
         {
             if (!socketReady)
                 return "";
             if (theStream.DataAvailable)
                 return theReader.ReadLine ();
             return "NoData";
         }
     
         public void CloseSocket()
         {
             if (!socketReady)
                 return;
             theWriter.Close ();
             theReader.Close ();
             mySocket.Close ();
             socketReady = false;
         }
     
         public void MainTainConnection()
         {
             if (!theStream.CanRead)
                 SetupSocket ();
         }
     }
  1. YunServer_Sketch
     #include <Bridge.h>
     #include <YunServer.h>
     #include <YunClient.h>
     
     YunServer server(5555);
     boolean alreadyConnected = false;
     
     void setup() {
       Serial.begin(9600);
       pinMode(13, OUTPUT);
       digitalWrite(13, LOW);
       Bridge.begin();
       digitalWrite(13, HIGH);
       delay (2000);
       digitalWrite(13, LOW);
       
       server.begin();
     
     }
     
     void loop() {
       YunClient client = server.accept();
       if (client.connected()){
         client.println("Connected");
         Serial.println("Client: " + client);
         process(client);
       }
         delay(50);
     }
     
     void process (YunClient client){
       
         char command = client.read();
         client.println(command);
         client.flush();
     
       if(command == "1"){
         digitalWrite(13, HIGH);
         client.println("Light on");
         Serial.println("On");
         }
     
       if (command == "0"){
         digitalWrite(13, LOW);
         client.println("Light off");
         Serial.println("Off");
         }
       delay(50);
       }

I hope you can help me getting back on track.

with kind regards Sebastian

Hello community,

I wasn't able to establish a proper communication between Unity and Yun in which both talk to another. Everytime Yun would send a string, Unity stops writing altogether and doesn't receive anything. But at least I got a one way communication working, in which Unity sends a string and Yun interprets it correctly. I will post my current scripts here, for those that are interested. If you want to add something, feel free to leave your thoughts here.

Unity - C#

   using System;
   using UnityEngine;
   using System.Net.Sockets;
   using System.Collections;
   using System.IO;
   
   public class Network_Script : MonoBehaviour {
   
    public int value;
   
    internal Boolean socketReady = false;
    TcpClient mySocket;
    NetworkStream theStream;
    StreamWriter theWriter;
    StreamReader theReader;
    String Host = "SERVER - IP"; // eg String Host = "192.168.1.1";
    Int32 Port = ANYPORT; // eg Int32 Port = 5555;
   
    String reader;
   
    void Start(){
    SetupSocket ();
    }
   
    void Update(){
    WriteSocket (value.ToString());
    }
   
    public void SetupSocket(){
    try{
    mySocket = new TcpClient(Host, Port);
    theStream = mySocket.GetStream();
    theWriter = new StreamWriter(theStream);
    theReader = new StreamReader(theStream);
    socketReady = true;
    }
    catch (Exception e){
    Debug.Log ("Socket error: " + e);
    }
    }
   
    public void WriteSocket(string theLine){
    if (!socketReady)
    return;
    String foo = theLine + "\r\n";
    theWriter.Write (foo);
    theWriter.Flush ();
    }
   
   //This part didn't work for me, but I'll leave it here just in case someone else wants to tinker around.
    /*public String ReadSocket(){
    if (!socketReady)
    return "";
    try {
    return theReader.ReadLine ();
    } catch (Exception e) {
    Debug.Log ("Error ReadSocket: " + e);
    return "";
    }
    }*/
   
    public void CloseSocket(){
    if (!socketReady)
    return;
    theWriter.Close ();
    theReader.Close ();
    mySocket.Close ();
    socketReady = false;
    }
   }

Arduino Yun Sketch - C/C++

   #include <Bridge.h>
   #include <YunServer.h>
   #include <YunClient.h>
   #define PORT 5555
   
   YunServer server(PORT);
   YunClient client;
   
   static boolean clientActive = false;
   String saveString;
   int value;
   
   void setup()
   {
     Bridge.begin();
     server.noListenOnLocalhost();
     server.begin();
     client = server.accept();
   }
   
   void loop ()
   {
     client = server.accept();
     if (!clientActive)
       Serial.println("New client connection.");
     clientActive = true;
     if(client.available() > 0)
     {
       Serial.print("From client: \"");
       saveString = client.readStringUntil(10); // 10 equals the ASCII Code for line feed in byte, or at least there ends the information we want to interpret
       value= saveString.toInt();
       Serial.println(value);
       Serial.println("\"");
       client.flush();
     }
   }

with kind regards
Sebastian

PS: I posted this question on Unity - Answers page as well. There have been no replies yet, but there might be some later.
LinkToUnityAnswers

Hi,

Can you send the unity project files because I am having a hard time on creating the gameobjects attached to the scripts.