Reputation: 11
I am a beginner programmer and am currently working on a project with virtual serial ports. This is my first time working with them and I am still learning. Right now, I am just trying to basically create my own version of putty--something where I can just confidently read and write from a port.
I am trying to get force data back from a load cell. They respond to a command set I was given, (like "w" returns weight) and if the command is not recognized it responds with an "E".
A lot of the time my code works--as long as I do not give it a command it does not recognize, it responds as it should. However, once I send a bad command, it will only respond with "E" from there on out, even to correct commands. Closing and re-opening the port within my code has not helped--it still only responds with the "E".
The only way I have been able to "reset" the situation has been to open and close a session in Putty. Then I can get good data from my program again. The load cell responds as it should in Putty 100% of the time, and is able to recover after a bad command.
What could Putty be doing to "reset" the situation, that I am not already doing in my code? I am closing the port... Help!!!
static SerialPort firstSerialPort;
static bool myContinue;
static void Main(string[] args)
{
string message;
Thread readThread = new Thread(Read);
//Initializing a SerialPort object
firstSerialPort = new SerialPort("COM3", 9600, Parity.None,8,StopBits.One);
//Checking if serial ports are initially open
Console.WriteLine("First serial port is open: {0}", firstSerialPort.IsOpen);
//Selecting the properties
firstSerialPort.Handshake = Handshake.XOnXOff;
firstSerialPort.DtrEnable = false;
firstSerialPort.RtsEnable = false;
//Opening the ports
Console.WriteLine("Attempting to open the ports!");
firstSerialPort.Open();
//Clearing the buffers
firstSerialPort.DiscardOutBuffer();
firstSerialPort.DiscardInBuffer();
firstSerialPort.BaseStream.Flush();
myContinue = true;
readThread.Start();
Console.WriteLine("First serial port is open: {0}", firstSerialPort.IsOpen);
Console.WriteLine("Type QUIT to exit"+"\n");
while (myContinue) {
message = Console.ReadLine();
if (message == "QUIT")
{
myContinue= false;
}
else
{
firstSerialPort.WriteLine(message + "\r");
}
}
Console.WriteLine("\n"+ "Attempting to close the ports!");
firstSerialPort.Close();
Console.WriteLine("First serialPort is open: {0}", firstSerialPort.IsOpen);
//Holding console open
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
public static void Read()
{
while (myContinue)
{
while (firstSerialPort.IsOpen)
{
Thread.Sleep(100); //This adds a delay. Commands will not work without this
try
{
//Reading back data
string firstMessage = firstSerialPort.ReadLine();
Console.WriteLine("firstMessage: {0}", firstMessage);
Console.WriteLine();
}
catch (System.IO.IOException error)
{
return;
}
catch (System.InvalidOperationException error)
{
return;
}
}
}
}
Upvotes: 1
Views: 450
Reputation: 2053
I've written a few terminal programs, similar to putty and hyperterminal. To elaborate on my comment, here is some code to help:
My forum has a Keypress event, in which I take whatever key was pressed and write it to the serialport. Note that this is just a simple example, but should get you going in the right direction:
public const int WM_VSCROLL = 0x0115;
public const int SB_BOTTOM = 7;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
try
{
//scroll terminal to latest char
richTextBoxConsole.SelectionStart = richTextBoxConsole.Text.Length;
SendMessage(richTextBoxConsole.Handle, WM_VSCROLL, SB_BOTTOM, 0);
//Send character to port
serialPort1.Write(e.KeyChar.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Here is my datarecieved event:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string data = serialPort1.ReadExisting();
//DataReceived event is on it's own thread, need to invoke to update the UI
this.Invoke((MethodInvoker)delegate
{
foreach (char c in data)
{
richTextBoxConsole.AppendText(c + "");
if (c == '\b')
{
//backspace, erase a char
richTextBoxConsole.Text = richTextBoxConsole.Text.Substring(0, richTextBoxConsole.Text.Length - 2);
}
}
richTextBoxConsole.SelectionStart = richTextBoxConsole.Text.Length;
SendMessage(richTextBoxConsole.Handle, WM_VSCROLL, SB_BOTTOM, 0);
});
}
Upvotes: 1