NodeMCU 统一连接,使用 UDP

NodeMCU Unity Connection, using UDP

我正在为我的大学项目尝试将 NodeMCU 与 unity 连接起来。

我的 nodemcu 接收数据(使用 UDP 测试工具应用程序测试)。我会在下面留下代码。

但是 Unity 我有问题。我试图找到一个简单的例子或类似的东西。

我最近找到的代码很简单,但它让Unity卡住了。我找到它 here 并稍微编辑了它。

Arduino 中的 NodeMCU 代码IDE

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "Epic SSID";
const char* password = "EpicPassword";

WiFiUDP Udp;
unsigned int port = 25666;
char packet[255];

IPAddress ip(192, 168, 43, 20);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
    Serial.begin(115200);
    Serial.println();

    WiFi.hostname("YVRB-01");
    WiFi.config(ip, gateway, subnet);

    Serial.printf("Connecting to %s ", ssid);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }

    Serial.println("Connection Successful");
    Udp.begin(port);
    Serial.printf("Listener started at IP %s, at port %d", WiFi.localIP().toString().c_str(), port);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
      Serial.printf("Received %d bytes from %s, port %d", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
      int len = Udp.read(packet, 255);
      if (len > 0)
      {
          packet[len] = 0;
      }
      Serial.printf("UDP packet contents: %s", packet);
      Serial.println();
  }

  Udp.beginPacket (Udp.remoteIP(), Udp.remotePort());
  Udp.write("Epic message");
  Udp.endPacket();

  delay(300);
}

当它起作用时,我脱下了衬衫,运行 也脱下了厨房。

我在 Unity 中的代码

