Serial Communication (with Arduino) on Windows - Errors when reading and writing

Hey all! I’m working on a sample project that communicates bidirectionally over serial with an Arduino Due on Windows 7 (64) with Unity 4.2.1f4 (with .NET 2.0). The Due has a couple LEDs on it, and the Unity project has a couple of lights with switches. The light switches in Unity can turn on and off the LEDs, so Unity sends a message to the Due about the state of the switches. The LEDs can be ripped out of circuit connected to the Due which causes the Due to send a message to Unity that the power source is gone and that the switches should no longer work.

The Due and Unity are both reading and writing to/from the serial. I’m only working with two LEDs at the moment, so the Due and Unity are each only sending a single byte (followed by a newline) which specifies the current state of the switches or the LEDs.

My problem - which caused me endless frustration late at night - was that everything runs fine if Unity is just reading serial messages from the Due, but as soon as Unity starts writing and reading something funny starts happening - Unity can’t read from the serial properly anymore. For example, the Due will be sending a byte containing the number 5, but when Unity reads from the serial, it sees the number 4. I can open up a serial monitor and verify that the byte coming from the Due is, in fact, the number 5. It also doesn’t seem to be a problem with the serial buffer on Unity’s end being backed up, because other numbers - like 7 - will come through just fine. If I stop Unity from writing to the serial, then it will go back to reading properly. I should note here that Unity is sending bytes containing numbers 0-3 to the Due; and the Due is sending bytes containing numbers 4-7 to Unity. So it isn’t a problem with Unity somehow reading the numbers that it is trying to send to the Due.

So after googling for answers, I’m at a bit of a loss and could use a little help. It might be that I’m just doing something excessively silly in my code - it is sort of stitched together from examples that I found on the forum here and elsewhere.

Here’s a variant of the unity code that controls the serial communication - I’ve omitted the non-serial lines. I set up the serial port object using the settings that my Due uses. Then, every frame, I read from the buffer to get the state of the connectedness of the LEDs from the Due. Then I do something hacky when I go to write to the serial from Unity (and this helps mostly fix my communication problems). I will only write the state of the switches if they have changed, and to make the communication more robust, I will keep sending that message for a specified, short duration.

Other notes - the Due is reading/writing to the serial every 30ms. Unity can keep up with that on my machine (or at least I believe it can since I’ll see read timeout messages). I’ve tried raising the speed of the Due to 10ms, and then Unity can’t keep up with it and the serial buffer will be backed up. I’ve also tried lower the speed of the Due, but that didn’t seem to help either. I’ve tried setting up a serial port event for receiving data using this, but it didn’t work, and I gather (from some prior forum posts) that this isn’t properly implemented under mono develop.

At this point, I’m close to just ditching the direct serial communication and going with some intermediary software (build with openFrameworks) that will handle the serial communication properly, and then pass that information into Unity using something like pipes (of which I know next to nothing)…

Anyway, thanks for reading this long post!

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

public class SerialController : MonoBehaviour {
	
	SerialPort serial = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One);
	
	bool hasChanged = false;
	float changeTimer = 0.0f;
	float changedDuration = 0.05f;
	
	...
	

	// Use this for initialization
	void Start () {
		serial.ReadTimeout = 1;
		serial.Open();
		...
	
	}
		
	// Update is called once per frame
	void Update () {	
			
		// Read in the buffer to get the connection state of the LEDs from arduino
		string buffer = serial.ReadLine();
		if (buffer.Length == 1) {
			connectionState = int.Parse(buffer);
		
			// Use the state to update the connection status of the LEDs in the scene
			...
		}
		
		
		// Check if the state of the switches has been changed in Unity
		...
			
		// Write to the serial if something has changed
		if (hasChanged) {
			changeTimer += Time.deltaTime;
			writeStateToSerial(led1On, led2On);
		}
		else if (changeTimer>0) {
			changeTimer += Time.deltaTime;
			if (changeTimer > changedDuration) changeTimer = 0;
			else writeStateToSerial(led1On, led2On);
		}
		
		...
	}
	
	
	void writeStateToSerial(bool led1On, bool led2On) {
		string outByte = "0";
		if (led1On  led2On) outByte = "0";
		else if (led1On  !led2On) outByte = "1";
		else if (!led1On  led2On) outByte = "2";
		else if (!led1On  !led2On) outByte = "3";
		serial.WriteLine(outByte);
	}
}

Well, I couldn’t figure out the weird serial bugs that I was having in unity, so I just moved to using an intermediary piece of software (written in openFrameworks) to handle the communication between arduino and unity (via OSC). I used this project as a basis for my code, and everything works like a charm now :smile: