Hello,
For a project I am using an Arduino UNO with three RS422 shields on top of it. I use this arduino (and shields) for reading the output of an differential quadrature encoder. The generated data is sent from the arduino to a .NET application (C#) by the USB cable/serial port.
This all works fine when I use the Serial.print function to send the encoder value as a string to the serial port.
But this printing takes too much time, and is not very stable in time consuming. So I would like to use the serial.write function. This one is faster and is very stable.
But now a problem occured. There is an enourmous delay now (10-15 seconds) before the data is read in the .NET application.
I assume that this has to do with the fact that I use a volatile variable as encoder value, because the encoder value is changed in a intterupt function. I think that the value is changing while it is being written.
When I send a random long value to the serial port, there is no delay. When I add a delay after the writing of 10 ms there is also no big delay (it is when I use less than 10 ms delay). But that is far too much delay. The data has to be send as soon as possible.
Does anyone know how this delay occurs and are there solutions to fix this?
Here below the arduino code (the encoder_position is changing in the two interrupt functions):
#define encoder0PinA 3
#define encoder0PinB 2
volatile unsigned long encoder_position = 0;
void setup() {
pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
attachInterrupt(0, doEncoderA, CHANGE);
attachInterrupt(1, doEncoderB, CHANGE);
Serial.begin (115200);
Serial.setTimeout(0);
}
void loop(){
Serial.write((byte*)&encoder_position,4);
}
This is my C# code for reading the data:
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Port.IsOpen)
{
byte[] data = new byte[Port.BytesToRead];
Port.Read(data, 0, data.Length);
data.ToList().ForEach(b => recievedData.Enqueue(b));
processData();
}
}
private void processData()
{
if (recievedData.Count >= 4)
{
var packet = Enumerable.Range(0, 4).Select(i => recievedData.Dequeue());
UInt32 pos = BitConverter.ToUInt32(packet.ToArray(), 0);
Pulse = pos.ToString();
}
}