/*
C# Network Programming
by Richard Blum

Publisher: Sybex
ISBN: 0782141765
*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class udpsend : MonoBehaviour
{
    Socket server;
    IPEndPoint ipep;

    void Start()
    {
        byte[] data = new byte[1024];

        ipep = new IPEndPoint(
                        IPAddress.Parse("192.162.43.209"), 25666);

        server = new Socket(AddressFamily.InterNetwork,
                       SocketType.Dgram, ProtocolType.Udp);

        string welcome = "I am connected";
        data = Encoding.ASCII.GetBytes(welcome);
        server.SendTo(data, data.Length, SocketFlags.None, ipep);
    }


    void Update()
    {
        string input, stringData;

        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        EndPoint Remote = (EndPoint)sender;

        byte[] data = new byte[1024];
        int recv = server.ReceiveFrom(data, ref Remote);

        Console.WriteLine("Message received from {0}:", Remote.ToString());
        Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));

        //while (true)
        //{
        //    input = Console.ReadLine();
        //    if (input == "exit")
        //        break;
        //    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
        //    data = new byte[1024];
        //    recv = server.ReceiveFrom(data, ref Remote);
        //    stringData = Encoding.ASCII.GetString(data, 0, recv);
        //    Console.WriteLine(stringData);
        //}

        Console.WriteLine("Stopping client");
        server.Close();
    }


    public void SendData(string message)
    {
        byte[] data = new byte[1024];
        data = Encoding.ASCII.GetBytes(message);
        server.SendTo(data, data.Length, SocketFlags.None, ipep);

    }
}

我只是说我没有完全理解,但我稍微编辑了一下。

任何修复或代码示例将不胜感激。我只想要一个可以调用的方法,例如 SendData("Never gonna give you up!").

我现在可以将信息从 Unity 应用程序传输到 NodeMCU 以及从 NodeMCU 到 Unity!

全部代码如下

我使用了代码并稍微编辑了一下。

为了接收数据,我在这里使用了 this code

为了发送信息,我使用了 this code 并将这段代码“混搭”在一起,创建了一个可以发送和接收的程序。

我这样做的原因是存在冲突,因为有一个客户端和多个代码试图访问它。

对于 Node MCU,我使用了 this code,这与我在上面的问题中所写的几乎相同。

我还制作了管理器代码,我可以使用它发送消息和做其他事情。

关闭所有端口也很重要,否则Unity会死机(很烦人的事情)。

Arduino 中的 Nodemcu 代码 IDE:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "YVRB";
const char* password = "YGreater";

WiFiUDP Udp;
unsigned int port = 25666;
char packet[255];

IPAddress ip(192, 168, 43, 20);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.hostname("YVRB-01");
  WiFi.config(ip, gateway, subnet);

  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("Connection Successful");
  Udp.begin(port);
  Serial.printf("Listener started at IP %s, at port %d", WiFi.localIP().toString().c_str(), port);
  Serial.println();
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    Serial.printf("Received %d bytes from %s, port %d", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(packet, 255);
    if (len > 0)
    {
      packet[len] = 0;
    }
    Serial.printf("UDP packet contents: %s", packet);
    Serial.println();
  }

  Udp.beginPacket (Udp.remoteIP(), Udp.remotePort());
  Udp.write("Important data");
  Udp.endPacket();

  delay(300);
}

文件UDPSend.cs同时接收的代码:

// Inspired by this thread: https://forum.unity.com/threads/simple-udp-implementation-send-read-via-mono-c.15900/
// Thanks OP la1n
// Thanks MattijsKneppers for letting me know that I also need to lock my queue while enqueuing
// Adapted during projects according to my needs

using UnityEngine;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class UDPSend
{
    public string IP { get; private set; }
    public int sourcePort { get; private set; } // Sometimes we need to define the source port, since some devices only accept messages coming from a predefined sourceport.
    public int remotePort { get; private set; }

    IPEndPoint remoteEndPoint;

    Thread receiveThread;

    // udpclient object
    UdpClient client;

    // public
    // public string IP = "127.0.0.1"; default local
    public int port = 25666; // define > init

    // Information
    public string lastReceivedUDPPacket = "";
    public string allReceivedUDPPackets = ""; // Clean up this from time to time!

    public bool newdatahereboys = false;

    public void init(string IPAdress, int RemotePort, int SourcePort = -1) // If sourceport is not set, its being chosen randomly by the system
    {
        IP = IPAdress;
        sourcePort = SourcePort;
        remotePort = RemotePort;

        remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), remotePort);
        if (sourcePort <= -1)
        {
            client = new UdpClient();
            Debug.Log("Sending to " + IP + ": " + remotePort);
        }
        else
        {
            client = new UdpClient(sourcePort);
            Debug.Log("Sending to " + IP + ": " + remotePort + " from Source Port: " + sourcePort);
        }

        receiveThread = new Thread(
            new ThreadStart(ReceiveData));
        receiveThread.IsBackground = true;
        receiveThread.Start();

    }

    private void ReceiveData()
    {
        //client = sender.client;
        while (true)
        {
            try
            {
                // Bytes empfangen.
                IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
                byte[] data = client.Receive(ref anyIP);

                // Bytes mit der UTF8-Kodierung in das Textformat kodieren.
                string text = Encoding.UTF8.GetString(data);

                // Den abgerufenen Text anzeigen.

                Debug.Log(text);
                newdatahereboys = true;
                //PlayerPrefs.SetString("ReceivedData", text);

                // Latest UDPpacket
                lastReceivedUDPPacket = text;

                // ....
                allReceivedUDPPackets = allReceivedUDPPackets + text;
            }
            catch (Exception err)
            {
                Debug.Log(err.ToString());
            }
        }
    }

    // sendData in different ways. Can be extended accordingly
    public void sendString(string message)
    {
        try
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            client.Send(data, data.Length, remoteEndPoint);

        }
        catch (Exception err)
        {
            Debug.Log(err.ToString());
        }
    }

    public void sendInt32(Int32 myInt)
    {
        try
        {
            byte[] data = BitConverter.GetBytes(myInt);
            client.Send(data, data.Length, remoteEndPoint);
        }
        catch (Exception err)
        {
            Debug.Log(err.ToString());
        }
    }

    public void sendInt32Array(Int32[] myInts)
    {
        try
        {
            byte[] data = new byte[myInts.Length * sizeof(Int32)];
            Buffer.BlockCopy(myInts, 0, data, 0, data.Length);
            client.Send(data, data.Length, remoteEndPoint);
        }
        catch (Exception err)
        {
            Debug.Log(err.ToString());
        }
    }

    public void sendInt16Array(Int16[] myInts)
    {
        try
        {
            byte[] data = new byte[myInts.Length * sizeof(Int16)];
            Buffer.BlockCopy(myInts, 0, data, 0, data.Length);
            client.Send(data, data.Length, remoteEndPoint);
        }
        catch (Exception err)
        {
            Debug.Log(err.ToString());
        }
    }

    public string getLatestUDPPacket()
    {
        allReceivedUDPPackets = "";
        return lastReceivedUDPPacket;
    }

    public void ClosePorts()
    {
        Debug.Log("closing receiving UDP on port: " + port);

        if (receiveThread != null)
            receiveThread.Abort();

        client.Close();
    }
}

文件manager.cs:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class manager : MonoBehaviour {

    public int Remoteport = 25666;

    public UDPSend sender = new UDPSend();

    public string datafromnode;

    void Start()
    {
        sender.init("192.168.43.209", Remoteport, 25666);
        sender.sendString("Hello from Start. " + Time.realtimeSinceStartup);

        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyUp(KeyCode.Return))
            sender.sendString("This should be delivered");

        if (sender.newdatahereboys)
        {
            datafromnode = sender.getLatestUDPPacket();
        }
    }

    public void OnDisable()
    {
        sender.ClosePorts();
    }

    public void OnApplicationQuit()
    {
        sender.ClosePorts();
    }

}

成功!参见 justlookatem。