Убедитесь, что вы открываете правильный порт, используя правильные настройки.Вот пример того, как вы можете настроить его:
serial = new SerialPort();
serial.ReadBufferSize = 8192;
serial.WriteBufferSize = 128;
serial.PortName = "COM1";
serial.BaudRate = 115200;
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
// attach handlers
// (appears to be broken in some Mono versions?)
serial.DataReceived += SerialPort_DataReceived;
serial.Disposed += SerialPort_Disposed;
serial.Open();
Я рекомендую терминал с открытым исходным кодом RealTerm , он имеет богатый набор функций и может помочь вам в отладке.Попробуйте написать байт вручную с помощью такого программного обеспечения, и, если оно работает, проблема в вашей программе.В противном случае это может быть проблема с драйвером (но, скорее всего, это не так).
[Редактировать]
Вызов SerialPort.ReadLine
на самом делепредполагается блокировать поток до получения SerialPort.NewLine
.Также ReadChar
и ReadByte
будут зависать, пока не будет получен хотя бы один байт.Вам нужно убедиться, что вы на самом деле получаете символы с другой стороны, и вы не будете получать их, если ваше приложение зависло и не может отправить пробел.
Поскольку я никогда не использовал Unity, я неконечно, как вызывается Update
, но я предполагаю, что он запускается в потоке переднего плана через регулярные промежутки времени (иначе ваше приложение не зависнет).
Пример, который вы связали ( Пример Arduino и Unity) показывает, что Arduino непрерывно отправляет данные, и поэтому их метод Update
постоянно получает данные (символ пробела не нужно отправлять на устройство).Если они отключат устройство, их приложение также будет зависать.
Ну, возможно, нет, потому что в .NET 1.1 значение по умолчанию для ReadTimeout
не было бесконечным, как в .NET 2.0.
Итак, что вы можете сделать:
a. Установите для свойства ReadTimeout
разумное значение.По умолчанию в .NET 2.0 используется InfiniteTimeout, который не соответствует вашим потребностям.Минусы: ваш метод обновления будет зависать некоторое время при каждом вызове, но не бесконечно.
b. Кто-то сказал, что события не реализованы в MONO SerialPort, поэтому я предполагаю, что с помощью DataReceived
только не вариант.
c. Переместите логику отправки в метод Update
, чтобы вы вообще не читали данные,пока не настало время его прочитать:
private volatile bool _shouldCommunicate = false;
void Update ()
{
if (_shouldCommunicate) // this is a flag you set in "OnGui"
{
try {
stream.Write(" ");
Debug.Log(stream.ReadLine());
} catch (Exception e){
Debug.Log("Error reading input "+e.ToString());
}
}
}
void OnGUI() // simple GUI
{
if (GUI.Button (new Rect(10,10,100,20), "Send"))
_shouldCommunicate = true;
}
Обратите внимание, что если ваше устройство не отправляет данные, оно также будет блокироваться на stream.ReadLine()
, поэтому убедитесь, что для вашего ReadTimeout
установлено разумное значение.Вы также захотите прекратить отправку в какой-то момент, но я оставлю это вам.
d. Отправьте пробел в OnGui
, как вы делаете сейчас, но всегда проверяйте, есть лиесть ли данные в вашем буфере перед чтением:
void Update () { // called about 60 times/second
try {
// call our new method
Debug.Log(ReadLineNonBlocking());
} catch (Exception e){
Debug.Log("Error reading input "+e.ToString());
}
}
private StringBuilder sb = new StringBuilder();
string ReadLineNonBlocking()
{
int len = stream.BytesToRead;
if (len == 0)
return "";
// read the buffer
byte[] buffer = new byte[len];
stream.Read(buffer, 0, len);
sb.Append(ASCIIEncoding.ASCII.GetString(buffer));
// got EOL?
if (sb.Length < 2 ||
sb[sb.Length-2] != '\r' ||
sb[sb.Length-1] != '\n')
return "";
// if we are here, we got both EOL chars
string entireLine = sb.ToString();
sb.Length = 0;
return entireLine;
}
Отказ от ответственности: это прямо из моей головы, не проверено, поэтому могут быть некоторые синтаксические ошибки, с которыми, я уверен, вы справитесь.