Hi all,
I am using C# 2010, Windows 7 and an Arduino Nano CH340G (serial USB interface) as a serial data source.
The Arduino is configured such that when I send it an asterisk it will respond with a plus sign. This code works and I tested it using the Arduino IDE Serial monitor and Putty.
In the form load event of the Windows Forms app I get a list of comm ports and then I traverse this list looking for the one corresponding to the Arduino test device. The odd behavior that I am experiencing is that when I first connect the serial device and run my app the program does not detect the Arduino. However, if I run the app again it locates it without any problems.
I got it to work by "polling" the comm port twice. The first time around it fails; the second time around it succeeds. Here is the working C# code:
private void frmMain_Load(object sender, EventArgs e)
{
int iCboIdx;
int iLoop = 0;
//Get serial ports into list.
List<String> lsPorts = new List<String>(System.IO.Ports.SerialPort.GetPortNames());
lsPorts.Sort();
foreach (string sPort in lsPorts){
//Add the COM id to the dropdown list, get the list index.
iCboIdx = cboPort.Items.Add(sPort);
//Test whether the Arduino reader is connected to this port. Return True if so
//or False if not.
iLoop = 0;
//I need to do this loop because for some unknown reason the software does not locate
//the reader on the first attempt right after the reader has been connected to the PC.
//It always seems to work on the second attempt though.
do
if (comTest4Reader(sPort))
{
//Yes, set selected index for this item.
cboPort.SelectedIndex = iCboIdx;
lblStatus.Text = "Reader found on " + sPort;
break;
}
else
{
iLoop++;
Thread.Sleep(500);
}
while(iLoop<2);
}
}
I found that this code does not work if the Sleep statement is removed or too low. This gives me a suspicion that the issue is time based, but I am unable to see how.
The C# code for the function follows:
Boolean comTest4Reader(string sCOMPort)
{
//Routine that tests to see whether the COM port corresponds to the Arduino Reader.
//Use a local serial port object.
SerialPort serRdr = new SerialPort(sCOMPort, 9600);
try
{
if (!serRdr.IsOpen)
{
string sRetMsg = "";
serRdr.ReadTimeout = 1000;
//bad serRdr.DtrEnable = true;
serRdr.Open();
serRdr.Write("*");
Thread.Sleep(1000);
if (serRdr.BytesToRead > 0)
{
byte[] buffer = new byte[3];
// There is no accurate method for checking how many bytes are read
// unless you check the return from the Read method.
int iBytesRead = serRdr.Read(buffer, 0, buffer.Length);
sRetMsg = System.Text.Encoding.Default.GetString(buffer);
}
serRdr.Close();
return sRetMsg.Contains("+");
}
else
{
//Port already open, can't do test.
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
I can't seem to figure out what effect the above function has on the serial port leaving it functional on the second run. Before putting in the loop I would simply run the app, let it fail, exit and run it again, succeeding on the second try. It seems it initializes the serial port in some way that I am not able to determine. I will be testing with a different Arduino just to discard the possibility of it being the CH340G serial/USB interface. I can also test it on a different computer.
I am aware of the issue surrounding this USB/serial interface chip, but so far have been able to make this Arduino (technically it is called a DCcduino) work with the Ardiuno IDE and aside from this odd glitch the app works fine.
Has any one experienced this behavior? Any suggestions on what sort of initialization procedure I can follow with each comm port? I would like to remove the loop that performs each test twice as this slows down the start of the app. Thanks all for your help and orientation. Saga