Communication Unity -> Arduino something is missing in serial monitoring

Hello,

i want to send a "mpu-read" string to tell the arduino nano μC to send me the mpu data. When i am sending the mpu-read string with the serial monitor of the arduino IDE, i am getting the right response from the arduino controller "MPU data send to unity..." (I am viewing this with serial port monitor Serial Port Monitor in dump view) depicted in the following screenshot.

|500x154

But when i am sending via the C# code (have listed only the main functionality for shortening) from Unity:

public class Arduino : MonoBehaviour {
  private int serialBaudRate = 115200;
  private SerialPort serialInterface;
  private string serialString;


  void OnEnable() {
    configSerialPort("COM5", serialBaudRate);
  }

  // Configs the serial port 
  void configSerialPort(string port, int baudRate) {
    serialInterface = new SerialPort(port, baudRate, Parity.None, 8, StopBits.One);
    serialInterface.Handshake = Handshake.None;
    serialInterface.ReadTimeout = 500;    // 0.5 sec
    serialInterface.WriteTimeout = 500;
    serialInterface.DtrEnable = true;      // IMPORTANT: auto-resets the arduino
    serialInterface.RtsEnable = true;      // IMPORTANT: auto-resets the arduino
    serialInterface.Open();
  }

  void Start () {
    serialInterface.Write("mpu-read");
  }

  ...
}

I am getting no response :confused: :

|500x162

[ARDUINO CODE]

void setup()
{
  Serial.begin(115200);         // Set baud rate to 115200;
  while (!Serial);              // Waits for establishing the serial port with the pc
}

void loop() {
  if (Serial.available() > 0) {
    String s = Serial.readString();  

    if(s.equals("mpu-read"))
      Serial.println("MPU data send to unity...");
  }
  delay(20);
}

Via the Serial Port Monitor app (table view) i could see that there is no IOCTL_SERIAL_SET_WAIT_MASK and IOCTL_SERIAL_WAIT_ON_MASK request when i am sending over Unity.

[Serial Port Monitor - Unity] |500x132

[Serial Port Monitor - Arduino] |500x117

Maybe someone knows this problem solution and can help me.

Thank you in advance

My C# code to open the serial port:

            System.ComponentModel.IContainer components = 
                new System.ComponentModel.Container();
            port = new System.IO.Ports.SerialPort(components);
            port.PortName = comPort.SelectedItem.ToString();
            port.BaudRate = Int32.Parse(baudRate.SelectedItem.ToString());
            port.DtrEnable = true;
            port.ReadTimeout = 5000;
            port.WriteTimeout = 500;
            port.Open();

I have a drop down list widget with the available com ports in it, and a list for the baud rates. I do not use RtsEnable, and how I deal the the SerialPort instance is different from how you do it.

Mine works.

Hello Paul and thank you for your help.

I have tried your solution without the drop down list cause I am using only Unity for my project and not WPF. In the Unity editor the player can choose the COM port and enter the baudrate (this is not ready only for test purpose I have set this). But it still does not work. Maybe this is an issue of Unity cause with the serial monitor from VS and the Arduino IDE i have no problem to get the response. I have searched over three days to find a solution of this problem, but I have nothing found that helps me. Since your solution works with WPF, too, I believe that the Serial class of C# does is not 100% compatible with Unity. Maybe there is a plugin in the app store but they mostly cost :(. Have you checked maybe with a serial port monitor app if you get this two missing requests IOCTL_SERIAL_SET_WAIT_MASK and IOCTL_SERIAL_WAIT_ON_MASK?

EDIT: I got the issue of the compatibility problem from here http://stackoverflow.com/questions/30011887/why-dont-serial-ports-work-properly-in-unity

EDIT2: Finaly i managed to get at least one character. The problem that it was not reading anything in Unity (or C#) was that I did not read properly the serial input buffer. But how can I read a full string and not only one character in C# and arduino? Thank you Paul for your help.

But how can I read a full string and not only one character in C# and arduino?

Write the proper code. You did not post your code for reading the serial data, so I can’t see what is wrong with it.

Oh yes you are right i've forgotten this. Ok now I am testing at first in C# and not Unity so here is my C# code.

C# Code

namespace SerialPortTestArduino {
  class Program {
    static void Main(string[] args) {
      
      SerialPort port = new SerialPort("COM4", 115200);
      port.DtrEnable = true;
     // port.RtsEnable = true;
      port.ReadTimeout = 5000;
      port.WriteTimeout = 500;
      port.Open();

      // Wait till serial port is ready
      int milliseconds = 2000;
      Thread.Sleep(milliseconds);

      if(port.IsOpen)
        port.Write("mpu-ready");

      // Read entire string from serial port
      string s = port.ReadExisting();
      Console.WriteLine("String: " + s);

      var v = Console.ReadLine();
    }
  }

Arduino

String s = "";

void setup()
{
  Serial.begin(115200);         // Set baud rate to 115200;
  while (!Serial);              // Waits for establishing the serial port with the pc
}

void loop() {
    if (Serial.available() > 0) {
        s = Serial.readString();
        Serial.println(s);
    }

  /*if(s.equals("mpu-read")) {
    Serial.println("MPU data send to unity...");
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
  }*/
  
  delay(20);
}

Thank you in advance

There are many methods in the SerialPort class for reading data from the port. ReadExisting() will grab whatever data has arrived. ReadLine() will read whatever data is there, up to a carriage return/line feed, waiting, if necessary, until they arrive. That’s what I use to get all of what the Arduino had to say.

Thanks for the nice explanation, I have used the ReadLine method for my purpose :).