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.
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 :
[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]
[Serial Port Monitor - Arduino]
Maybe someone knows this problem solution and can help me.
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.
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?
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.
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);
}
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.