Reading data from serial port used >90% CPU - c#

I just created 1 simple C# app reading data from serial port (baudrate 57600). When I send file data from another computer through serial port, CPU worked >90%. How can I solve that ?
EDIT:
private void btn_Start_Click(object sender, EventArgs e)
{
if (temp_portname != null)
{
//ポート設定
SerialPort.PortName = PORT1;
SerialPort.BaudRate = 57600;
//ポートを開く
try
{
SerialPort.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

Related

Reading Serial Data from Arduino in Windows Forms Application

I am currently trying to build a windows forms app that gets sensor data from an arduino via the serial com.
when checking in the arduino IDE the data gets writen into the serial port correctly.
But i can't figure out how to read the data via c#.
class Program
{
static SerialPort SP;
static void Main(string[] args)
{
SP = new SerialPort();
SP.PortName = "COM7";
SP.BaudRate = 9600;
SP.Handshake = System.IO.Ports.Handshake.RequestToSend;
SP.Open();
while (true)
{
Console.WriteLine(DateTime.Now.ToString() + " : " + SP.ReadLine());
}
}
}
My guess is that the Port is not properly set up, but i have no idea what i am missing.
The Goal is just to receive strings from the arduino, i do not necessarily need to send any data to the arduino.
edit: i am working with an arduino micro
Did you close Arduino IDE?
You need to add a wait code before reading from the port
Below is a working example:
private SerialPort _currentPort = new SerialPort("COM7", 9600);
private readonly object _sync = new object();
public bool Open()
{
_currentPort.Encoding = Encoding.UTF8;
_currentPort.DtrEnable = true;
_currentPort.ReadTimeout = 2000;
try
{
if (!_currentPort.IsOpen)
lock (_sync)
{
if (_currentPort.IsOpen)
return true;
_currentPort.Open();
System.Threading.Thread.Sleep(1500);
}
}
catch (Exception e)
{
//_localLogger?.Error($"{_currentPort.PortName}, {e.Message}", e);
return false;
}
return _currentPort.IsOpen;
}
public bool Subscribe()
{
try
{
if (Open())
{
_currentPort.DataReceived += CurrentPortOnDataReceived;
return true;
}
return false;
}
catch (Exception e)
{
//_localLogger?.Error($"{_currentPort.PortName}, {e.Message}", e);
return false;
}
}
private void CurrentPortOnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!_currentPort.IsOpen)
{
//_localLogger.Info($"{_currentPort} is closed");
Open();
}
Console.WriteLine(_currentPort.ReadExisting());
}

Modbus TCP master to multiple slave Connectivity

I am developing a windows form to function as a modbus tcp Master Simulator.I am using NModbus library.
I want to connect to multiple slaves simultaneously and do the read and write operation,does the NModbus library supports this kind of implementation? and if so how?.
Currently i am able to connect to single slave device and do the read/write operations,but i am stuck on how to the same with multiple slaves though.
Should i use the threading Concept to achieve the same.
Here is my code to connect to single slave device and do the read/write operation.
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
TcpClient masterTcpClient = new TcpClient(txtIP.Text, 502);
master = ModbusIpMaster.CreateIp(masterTcpClient);
MessageBox.Show("Connected");
}
catch (SystemException error)
{
MessageBox.Show(error.Message);
}
}
private void btnReadCoil_Click(object sender, EventArgs e)
{
try
{
byte slaveID = 255;
ushort startAddress = Convert.ToUInt16(txtStartaddress.Text);
ushort numInputs = Convert.ToUInt16(txtSize.Text);
bool[] inputs = master.ReadCoils(slaveID, startAddress, numInputs);
AnswerFromServer.Items.Clear();
for (int i = 0; i < inputs.Length; i++)
{
AnswerFromServer.Items.Add(Convert.ToInt16(inputs[i]));
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnWriteSingleRegister_Click(object sender, EventArgs e)
{
try
{
byte slaveID = 255;
ushort RegisterAddress = Convert.ToUInt16(txtStartaddress.Text);
ushort value = Convert.ToUInt16(txtSingleValue.Text);
master.WriteSingleRegister(slaveID, RegisterAddress, value);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Can any one please help me with this one?
create another instance of this socket and maintain it.
TcpClient masterTcpClient_Two = new TcpClient(txtIPTwo.Text, 502);

Receiving continuous data using 32feet in .Net (BLUETOOTH)

I am creating a Windows Form application, where it is connecting to a device through bluetooth. I am able to send commands to the device and I am receiving the data continuously. The problem I am facing is that I am not able to show the continuous data in the text box. The text box only shows the first line of characters the application is receiving. Here is my code:
CONNECT BUTTON ACTION:
private void btnConnect_Click(object sender, EventArgs e)
{
if (listBox.SelectedItem != null)
{
lblProgress.Text = "";
btnStart.Enabled = true;
cBoxAvailablePorts.Enabled = cBoxAvailableBaudRates.Enabled = true;
try
{
int pos = listBox.SelectedIndex;
deviceInfo = array.ElementAt(pos);
if (pairDevice())
{
Thread thread = new Thread(() => connectThread());
thread.Start();
}
else
{
MessageBox.Show("Pair failed!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
else
{
MessageBox.Show("Please connect to a device!");
}
}
THREAD ACTION
private void connectThread()
{
//BluetoothClient client = new BluetoothClient();
bc.BeginConnect(deviceInfo.DeviceAddress, serviceClass, this.connectCallBack, bc);
}
CALLBACK ACTION:
private void connectCallBack(IAsyncResult result)
{
//BluetoothClient client = (BluetoothClient)result.AsyncState;
try
{
if (bc.Connected)
{
MessageBox.Show("Connected!");
}
else
{
MessageBox.Show("Connection Failed!");
}
}
catch (Exception)
{
MessageBox.Show("Not able to identify Bluetooth devices! Please try again.!");
}
}
START BUTTON ACTION:
Here I send a command "S".
In button action I call sendMessage("S").
The function that is called is shown below:
public void sendMessage(string msg)
{
try
{
if (bc.Connected)
{
Stream stream = bc.GetStream();
stream.ReadTimeout = 1000;
StreamWriter streamWriter = new StreamWriter(stream);
streamWriter.WriteLine(msg);
streamWriter.Flush();
// Read operation
StreamReader streamReader = new StreamReader(stream);
string result = streamReader.ReadLine();
txtResult.Text = result;
}
else
{
MessageBox.Show("Sending failed!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I wrote the StreamReader part in a loop, and it gave me Socket Exception.
I also tried to get the data from Serial Port and used DataReceived event just in case, but still it didn't help.
Any help would be appreciated.
Thank you!
OKAY! I solved the problem. Without getting in trouble with 32feet library (though it is fun to code with 32feet), I thought to make communication through serial port. I connected the device with my laptop and got to know the outgoing COMPORT in bluetooth setting of my laptop. The two-way communication can only be done through outgoing COMPORT, not the incoming COMPORT.
Suppose the outgoing COMPORT is COM12 and the baud rate that I have set is 9600.
So here is my code:
public delegate void updateDelegate(string text);
private updateDelegate objDelegate;
private SerialPort serialPort;
public View() // constructor
{
InitializeComponent();
this.WindowState = FormWindowState.Normal;
this.StartPosition = FormStartPosition.CenterScreen;
this.objDelegate = new updateDelegate(getText);
serialPort = new SerialPort("COM12", 9600);
serialPort.Handshake = Handshake.None;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
}
START BUTTON ACTION
private void btnStart_Click(object sender, EventArgs e)
{
sendData("S");
}
// SEND COMMAND
public void sendData(string msg)
{
try
{
if (!serialPort.IsOpen)
{
serialPort.Open();
//serialPort.Close();
}
if (serialPort.IsOpen)
{
serialPort.Write(msg);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// READ DATA
public void readData()
{
try
{
serialPort.DataReceived += SerialPort_DataReceived;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string res = serialPort.ReadExisting();
Thread.Sleep(500);
txtResult.Invoke(this.objDelegate, new object[] {res});
}
public void getText(string text)
{
txtResult.Text = text;
}
I hope this will help someone! Thank you!!!

Close application after reading upper code c#

I am working with arduino serial monitor. My goal is to connect through serial port, send some data and close the application after it's done.
This is a C# application. Everything works well besides the fact that the application does not close. To solve the issue, I added Application.Exit() call at the end of Form1_Load method. After this change, the application starts and closes without reading the uppercase letter that I'm sending.
Source code:
namespace ForTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
SerialPort sp = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);
try
{
sp.Open();
try
{
sp.WriteLine("Z"); // Send 1 to Arduino
sp.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
catch (Exception ek)
{
System.Diagnostics.Debug.WriteLine(ek.Message);
}
}
Application.Exit();
}
private void label2_Click(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}
if I understood properly, you want to send data FROM C# to ARDUINO and then you exit the C# app
you can't just call Application.exit() after the InitializeComponent(), instead to achieve that you need to exit after sending the data
sp.WriteLine("Z"); // Send 1 to Arduino
sp.Close();
Application.Exit(); ///here!!

serial port doesn't refresh received data until I restart the application

I wrote a message last week but would like to add another more simple question again to clarify.
I have a serial port console application. There are 20 virtual ports. My application successfully working but doesnt change received data value until I restart the application. I am not sure why it happens.
This issue appeared after FIFO enabled property was set to true.
How can i refresh serial port?
Thanks
--- here is the codes :
static void serialportinstances()
{
for (int ix =1; ix < 20; ix++)
{
if (sportlar.ContainsValue("COM"+ix.ToString()) ==false)
{
try
{
SerialPort ekle = new SerialPort("COM" + ix.ToString(), 1200, Parity.None, 8, StopBits.One);
//ekle.DtrEnable = true;
//ekle.RtsEnable = true;
try
{
ekle.NewLine = "\r";
ekle.Open();
ekle.DataReceived += new SerialDataReceivedEventHandler(datareceived);
Console.WriteLine(String.Format("Dinamik SP {0} başarıyla açıldı", ekle.PortName));
}
catch (Exception eu)
{
Console.WriteLine(String.Format("Dynamic SP {0} açılamadı!", ekle.PortName));
}
sportlar.Add(ekle, "COM" + ix.ToString());
}
catch (Exception ee)
{
Console.WriteLine("port could not be created");
}
}
}
}
and datareceiving handler ;
static void datareceived(object sender, SerialDataReceivedEventArgs e)
{
lock (mylockobject)
{
SerialPort spn = (SerialPort)sender;
try
{
string s = spn.ReadLine();
GetWeightPWI(spn.PortName, s);
Thread.Sleep(1);
}
catch (Exception ee)
{
Console.WriteLine("error : " + ee.ToString());
}
}
}
and parsing the received data here :
private static void GetWeightPWI(string portadi, string alinan)
{
Console.WriteLine("PORT NAME : "+portadi+" and received data : "+alinan.toString());
}

Categories

Resources