I've coin machine acceptor set and I wanna connect this machine using serialport. My main problem is, I did try almost every setting to connect that machine. The pin numbers are written on the cable as 3th and 7th. So I try
private void Form1_Load(object sender, EventArgs e)
{
// SerialPort paraPort defined at designer's generated code
paraport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
//I wanna access to windows controls from the thread
System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;
}
private void button2_Click(object sender, EventArgs e)
{
//paraPort is the name of serialport class
paraPort.ReadBufferSize = 1024;
paraPort.WriteBufferSize = 1024;
paraPort.ReadTimeout = 1000;
paraPort.WriteTimeout = 1000;
paraPort.NewLine = "\n";
//Because 7th pin is for RTS which means request 2 send
paraPort.Handshake = Handshake.RequestToSend;
//Data Terminal Ready Enable
paraPort.DtrEnable = true;
paraPort.RtsEnable = true;
paraPort.Open();
//Then Thread check the procedure inside of try - catch block
try{
// Thread money defined at designer's generated code
money = new Thread(new ThreadStart(CheckTheMachineState));
money.Start();
}catch(Exception e){
MessageBox.Show("thread cannot be created"+e.Message);
}
}
private void CheckTheMachineState()
{
richTextBox1.AppendText("Thread is running\n");
//I wanna get the value of IOCTL_SERIAL_WAIT_ON_MASK
//But I still don't know how
}
}
The machine is working well. But when I use paraPort.ReadBufferSize property, it gives me 0 when the coin accept :S. When I use the paraPort.Read method it throws an timeout exception :\
So What can I do for this stuff ? I'm using portmon tools to catch the coin machine signal.
IOCTL_SERIAL_WAIT_ON_MASK value is changed as SUCESS when I put the coin. How can I catch this value ?
After several days of work, I have figured out how to connect a coin acceptor/validator machine to a PC via serial port using VB6, such that every coin inserted in the slot will trigger a signal that will be caught by the PC.
Related
this is my first question on here, since I couldn't find it answered anywhere.
I am not particularly new to WPF and C#, but I've never read SerialData with it before, and I'm having rudimentary problems I'm sure.
Setup:
Arduino clone (SparkFun Pro Micro) sending "Hello!" + a number to the USB serial port (COM5) once every second:
String hello = "hello!";
Serial.println(hello + i);
i++;
delay(1000);
And trying to receive it in WPF, with a simple button that refreshes the data to a TextBlock (tbData).
SerialPort sp = null;
String str = null;
int i = 0;
public MainWindow()
{
InitializeComponent();
sp = new SerialPort("COM5", 9600);
sp.DataReceived += new SerialDataReceivedEventHandler(ReceiveData);
sp.Open();
}
void ReceiveData(object sender, SerialDataReceivedEventArgs e)
{
str = sp.ReadLine();
}
private void Refresh_Click(object sender, RoutedEventArgs e)
{
tbData.Text = str;
}
But nothing happens, I seem to be getting an empty string, since the TextBlock doesn't show anything when I press the Refresh_Click button.
I can get it to work with a new Thread, but it keeps timeouting, and I read on here (Timeouts in C# serial port) that the best (and simplest it seems) method is using a SerialDataReceived event.
t = new Thread(() =>
{
int i = 0;
while (run)
{
SerialString = sp.ReadLine();
Thread.Sleep(1000);
}
sp.Close();
});
What I am missing must be something along the lines of changing the size of the buffer? Or something similar?
It seems I've found the answer!
I am pretty clueless about Serial communications, but today I came across the MODE cmd function:
C:\Users\Username>mode
Status for device COM5:
-----------------------
Baud: 9600
Parity: None
Data Bits: 8
Stop Bits: 1
Timeout: ON
XON/XOFF: OFF
CTS handshaking: OFF
DSR handshaking: OFF
DSR sensitivity: OFF
DTR circuit: OFF
RTS circuit: OFF
And I noticed that it changed whenever I had the Arduino IDE report the data to me - which it would always do successfully! - and whenever I tried to make WPF do the same.
Above is the MODE return after I tried to run my own code, and:
Status for device COM5:
-----------------------
Baud: 9600
Parity: None
Data Bits: 8
Stop Bits: 1
Timeout: OFF
XON/XOFF: OFF
CTS handshaking: OFF
DSR handshaking: OFF
DSR sensitivity: OFF
DTR circuit: ON
RTS circuit: ON
this is what it showed after opening Tools>Serial monitor in the Arduino IDE, and closing it again immediately.
I changed my WPF code from:
sp = new SerialPort("COM5", 9600);
sp.Open();
to:
sp = new SerialPort("COM5", 9600);
//sp.ReadTimeout = 200;
sp.DtrEnable = true;
sp.RtsEnable = true;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.Open();
And now both the threading example and the SerialDataReceived event runs smoothly (well, except I can't update a UI thread within a SerialDataReceived thread).
I hope someone out there finds this useful.
I am new to C# and am looking for some advice on an issue I have been trying to solve in my Windows Form application.
I have an application that needs to continuously read data coming back to the program over a connected serial port. I have buttons that Open and Close the port via the user. I am having trouble configuring the "DataReceived" event handler to read the incoming data and display it in a textbox in the app.
I have been getting this error: "Cross-thread operation not valid: Control 'textBox4' accessed from a thread other than the thread it was created on." I see this is a thread error but I have not been able to figure out my issue.
namespace Program
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
getAvailabePorts();
}
private void getAvailabePorts()
{
String[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
}
public void button1_Click(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || comboBox2.Text == "")
{
textBox4.Text = "Please select port settings";
}
else
{
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived);
serialPort1.Open();
}
}
catch (UnauthorizedAccessException)
{
textBox4.Text = "Unauthorized Access";
}
public void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
textBox4.Text = sp.ReadExisting() + "\n";
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Close();
textBox4.Clear();
}
}
}
}
First, welcome.
Before the "big" issue (marshalling data), let me warn you -- serial ports are tricky. For example, your call to "ReadExisting" may not return what you expect -- will return whatever is in the serial port buffer at the time, but more may come in, which will overwrite what is already in your text box. So you may want to append data your text box.
Now the real issue. As a commentor mentioned, you cannot post directly post data from another thread to the UI thread. Without you knowing, the serial port created a new thread to receive data.
You can handle this directly by modifying your receiver code as follows:
public void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort) sender;
var dataRcvd = sp.ReadExisting();
object[] dataArray = new object[1];
dataArray[0] = dataRcvd;
BeginInvoke( new postDataDelegate( postData), dataArray );
}
private delegate void postDataDelegate( string d );
private void postData( string d)
{
textBox4.Text = d;
}
This will "marshall" the data to the UI thread so it can be used. There are many ways this can be done (and, many differences between how it is done in WPF vs. Winforms, so watch out for that). I hope this illustrates the point.
Another aside -- no need ot make the DataReceived method public -- it will work fine private.
I'm new to the Arduino and serial communication, and I haven't coded in a while, but I'm trying to do what I think should be fairly simple, and have been having plenty of trouble. What I'd like to do is to create a simple GUI on Windows Forms and control a Arduino. I keep seeming to run into different problems every new session.
What I've been trying to do is to create a simple GUI that can toggle an LED on and off, and then to use NumericUpDown to toggle it blinking. Previously, I could get the numericUpDown to toggle values but nothing happens, now if I try and toggle, it tells me the port is closed. I've been trying different port communication methods. Since the Form is saying my port is closed, I cannot test to see if what I've written works. Please ignore the commented code as I'm still trying different things.
When I try to call the blink function, it hasn't blinked properly inside a if statement compared to if I kept it in the loop. I'm not sure how and where to send the value from the Winform to the Arduino.
Is Winform much different than using serial monitor commands?
EDIT1: I stepped away from my computer and now when I run the Windows Form, it shows no errors but The program has exited with code 0 (0x0). I've had the timer and haven't really messed with it yet but it wasn't telling me this error earlier and was running the form fine.
My Arduino Code:
// Define Function Prototypes that use User Types below here or use a .h file
int dorun;
int Blinks;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
getBlinks();
}
// the loop function runs over and over again forever
void loop()
{
if (Serial.available() > 0)
/*
{
byte Blinktimes = Serial.readBytes[];
}
*/
{
String serialInput = Serial.readString();
//Toggle LED
if (serialInput == "On")
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); //I have this just to see that the LED is staying on and off, and will need to change things.
for (int x = 1; x = Blinks; x++)
{
blink();
}
}
else
{
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (LOW is the voltage level)
}
Serial.flush(); //Clear Serial
}
/*
digitalWrite(LED_BUILTIN, HIGH);
if ((Serial.available()))
{
int dorun = Serial.read();
if (dorun = 1)
{
blink();
}
else
{
digitalWrite(LED_BUILTIN, LOW);
}
}
*/
/*turnon();
if (dorun == 1)
{
blink();
}
else
{
digitalWrite(LED_BUILTIN, LOW);
}
*/
}
void getBlinks()
{
byte message[3];
if (Serial.available())
{
Serial.readBytes(message, 3);
Blinks = message[3];
}
}
void blink()
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the
voltage level)
delay(250); // wait for a second
digitalWrite(LED_BUILTIN, LOW); //!digitalRead(LED_BUILTIN); // turn the LED off by making the voltage LOW
delay(1000);
}
void turnon()
{
if (Serial.available()> 0)
{
String run = Serial.readString();
if (run == "Run")
{
dorun == 1;
}
if (run == "Off")
{
dorun == 0;
}
}
}
My Windows Form Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace WindowsFormsApp9
{
public partial class Form1 : Form
{
SerialPort serial; // create serial port
/*
* public class Port
{
public string Name { get; set; }
public int Value { get; set; }
public Port(string n, int i)
{
Name = n;
Value = i;
}
}
*/
SerialPort port;
string[] availablePorts = SerialPort.GetPortNames();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("On");
port.Close();
}
private void button2_Click(object sender, EventArgs e)
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Off");
port.Close();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
UpdateBlink();
}
void UpdateBlink()
{
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
const byte messageType = 2;
byte Blinkcount = (byte)numericUpDown1.Value;
byte[] serialBlink = { messageType, Blinkcount };
serialPort1.Write(serialBlink, 0, serialBlink.Length);
port.Close();
}
private void timer1_Tick(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
}
I've been checking out these links:
Click here How I toggle the LED
Click here How to return an int since NumericUpDown returns a decimal
Click [here] (https://www.instructables.com/id/Arduino-Visual-Studio-Serial-Communication/) Arduino Visual Studio Serial communication timer things
Click [here] (https://www.instructables.com/id/Communication-From-a-WinForms-to-a-TinyDuino/) instructions about Winforms to TinyDuino, They should use similar commands as the Arduino right?
So I decided to do a slight overhaul. Instead of trying to deal with sending multiple different types of inputs(String and int) I have decided to just change everything into a byte array and then send it all at once.
Regarding 1. I was really just wondering if it'd be alright to create a function to return a value rather than just building the code in a void function. So I tried it and it worked, hence the change. From what I understood and saw that your protected override bool ProcessCmdKey, basically you wanted to see if the key was an arrow key. If it was return true. So what I did was basically if it's one of the selected colors, return a value corresponding to the color.
I was just hoping you could either help me understand the Serial and COM port connection or if you had a link for more explanation. Earlier when I was trying to send a string(On/Off) and then send a numeric(byte/int) to set a number of blink times, I couldn't figure out if the COM port is kind of like a singular channel. If I'm sending a string from the Windows Form, could I send out a int/byte in the same channel? Now that everything is of one keyword (byte) I can just create a byte array and figure out the communication between the Windows Form and Arduino. I'm a little confused about the underlying Serial aspect. When I saw your code I started to think a little differently.
In your code, if I'm understanding it properly, it seems that MyVCOM is how to communicate back and forth, just like port.Write. I believe it's singular as it's basically like the old telephone line, if I'm on a call, and you call try to call me, your call is blocked since my line is already being used.
So in your ConnReset, you want to make sure the COM's aren't open so you can set up communication. So your ConReset will clear the line if it's open already. What I'm confused about is the else part. If your port isn't open, open COM+PortNumber, so basically open the channel so you can communicate, but you declared port number to be 8, so shouldn't you just use:
MyVCOM.PortName = "COM8";
Where does the user select which COM? All of the communication is being done on COM8 isn't it? Or does is that part all part of a built in library? I believe all I need to do now is to send my byte array to my Arduino and then work on the Back End to take the data the Windows Form is sending.
public int Colorselection(string label3, int color) //Toggle a pin
{
if (label3 == "Red")
{
color = 6;
}
else if (label3 == "Green")
{
color = 5;
}
else if (label3 == "Blue")
{
color = 3;
}
return color;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
String label4 = LEDColor.SelectedItem.ToString(); //Generate A string of selected Color
int xled = Colorselection(label4, color); //Toggle the string into an int
LEDLabel.Text = xled.ToString(); //Generate a string from the int
}
private void Run_Click(object sender, EventArgs e) //Generate byte to send instead of sending strings and int/byte
{
byte RGBLED = Convert.ToByte(color);
byte BlinkNum = Convert.ToByte(number1.Value);
byte BlinkDur = Convert.ToByte(number2.Value);
byte[] array2 = new byte[] { RGBLED, BlinkNum, BlinkDur };
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
/*
port.Open();
port.Write(array2, 0, 2);
port.Close();
*/
}
Your WinForms application assumes that your Arduino is connected to COM3. Do you know if that's actually the case, or is that sample code that you just copy and pasted? (Check the Windows Device Manager under COM ports to see what ports are available, then unplug/plug your device to see which port it's being mapped to)
Besides that, have you tried debugging your Arduino code on target to see what, if anything, is actually being received?
From the MS documentation, it's not clear how the SerialPort.Write command works exactly in terms of synchronization, so it may not be a great idea to close the port immediately after sending your command. Unfortunately, since I'm not in possession of an Arduino I can't test your code. But I did create a WinForms GUI to accomplish essentially the same task (and more that you probably don't need) several years ago that I've since posted to github (https://github.com/mbhul/RoboCOM). Let me know if that helps, otherwise please tell us more about your development environment.
I have one device "installed" on a users desk (a desk is nothing but a chair or table on which user will sit), and I will be supporting thousands of desks.
A user will have one "chip" and the user will scan this chip on the device which is installed on their desk.
The device will read the data off the chip and will send it to my laptop which will also have one of the devices installed, except this device is the main device responsible for collecting all user scan chip data.
All the data will be routed to my device via a wifi router and I will listen to this from my Main device and read data from this device from my laptop via serial port connection.
This data sending will happen as each user number scans his/her chip.
I have created a windows form application which will continuously run in the background on my laptop, and will be listening to my serial port on which main device is connected.
This is my code taken from here: Source Code Reference:
public partial class MainUI : Form
{
SerialPortManager _spManager;
public MainUI()
{
InitializeComponent();
UserInitialization();
}
}
private void UserInitialization()
{
_spManager = new SerialPortManager();
_spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved);
this.FormClosing += new FormClosingEventHandler(MainUI_FormClosing);
}
private void MainUI_Load(object sender, EventArgs e)
{
_spManager.StartListening()
}
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int dataLength = _serialPort.BytesToRead;
byte[] data = new byte[dataLength];
int nbrDataRead = _serialPort.Read(data, 0, dataLength);
if (nbrDataRead == 0)
return;
// Send data to whom ever interested
if (NewSerialDataRecieved != null)
{
NewSerialDataRecieved(this, new SerialDataEventArgs(data));
}
}
void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
if (this.InvokeRequired)
{
// Using this.Invoke causes deadlock when closing serial port, and BeginInvoke is good practice anyway.
this.BeginInvoke(new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved), new object[] { sender, e });
return;
}
//data is converted to text
string str = Encoding.ASCII.GetString(e.Data);
if (!string.IsNullOrEmpty(str))
{
//Here i will store that data in to my database through web service.
//What i should use whether WCF service or Web Api because data will be continuos like at a
//time more than 10 or 100 user can scan data at the same time so this event will be fired continuously.
//I am using entity framework to store data in to my database and how to ansynchornously call web service to store my data
//so that my call doesnt block incoming data to serial port
}
}
My main concern is I will have numerous users who will scan data at the same time and how I will handle when more than 10 or 100 user scan the data at the same time.
How can I mitigate this potential issue?
Ok, if i got the question right you need to do something like this ...
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int dataLength = _serialPort.BytesToRead;
byte[] data = new byte[dataLength];
int nbrDataRead = _serialPort.Read(data, 0, dataLength);
if (nbrDataRead == 0)
return;
// Send data to api
string str = Encoding.ASCII.GetString(e.Data);
if (!string.IsNullOrEmpty(str))
{
var api = new HttpClient();
api.BaseUrl("http://somewhere.com");
api.PostAsJsonAsync("api/Something", str)
}
if (this.InvokeRequired)
{
// Using this.Invoke causes deadlock when closing serial port,
// and BeginInvoke is good practice anyway.
this.BeginInvoke(new EventHandler<SerialDataEventArgs>(
_spManager_NewSerialDataRecieved), new object[] { sender, e
});
return;
}
}
// i think this can go completely ...
void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
That posts the data to webapi but whilst that post is taking place on another thread the serial port can carry on receiving data
close your serial port and load every some-amount-of-time. After that some-amount-of-time open the port and scan all devices, then close it again.
public void MainUI.Load(Object sender, Eventargs e)
{
if (_spmanager != null && !_spManager.IsOpen)
//*write the code here where it opens and starts listening
_spmanager.StartListening();
//*write the code here where it waits a little bit then
_spmanager.Close();
}
Therefore everytime it loads it starts when the port is closed, it opens for a little bit, scans whatever values are true and then closes again.
I am not very sure about this but it is just an idea of how to handle it. The code might not be accurate or currect I just wrote it quickly. Take the idea from this
Life status of device connected via serial port.
Hello everyone.
How can I check if the device responds to the request? I'm googling this for couple days and tried lot of solutions also from SO, but nothing gave me results that I've expected. After lot of tries I'm in point described below. I think I'm very close but now I need little help, so thanks for every answer in advance.
The current situation
What am I doing right now is very simple. First of all I'm opening serial port serialPort.Open() at very beggining of app (data is receiving almost all the application running time).
As this is just an example in my form is only one label called labelStatus and labelStatus.Text = "Not connected"
Next I'm adding a timer and it's tick method, that contains execute of serialPort.Write(). Timer Interval is set to 100 if that matters.
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
}
Next step is create DataReceived event like below (very simplified version, in my app received data is parsing to floats and storing in array, but it's just to show the problem)
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
One last thing is create ErrorReceived method.
private void serialPort_ErrorReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
}
Untill now everything works brilliant. Sending data works. DataReceived event is executig each 100 miliseconds when data is send. My data is received properly with no problems. When I start application labelStatus text is "Not connected" (device cable is not plugged in). When I plugged in device labelStatus text changing to "Connected". But now when I plugged of cable ErrorReceived event is not executing and labelStatus text is still "Connected". So as I've asked before: How can I check is device still connected to computer? (Or maybe: how to execute ErrorReceived event, when data is not receiving?).
Note: Serial port ReadTimeout is set to 300 miliseconds.
What have I tried
I've tried lot of things but this one in my head seems to should work but doesn't.
I've modified DataReceived event and I've put serialPort.ReadLine() into try/catch block with TimeoutException where I've tried to manually execute ErrorReceived method like below
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
catch (TimeoutException)
{
serialPort_ErrorReceived(null, null);
}
}
I was hoping that will work like I want.
BTW. Sorry for my English. It's not perfect, but I do my best. Cheers!
Listen to the WM_DEVICECHANGE event that will be fired when a device is removed or inserted.
Here is an example of a implementation and some more information:
Detect serial port insertion/removal
http://www.codemiles.com/download/file.php?id=719 (USB Sample)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363480(v=vs.85).aspx
This is solution in my case
Regarding to Martjin's answer i need to further explain my situation. First of all I want to say that I'm not installing any hardware into my computer, so in my opinion WM_DEVICECHANGE event was not what i need (but of course thanks for information, I've learned something new). Application is reading data from scale. Scale after plug into com port is not sending any data and actually there's no communication between it and computer at all. The only way to read data is to send request to scale, so I have to rely on that.
First try
The plan:
Add two static int fields (flags) checkOld and checkNew,
increment checkNew in DataReceived, check in timer Tick method
is checkOld is equal to checkNew. If true that means checkNew
was not increment, and that means DataReceived was not executed.
`
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
checkNew++;
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
if (checkOld == checkNew)
{
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
}
}
`
The plan was good but when I've tested it result was not even good. What happened? Actually device status was blinking connected-not connected-connected-not connected etc. I've wrote some data to output and get answer. The timer was looping so fast that DataReceived event could not always increment checkNew value.
Final solution
Based on what I had at the moment I've decided to add some little changes. Instead of comparing two integers values try to collect couple last values ad check if all were the sem or not.
The plan:
Add three static fields: first six elements array of integers
statusArray, second integer index with value equals to 6 (last
element of array + 1), third integer checkNew,
increment checkNew in
DataReceived event,
in timer Tick event fill array to index,
decrement index value untill whole array is filled, and if index == 0 reset index value to
6,
and last check if last six values of checkNew, stored in
statusArray are the same. If true that means DataReceived did not
executed six times in a row, and now I can be sure that connection is
lost.
`
static int index = 6;
static int checkNew = 0;
static int[] statusArray = {0,0,0,0,0,0};
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
checkNew++;
string someVariable = serialPort.ReadLine();
labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
//If i received something that means the device is plugged in and connection is correct (still very simplified)
}
private void timer_Tick(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
}
if (index == 0)
index = 6;
index--;
int value = statusArray[index] = checkNew;
}
`