In my handler for receiving data over the serial port, when data is received I store it to a string and do a .contains search to determine if something needs to be done with the data. When the application is sitting idle and the (lets call it a modem) sends something like “Connected” it works fine.
The problem is when I poll the machine. When I initiate a command that expects return results It does not work and I cant figure out why. Now If I start the function with a Message Box it will work. I would rather not have an unnecessary Message Box.
Here is a sample of my code.
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
if (this.InvokeRequired)
{
RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
Invoke(d);
}
else
{
RefreshTextBoxResults();
}
}
private void RefreshTextBoxResults()
{
//MessageBox.Show("refresh text is occurring");
indata1 = serialPort1.ReadExisting();
rx.AppendText(indata1);
string dataCheck = indata1.ToUpper();
//MessageBox.Show(dataCheck);
if (indata1.ToUpper().Contains("CONNECT"))//dataCheck.Contains("CONNECT"))
{
// MessageBox.Show("connect");
cState.Text = "Connected";
if(connected==false)
connectLink();
}
if (dataCheck.Contains("CONNECTED"))
{
// MessageBox.Show("Active Call in Session");
cState.Text = "Connected";
if (connected==false)
connectLink();
}
if (dataCheck.Contains("NO"))
{
cState.Text = "Disconnected";
disconnect();
}
if (dataCheck.Contains("CAMPOS"))
{
campos = indata1;
camDat = true;
}
}
private void cState_Click(object sender, EventArgs e)
{
writeDevice("callstatus");
}
public void writeDevice(string cmd)
{
try
{
{
serialPort1.Write(cmd + "\r\n");
}
}
catch
{ noconnect(); }
}
When I execute cstate() it should return the call status and type if any. The modem does respond as I can see it in my prompt box. If the word connected is anywhere in there It should change a label’s text to say “Connected”. As the code sits, nothing happens to that label. But, if I remove the comment on the first line in RefreshTextBoxResults() making that MessageBox active, it detects the status of the modem.
I just don’t see what is going on. Can someone explain to me why this is happening?
That’s the key phrase. The issue is that you use ReadExisting(). Serial ports are very slow, your DataReceived event handler will typically only get one or two characters. By displaying the message box, you slow it down. That allows the serial port driver to read more characters. Enough for ReadExisting to read the entire “Connected” string instead of just “C” or “Co”.
Hard to diagnose too when you use a debugger, single stepping the code also slows it down enough to allow the port to get enough characters.
What you need to do is process the response only after you got the entire response string. That’s always easy with a modem, just use ReadLine() instead of ReadExisting(). You may have to tweak the value of the NewLine property.