SerialPort frustartion

Hi All,
This is my first post and i have 1 week of Unity +C# under my belt so excuse me if im a little DUMB on this matter.

I have some basic script which will rotate a cube in Unity based on accellerometer values passed to it via an Android phone Bluetooth virtual serial port connection. The data passed to Unity is around 160 bytes per second (x,y,z float values). The serial port is set at 38,400,8,1,N (i have tried different settings). I have tried various receive time out’s from 1ms to 100ms, same problem occurs.The problem i am getting is all works fine for around 5 minutes THEN the data received by unity will start to slow down. What i mean by that is the data i pull from the serial port will be active for 5 seconds, then stop for 2 seconds then start for another 5 seconds. The missing data is in the buffer and read correctly by unity when it restarts. This time ratio is ALWAYS the same.

I have tried several methods of reading the buffer including ReadLine, ReadByte, ReadChar, ReadTo, all these functions exhibit the same behavior. These functions are called from a coroutine, i have also tried a separate a thread but with the same results. I have played with different baud and time out settings but with the same results. I also tried the serial data received event but that did not work at all, apparently there is some problem with this event in mono? I am beginning to think there is a problem with the SerialPort class in unity?

I have tried looking at the sent data from the Android with a terminal program and all is good so no problems there. I have set up a byte counter at each end of the comms and all bytes are received by unity providing it is in focus, the problem being this 2 second gap when unity does not receive (but the serial buffer is filling). I have tried this on 2 different machines with different O/S and the results are the same.

HELP cos it’s driving me nuts! (3 days with NO progress) can i use a 3rd party serial class? any suggestions would be REAL nice, but please remember im a newbie :slight_smile:

Cheers Ray

The problem is the same both in the editor and when i do a build on the project.

OK so after a LOT of digging around on the internet and reading lots of problems from other coders i have come to the conclusion that the problem lies in the serialport methods, see this link for a very in depth opinion from a “coms” expert.

He has suggested a reliable method for reading serial comms in an async fashion but because of my lack of experience with C# i cannot understand how i would implement this code in my main script. Could someone out there help me, please, please? I will post my findings here after some extensive testing and hopefully this will be useful to other serial comms users.

Here is the suggested code snippet…

byte[] buffer = new byte[blockLimit];
Action kickoffRead = delegate {

    port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) {

        try {

            int actualLength = port.BaseStream.EndRead(ar);

            byte[] received = new byte[actualLength];

            Buffer.BlockCopy(buffer, 0, received, 0, actualLength);

            raiseAppSerialDataEvent(received);
        }
        catch (IOException exc) {

            handleAppSerialError(exc);

        }
        kickoffRead();

    }, null);
}

kickoffRead();

Thanks in advance
Ray

How are we supposed to know how to implement it in your main script, when we’ve never seen your main script?

OK good point so here is the main script :wink: it’s empty as you can see. What i want to know is how i implement this code and read the serial data into a string. I can process and add this to my rotating cube later. I am trying to get to grips with C#, i have 1 week under my belt so the learning curve is BIG. my specialty is electronics design and writing code in assembler for micro controllers :-/

using UnityEngine;
using System.Collections;
using System.IO.Ports

public class ReadSerial : MonoBehaviour {

    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}

Thanks
Ray

im watching the learning video’s as we speak :slight_smile:

You should be able to just throw the entire chunk of code in your Start method. Assuming the code works as is.

OK Questions.

  1. what the hell is IAsyncResult ar? what do i do with that?
  2. raiseAppSerialDataEvent(received); this kicks an event of when data is received?
  3. the read data is available in buffer[ ]?
  4. is kickoffRead(); a function where i would parse the data?

Happy new year all :slight_smile:
I found this article interesting relating to serial I\O bugs and fixes for the port i.o class.
http://blogs.msdn.com/b/bclteam/archive/2006/10/10/top-5-serialport-tips-_5b00_kim-hamilton_5d00_.aspx

Im still working on this BUT one day in the distant future when im more up to speed with C# and OOP i will post my fix (hopefully :slight_smile:

Cheers
Ray