I have been trying to establish a serial port communication in C#. I see, that the event handler for reading data doesnt get fired. The initial strings are the format in which i need to send the data to a register( for eg 0000 reg gets the value of 1180).
Please let me know if i am missing something here.
PS: Just a beginner.
class Program
{
static SerialPort _serialPort;
public static void Main()
{
string phyad = "17";
string regad = "0000";
string value = "1180";
string readad = phyad + regad + "=" + "/";
string combo = phyad + regad + value + "=" + "/";
_serialPort = new SerialPort();
_serialPort.PortName = "COM4";
_serialPort.BaudRate = 9600;
_serialPort.Parity = Parity.None;
_serialPort.DataBits = 8;
_serialPort.StopBits = StopBits.One;
_serialPort.Handshake = Handshake.None;
_serialPort.Open();
_serialPort.DtrEnable = true;
_serialPort.RtsEnable = true;
byte[] data = Encoding.ASCII.GetBytes(combo);
_serialPort.Write(data, 0, data.Length);
_serialPort.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler);
}
private static void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(_serialPort.ReadExisting());
}
}
Related
EDIT: Okay, so I've moved on and made a fully working console app:
public static void Main(string[] args)
{
SerialPort mySerialPort = new SerialPort("COM4");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine($"Data Received: {indata}");
indata = "";
}
Now the problem is that when I try to do something similar in the UWP app -
public void InitScanner()
{
SerialPort mySerialPort = new SerialPort("COM4")
{
BaudRate = 9600,
Parity = Parity.None,
StopBits = StopBits.One,
DataBits = 8,
Handshake = Handshake.None,
RtsEnable = true
};
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
tBlock_spState.Text = mySerialPort.IsOpen.ToString();
}
void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
tBlock_test.Text = indata;
}
public MainPage()
{
this.InitializeComponent();
InitScanner();
}
It throws an System.IO.IOException with description "Too many posts on a semaphore" (sorry for the translation, I am using VS with Czech language). Does anyone know the reason why is this happening? Once again, can't find anything anywhere.
So, I've got a task to write a code, which could allow to read data from a barcode scanner that does not act like a keyboard and write it to a textbox. My thought was that it could be possible via System.IO.Ports.SerialPort class, but I have absolutely no idea how to make it work as it should. I am working on this in an UWP. I've tried this so far
SerialPort sp = new SerialPort("COM4", 9600);
void MethodName()
{
string s;
if(!sp.IsOpen)
sp.Open();
while (sp.BytesToRead > 0)
{
s = sp.ReadLine();
tBlock_test.Text = s;
}
sp.Close();
}
And that is where I've ended and don't know what to do next, or even if this is somehow correct. Again, basic question, i know, but i am seriously stuck on this and cannot find solution anywhere. I'd appreciate any kind of help.
I've remade the app in the WPF template and tried the answer from here: SerialPort reading cause error because of not owning thread (Delegate + Invoke method) and it finally worked.
I am reading from a serial port Rs232. I am facing a very strange problem.
The total bytes from incoming information is 37 bytes. In my computer, each time which i have interrupt in my serial port, the information is exactly 37bytes.
example abcdefghijklmnopqrstuvwxyz1234567890! and so on till 3
but in another pc, my imformation is been seperated to 8 bytes
example abcdefgh, in next interrup ijklmnop , in next interrup qrstuvwx and so on
Here is my serial port code:
public static string Rs232Weight = "0";//Αυτό είναι για να παίρνει την τιμή η ζυγαριά
public static readonly object lockWeight = new object();
private static SerialPort mySerialPort;
private void button1_Click(object sender, EventArgs e)
{
try
{
mySerialPort = new SerialPort(textBox1.Text);
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.Open();
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
catch
{
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
SerialPort sp = (SerialPort)sender;
lock (lockWeight)
{
string tmp = sp.ReadExisting();
ExportFile(Convert.ToString(tmp) + "|" + Convert.ToString(tmp.Length));
}
}
catch //(Exception ex)
{
// Dialogs.SingleMessage(Convert.ToString(ex), "Προειδοποίηση");
}
}
so I wrote a terminal in c# and I need to communicate with a kl25z microprocessor.
the application needs to support the option to choose the number of stop bits, the baud rate and the parity method.
I managed to sort it out with the baud rate but when I try to change the stop bits something goes out of sync and I cant figure out what.
the problem is that the uart is getting jibrish kind of chars instead of what I intended it to get, it does work well when I use one stop bit so I assume I just missed something in my code
I'll add the part of the code that gives me hard time:
this is only the c# part, my terminal I'm pretty sure that the problem is here
and not in the kl25z code
public Form1() {
InitializeComponent(); //init all variables
getAvailablePorts(); //fill the ports combo box with all the ports
}
void getAvailablePorts() {
String[] ports = SerialPort.GetPortNames(); //get the names of all availoable ports
comboBox1.Items.AddRange(ports); //add all the ports names to the combo box
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
try {
SerialPort sp = (SerialPort) sender;
if (serialPort1.IsOpen & sp.IsOpen) {
string indata = sp.ReadLine();
Invoke(new Action(() => textBox1.Text = indata));
if (indata.Equals("new settings been set") ||
indata.Equals("\0new settings been set") ||
indata.Equals("new settings been set??")) {
// baud rate
Invoke(new Action(() => baud = Convert.ToInt32(comboBox3.Text)));
Invoke(new Action(() => serialPort1.BaudRate = baud));
//end bits
Invoke(new Action(() => serialPort1.StopBits = end));
}
}
} catch (System.IO.IOException error) {
return;
} catch (System.InvalidOperationException error) {
return;
}
}
//here i open the port
private void button3_Click(object sender, EventArgs e) { //start port
try { // give the micro processor the info it needs about the settings
serialPort1.Handshake = Handshake.RequestToSendXOnXOff;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
serialPort1.PortName = comboBox1.Text; //port
serialPort1.BaudRate = baud; //baud rate current
// serialPort1.Parity= parity;//parity current
serialPort1.StopBits = end; //stopBits current
serialPort1.DataBits = bits; //current
//sort strings to send
String baudString = comboBox3.Text;
String StopString = comboBox6.Text;
String bitsString = comboBox2.Text;
String parityString = comboBox4.Text;
String startString = comboBox5.Text;
serialPort1.Open(); //open port
bitsString = "8";
//send properties to klz
serialPort1.Write("prop" + "$" + baudString + "$" + StopString + "$" + bitsString + "$" + parityString + "$" + startString + "$");
if (Convert.ToInt32(comboBox6.Text) == 1) {
end = StopBits.One;
} else {
end = StopBits.Two;
}
bits = Convert.ToInt32(comboBox2.Text);
} catch (UnauthorizedAccessException) {
textBox1.Text = "Unauthorized Access";
}
try {
progressBar1.Value = 100;
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = false;
button4.Enabled = true;
textBox2.Enabled = true;
} catch (UnauthorizedAccessException) {
textBox1.Text = "Unauthorized Access";
}
}
When using C# I can only read the last 4 characters of the value in COM2.
Putty reads it correctly
I have no control or information over the source that is putting the value on COM2.
My C# settings resemble the basic settings on Putty configuration screen, but C# offers more settings, so Putty must have some underlying settings not being shown.
I checked the documentation on Putty, I can't find the default settings on serial port.
My code:
using System.IO.Ports;
...
SerialPort mySerialPort = null;
mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 19200;
mySerialPort.Parity = System.IO.Ports.Parity.None;
mySerialPort.StopBits = System.IO.Ports.StopBits.One
mySerialPort.DataBits = 8;
mySerialPort.Handshake = System.IO.Ports.Handshake.None;
mySerialPort.DiscardNull = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.ReadBufferSize = 2147483647;
...
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string value= sp.ReadExisting(); //I onle get the last four characters
}
So I should be obtaining the value "17159160118A" but I onle get "118A", Putty reads the whole string correctly
So given that I have no information about the signal source, my best bet is to use similar configuration as Putty in my code, do you know what configuration this could be? or what am I doing wrong?
So, I deleted all the code and started again with a clean console application, the source was sending the data in two parts, , I was just only reading the second, I just needed to know what was the string terminator, I found out that it was the null terminator character ('\0') so I used that to concatenate my strings, here's my code:
class Program
{
static void Main(string[] args)
{
using (SerialPort sp = new SerialPort("COM2", 19200, Parity.None, 8, StopBits.One))
{
//sp.DiscardNull = true;
sp.Handshake = Handshake.XOnXOff;
sp.ReadBufferSize = 16384;
sp.Open();
sp.DataReceived += sp_DataReceived;
AppDomain.CurrentDomain.ProcessExit += new EventHandler((x, y) =>
{
sp.Close();
});
Console.ReadKey();
}
}
static string myString = string.Empty;
static void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (sender as SerialPort);
if (sp.BytesToRead > 0)
{
myString += sp.ReadExisting().Trim();
if (myString.Last() == '\0')
{
myString = myString.Trim('\0').Trim();
if (!string.IsNullOrWhiteSpace(myString))
{
Console.WriteLine(myString);
}
sp.DiscardInBuffer();
myString = string.Empty;
}
}
}
}
I commented out //sp.DiscardNull = true; as it was removing all the null characters and it worked, so any way thanks for the downvote.
I have to write a program that writes on a serial port but sometimes the call to the Write method hangs and the WriteTimeout is never fired so my program hangs indefinitely.
Here is the port creation code:
void DetectX1BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
String[] ports = SerialPort.GetPortNames();
int i = 0;
foreach (string PortName in ports)
{
try
{
Console.WriteLine("Trying to open:" + PortName);
SerialPort port = openSerial(PortName);
Console.WriteLine("Port is open:" + PortName);
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Write("$ST+IMEI=0000\r\n");
if (IMEIFoundEvent.WaitOne(250))
{
Console.WriteLine("IMEI Found:[" + imei + "]");
if (addresses.ContainsKey(imei))
{
((BackgroundWorker)sender).ReportProgress(0, new X1Model(imei, PortName, addresses[imei]));
}
else
Console.WriteLine("imei not in file: " + imei);
}
port.Close();
}
catch (Exception ex)
{
Console.WriteLine("Erreur port " + PortName + ex.Message);
}
finally
{
i++;
((BackgroundWorker)sender).ReportProgress(i * 100 / ports.Length);
}
}
}
private SerialPort openSerial(string PortName)
{
SerialPort port = new SerialPort(PortName);
port.BaudRate = 57600;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Parity = Parity.None;
port.ReceivedBytesThreshold = 1;
port.Handshake = Handshake.None;
port.DtrEnable = true;
port.RtsEnable = true;
port.WriteTimeout = 5000;
port.ReadTimeout = 5000;
if (!port.IsOpen)
port.Open();
return port;
}
Is there anything I'm missing ?
I don't know if it's relevant but I'm using Serial To USB Adapters.
Edit: I'm using Windows XP with .Net 4.0. The line doesnt't exceed 50 characters and ends by a EOL character.
I know it's an old question, which you've probably solved by now, but there's no accepted answer yet. I was having the same issue yesterday and seem to have fixed it -- were you setting the Write Timeout?
_serialPort.WriteTimeout = 500;
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.writetimeout.aspx
You also need to set the PortName. You can get the list of ports from GetPortNames. This will typically be like COM1 or COM2