so I have a hardware connected to a COM port, but when I try to get its input it doesnt receive nothing. It just doesnt fires that receives something.
First I get all the COM ports and I know that its connected to COM5 so I do
public void StartCOM(string COMPort, ref SerialPort serialPort)
{
serialPort = new SerialPort(COMPort, 9600, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.None;
serialPort.RtsEnable = true;
Debug.Log("Serial port inicializado en: " + COMPort + " |Baudrate: " + baudRate);
}
then I call
serialPort.DataReceived += DebugReceivedData;
That does:
void DebugReceivedData(object sender, SerialDataReceivedEventArgs e)
{
Debug.Log("Data recibida");
SerialPort serialPortSender = (SerialPort)sender;
string dataReceived = serialPortSender.ReadExisting();
Debug.Log(dataReceived);
}
and finally I call:
public void OpenCOM(ref SerialPort serialPort)
{
//Comprobamos si el serial port existe
if (serialPort != null)
{
//Si ya está abierto no hacemos nada
if (serialPort.IsOpen)
{
Debug.Log("El puerto " + serialPort.PortName + " ya estaba abierto");
}
//Si está cerrado lo abrimos
else
{
Debug.Log("Abrimos puerto: " + serialPort.PortName);
serialPort.Open();
// Set the read/write timeouts
serialPort.ReadTimeout = 16;
//serialPort.ReadTimeout = 500;
//serialPort.WriteTimeout = 500;
}
}
}
It wont never Debug "Data recibida".
Im using Unity with API 4.0
UPDATE:
Checking every frame (That does Update method)
private void Update()
{
string dataReceived = serialPort.ReadExisting();
Debug.Log(dataReceived);
}
It prints the received data (ie: -17F)
Related
There are loads of questions about listening of devices on Serial Port using C#.
However I couldn't find something about my problem.
Connected two serial port device one transmitter and one receiver.
When i start one application exe and check two port for listen async, after a
while the reading stops for one of the com ports.
There is no problem when I start separate application for each port.
ScreenShoot
public Form1()
{
InitializeComponent();
// Get a list of serial port names.
string[] ports = SerialPort.GetPortNames();
foreach (var item in ports)
{
checkedListBox1.Items.Add(item);
}
}
private void btnListenPort_Click(object sender, EventArgs e)
{
doWork(checkedListBox1);
}
private async Task doWork(CheckedListBox cbl)
{
try
{
foreach (var itemChecked in cbl.CheckedItems)
{
string sPort = itemChecked.ToString();
await Task.Run(() =>
{
ListenAsync(sPort);
});
}
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred: {0}", ex.Message);
}
}
private void ListenAsync(string strPort) {
var serialPort = new SerialPort(strPort, 9600, Parity.None, 8, StopBits.One);
serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
serialPort.Open();
}
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort)sender;
string incomSting = spL.ReadLine();
setText(spL.PortName + " " + incomSting);
}
delegate void serialCalback(string val);
private void setText(string val)
{
if (this.richTextBox1.InvokeRequired)
{
serialCalback scb = new serialCalback(setText);
this.Invoke(scb, new object[] { val });
}
else
{
richTextBox1.Text += Environment.NewLine;
richTextBox1.Text += val + Environment.NewLine;
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
}
'''
If you use spL.ReadLine() to read data, you must add a new line ("\n") at the end of your data.
ex: spL.Write("your transmitte data \n");
Solution: Try to replace with spL.ReadLine() with spL.ReadExisting()
So I have this port that I'm opening and saving the name of the port in a setting of my application. When I load the form it tries to open the port however fails to do so. Only after clicking on my "open port" button that has the EXACT same code does the port open. And then If I click my "close port" button and reopen the form it works! It automatically opens the port for me. However it's only if I'm fast enough. If I leave the application closed (and thus port closed) for say 10-15 seconds and reopen the application, I'll get my error thrown at me. What's the reason for this??
The code used at launch and in my "open port" button:
mySerialPort.createPort(Properties.Settings.Default.portName);
if (!mySerialPort.isOpen)
{
try
{
mySerialPort.openSerialPort();
}
catch
{
MessageBox.Show("Error: Could not open Serial port " + Properties.Settings.Default.portName, "Port Opening Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (mySerialPort.isOpen)
{
portActiveStatusLbl.Text = Properties.Settings.Default.portName + " OPEN";
portActiveStatusLbl.ForeColor = Color.Green;
}
}
and here's mySerialPort Class:
public static class SerialPortConfig
{
public static SerialPort mySerialPort = new SerialPort();
public static string myString = "";
public static bool isOpen { get { return mySerialPort.IsOpen; } }
public static void createPort (string portName)
{
if (portName == "")
portName = "COM1";
mySerialPort.PortName = portName;
mySerialPort.BaudRate = 2400; //Depending on the hardware used this may change, mitutoyo input tool asks for 2400 baud
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.RequestToSend; //DO NOT SET TO NONE
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
public static void openSerialPort()
{
mySerialPort.Open();
}
public static void closeSerialPort()
{
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting(); //stores the char that fired the event into 'indata'
myString += indata;
if (indata.Contains("\r")) //check to see if char received indicates end of measurement
{
if (myString == "911\r") //911 is the code given when the micrometer is off, so we have it do nothing
myString = "";
else
{
myString = myString.Substring(4, 8);
Form1.instance.pendingMeasurement = true;
}
}
}
}
im writing a program which reads the input from the serial port. It does recieve something but its breaking the line without reason.
The right input
This right inout should be
Sending...Sending...Sending...Sending...Sending...
Without changing line.
The actual input
Sending...
Se
ndin
g...
S
endi
ng..
.
Send
ing.
..
Se
ndin
g...
The code
public void Serial ()
{
try
{
SerialPort serial = new SerialPort(this.comboBox1.Text);
serial.BaudRate = 9600;
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
serial.DataBits = 8;
serial.Handshake = Handshake.None;
serial.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceivedHandler);
serial.Open();
}
catch
{
}
}
public void SerialDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string dataIn = sp.ReadExisting();
if (log_time == true)
{
this.richTextBox1.AppendText(time + dataIn);
}
else
{
this.richTextBox1.AppendText(dataIn + "\n");
}
}
The this.combobox1.Text is working fine, im using try because if not the program would crash if the serial port wasnt on!
Im initializing the serial on an other void with Serial();
How can i get the right input?
In your else clause, you should not append "\n" to this.richTextBox1. That is the special character for a new line. If you want the right input, need something like this.richTextBox1.AppendText(dataIn + "...");
i have a serial port that will iterate through the ports with this method:
foreach (string s in SerialPort.GetPortNames())
{
var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (serialOneOfMany.IsOpen)
{
serialOneOfMany.Close();
}
else
{
try
{
serialOneOfMany.Open();
}
catch
{
var openSerial = new System.Timers.Timer(3100);
openSerial.Elapsed += (o, e) =>
{
serialOneOfMany.Open();
openSerial.Enabled = false;
openSerial.Dispose();
};
openSerial.Enabled = true;
}
}
if (serialOneOfMany.IsOpen)
{
string received;
try
{
lblPortNum.Content = s;
lblPortNum.Refresh();
serialOneOfMany.Write(testMessage);
serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
}
catch (TimeoutException e)
{
serialOneOfMany.Close();
continue;
}
}
}
so, i want to open the port, send it a message, listen for the response, then close it. as everyone knows, every comport found in GetPortNames isn't a valid serial port. so, what i've been doing is setting a timer with a dispatcher timer:
DispatcherTimer time = new DispatcherTimer();
time.Interval = TimeSpan.FromMilliseconds(3000);
time.Tick += new EventHandler(someEventHandler);
time.Start();
here's the other method handled here:
private void someEventHandler(Object sender, EventArgs args)
{
SerialPort serial = (SerialPort)sender;
if (serial.IsOpen)
serial.Close();
serial.Dispose();
//if you want this event handler executed for just once
DispatcherTimer thisTimer = (DispatcherTimer)sender;
thisTimer.Stop();
}
so, it'll open the com port, if it doesn't get a response within 3 seconds, it will close the port. the problem i'm having is that the foreach loop will just barrel through the code and open the comport several times, i'll get a message saying The COM Port is open already and can't be used. so basically it's not pausing in openSerial.
i want it to open a new serial port, and if it's not accessible, wait 3100 milliseconds and try again. how do i do that?
UPDATED CODE:
private void button1_Click(object sender, RoutedEventArgs e)
{
CheckPorts();
}
private void checkPorts()
{
SendMessage("messageToDevice1", 19200);
SendMessage("Message2", 9600);
}
private void SendMessage(string testMessage, int baudRate)
{
int baudRate = 9600;
string testMessage = "test";
txtPortName.Text = "Testing all serial ports";
foreach (string s in SerialPort.GetPortNames())
{
SerialPort newPort = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (!newPort.IsOpen)
{
try
{
newPort.Open();
}
catch { }
}
if (newPort.IsOpen)
{
openPorts.Add(newPort);
newPort.Write(testMessage);
newPort.DataReceived += new SerialDataReceivedEventHandler(serialOneOfMany_DataReceived);
}
else
{
newPort.Dispose();
}
}
txtPortName.Text = "Waiting for response";
tmrPortTest.Enabled = true;
}
my new problem is that it just blows through the com ports, i need it to stop for each one, take a second to listen, then close it. it just blows through the foreach loop.
now, the reason why i don't just open up the port and keep it open through all the messages is that my devices have different baud rates, and i can't adjust them to all match. so, i need to open the ports, then send messages, listen, if they don't respond to the first round of messages, then open them up at the new baudrate and send a new batch of messages. but the foreachloop doens't pause for me to listen.
I think this more or less agrees with rare's answer. The port where you receive a response (you would probably want to check the response as well) will remain open and all the others should close.
private List<SerialPort> openPorts = new List<SerialPort>();
private void button3_Click(object sender, EventArgs e)
{
int baudRate = 9600;
string testMessage = "test";
txtPortName.Text = "Testing all serial ports";
foreach (string s in SerialPort.GetPortNames())
{
SerialPort newPort = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (!newPort.IsOpen)
{
try
{
newPort.Open();
}
catch { }
}
if (newPort.IsOpen)
{
openPorts.Add(newPort);
newPort.Write(testMessage);
newPort.DataReceived += new SerialDataReceivedEventHandler(serialOneOfMany_DataReceived);
}
else
{
newPort.Dispose();
}
}
txtPortName.Text = "Waiting for response";
tmrPortTest.Enabled = true;
}
private void serialOneOfMany_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
txtPortName.Text = ((SerialPort)sender).PortName;
}
private void tmrPortTest_Tick(object sender, EventArgs e)
{
tmrPortTest.Enabled = false;
foreach (SerialPort port in openPorts)
{
if (port.PortName != txtPortName.Text)
{
port.Close();
port.Dispose();
}
}
}
Here's how I would do this --
First, try to open all the serial ports. The ones that actually do open are put in a list.
Assign all serial ports in the list to the same DataReceived event handler. The event handler is where you will save the port name (it's in the args) and kill the timer if you rx'd the response
Send your testMessage out all the open ports
Set just one timer for 3.1 seconds
Close the ports once the timer fires or the event handler rx's the response.
HI
im new in c# serial port. im writing a c# program running is winXP and win7 to keep received data from the serial port when the machine was sent data.
using System.IO;
using System.IO.Ports;
using System.Threading;
namespace RS232RVR
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SettingRS232();
}
public void SettingRS232 ()
{
try
{
SerialPort mySerialPort = new SerialPort("COM6");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None; //send to hardware flow control.
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceviedHandler);
mySerialPort.Open();
richTextBox1.Text = "on";
mySerialPort.Close();
}
catch (Exception ex)
{
richTextBox1.Text = ex.Message;
}
}
private void DataReceviedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
richTextBox1.Text = indata;
}
}
}
COM6 is active in my pc. but my problem was seem the datareceived event is not fire when it has data coming from the serial port. ( i had checked the sport by using some of the freeware application)
anyone can help?
thanks
mySerialPort.Open();
richTextBox1.Text = "on";
mySerialPort.Close();
That's not going to work, you'll close the serial port a couple of microseconds after opening it. Yes, the DataReceived event handler is not likely to fire. Only close the port when shutting down your program.
mySerialPort.Handshake = Handshake.None
That's a problem too, you'll need to control the handshake signals yourself now. The vast majority of serial port devices won't send anything until they see the machine powered up and ready to receive. Set the DtrEnabled and RtsEnabled properties to true.
Did you copy that code from your application? Is it perhaps just a case that the event handler name is misspelled? E.g. DataReceviedHandler should actually be spelt DataReceivedHandler.
The problem was solved and i would like to share it. i had fine dunning as below:
namespace RS232RVR
{
public partial class Form1 : Form
{
private delegate void SetTextDeleg(string data);
public Form1()
{
InitializeComponent();
SettingRS232();
}
public void SettingRS232 ()
{
try
{
SerialPort mySerialPort = new SerialPort("COM6");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.ReadTimeout = 2000;
mySerialPort.WriteTimeout = 500;
mySerialPort.DtrEnable = true;
mySerialPort.RtsEnable = true;
mySerialPort.Open();
//mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.DataReceived += DataReceivedHandler;
textBox1.Text = "Serial Port is Ready.";
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
}
public void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
System.Threading.Thread.Sleep(500);
string indata = sp.ReadExisting();
this.BeginInvoke(new SetTextDeleg(DisplayToUI), new object[] { indata });
//textBox1.Text += indata;
}
private void DisplayToUI(string displayData)
{
textBox1.Text += displayData.Trim();
// textBox1.Text += displayData;
}
}
}
If anyone have comment on the code you are welcome, is my pleasure and wish to code it better.