I got a C# WPF application wich communcates with my arduino uno over serial port. Everything works fine for 3 to 20 seconds then i can not send or receive anything from/to the arduino.
What im trying to archieve: Connected a arduino uno to an optical sensor of a mouse to read from its registers, now i want to process the data on my pc.
I tried using another arduino uno and also some other mouse optical sensor, wich did not change anything.
Opening and closing the serialport after each communication did not work for me.
I have seen a few questions here on stack exchange, i looked through everyone but they could not help me.
Serial.flush()
seems to be not working, or its some kind of overflow i cant figure out.
I would really appreciate it if someone could explain me what the root of this problem is.
For completeness, here is my C# code:
public class SerialCommunication
{
public SerialPort serialPort = new SerialPort();
public SerialCommunication()
{
string[] ports = SerialPort.GetPortNames();
if (ports.Count() == 1)
{
MessageBox.Show("No serialport is available");
return;
}
serialPort.PortName = ports[1];
serialPort.BaudRate = 115200;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.Handshake = Handshake.None;
serialPort.StopBits = StopBits.One;
serialPort.NewLine = "\r\n";
serialPort.WriteTimeout = 2000;
serialPort.ReadTimeout = -1;
serialPort.Open();
}
}
public partial class MainWindow : Window
{
public static readonly object _lock = new object();
private SerialCommunication serialCommunication = new SerialCommunication();
public MainWindow()
{
InitializeComponent();
GetWindow(this).KeyDown += HandelKeyDown;
serialCommunication.serialPort.DataReceived += (sender, args) =>
{
string bufferstring = ((SerialPort)sender).ReadLine();
OnMessageReceived(bufferstring);
//serialCommunication.serialPort.DiscardOutBuffer();
//serialCommunication.serialPort.DiscardInBuffer();
//Thread.Sleep(3);
//byte[] buffer = new byte[15];
//((SerialPort)sender).Read(buffer, 0, buffer.Length);
//string bufferstring = Encoding.UTF8.GetString(buffer);
};
serialCommunication.serialPort.WriteLine("OK");
}
private void OnMessageReceived(string message)
{
if (message.Length != 15 || message.Contains('O') || message.Contains('K') || message.Contains('\n') || message.Contains('\r'))
{
serialCommunication.serialPort.DiscardInBuffer();
serialCommunication.serialPort.DiscardOutBuffer();
serialCommunication.serialPort.WriteLine("OK");
return;
}
//Format: "y: 0x%02X,x: 0x%02X"
string x = message.Substring(3, 4);
string y = message.Substring(11, 4);
int offsetX = (Convert.ToInt32(x, 16) - 128);
int offsetY = (Convert.ToInt32(y, 16) - 128);
// the next three lines only visualize the received data but do not change it
MoveX(offsetX / 50);
MoveY(offsetY / 50);
ShowMessage(message);
Thread.Sleep(2);
serialCommunication.serialPort.WriteLine("OK");
}
}
Foto of how the application and data it receives look like:
Here is my arduino code:
#include <Arduino.h>
// 5v
#define POWER 13
// Serial I/O
#define SDIO 11
// Serial clock
#define SCK 12
// Registers
#define DELTAY 0x02
#define DELTAX 0x03
#define serialInputBufferSize 16
char dataBuffer[serialInputBufferSize];
unsigned short inputBufferLength = 0;
bool sendPosition = true;
char tmp[16];
void InitMouse()
{
digitalWrite(SCK, HIGH);
delayMicroseconds(5);
digitalWrite(SCK, LOW);
delayMicroseconds(1);
digitalWrite(SCK, HIGH);
// Wait for the serial transaction timer to time out:
delay(1000);
}
byte readRegister(byte addr)
{
byte r = 0;
// Set the dataline to output
pinMode(SDIO, OUTPUT);
for (int i = 7; i >= 0; i--)
{
digitalWrite(SCK, LOW);
digitalWrite(SDIO, addr & (1 << i));
digitalWrite(SCK, HIGH);
}
// Switch the dataline from output to input
pinMode(SDIO, INPUT);
// The datasheet mentions to wait at least 100 µsec
// when switching from write to read operations.
// This is needed for the chip to prepare the data
delayMicroseconds(110);
// Clock trough the register and read its data
for (int i = 7; i >= 0; i--)
{
digitalWrite(SCK, LOW);
digitalWrite(SCK, HIGH);
r |= (digitalRead(SDIO) << i);
}
// Delay at the end guarantees >100 µsec before next transaction
delayMicroseconds(110);
return r;
}
byte y = 0;
byte x = 0;
void WaitForMovementThenSendPositionOffset()
{
x = 0;
y = 0;
while (((y == 0 && x == 0) || x == NULL || y == NULL) && sendPosition)
{
delay(1); // kann eigentlich weg
y = readRegister(DELTAY);
x = readRegister(DELTAX);
}
if (sprintf(tmp, "y: 0x%02X,x: 0x%02X", y, x) > 0)
{
tmp[16] = 0;
if (!Serial.println(tmp))
{
// Serial.end();
// Serial.begin(9600);
// Serial.begin(115200);
Serial.flush();
}
sendPosition = false;
}
}
void serialEvent()
{
sendPosition = false;
// Read serial data into the buffer
while (Serial.available())
{
dataBuffer[inputBufferLength++] = Serial.read();
}
Serial.flush();
if (strstr(dataBuffer, "OK"))
{
sendPosition = true;
WaitForMovementThenSendPositionOffset();
}
}
void setup()
{
pinMode(SCK, OUTPUT);
pinMode(SDIO, INPUT);
pinMode(POWER, OUTPUT);
digitalWrite(POWER, HIGH);
Serial.setTimeout(1000);
// Serial.begin(9600);
Serial.begin(115200);
InitMouse();
}
void loop()
{
}