I have a small problem. Now I have written my code, and it works excellent, but I'm trying to do it better.
I receive data from a device, but now I will upgrade it to receive data from more devices.
To this I have made a string called adress, this is the string which should be looked at. If this string is for example 111222333, then the data received should be saven in chart 1. But if this string is for example 333aaa444, then the data received should be saven in chart 2.
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
recievdata = SerialPort.ReadExisting();
string adress = recievdata.Substring(7, 16);
this.Invoke(new EventHandler(DisplayText));
using (Stream stream2 = File.Open(path, FileMode.Append))
using (StreamWriter sWriter1 = new StreamWriter(stream2))
{
if (adress )
if (recievdata.Contains("UCAST") && recievdata.Contains("=g"))
{
sWriter1.Write(DateTime.Now.ToString("HH:mm:ss"));
sWriter1.Write(" ; ");
sWriter1.WriteLine(1);
if (SleepMovChar.InvokeRequired)
{
SleepMovChar.Invoke(new MethodInvoker(delegate
{ SleepMovChar.Series["Bevægelse"].Points.AddXY(DateTime.Now.ToString("HH:mm:ss"), 1); }));
SleepMovChar.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
}
}
else
{
timer1.Tick += new EventHandler(timer1_Tick);
}
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
Hope that you can help me.
Thanks.
Related
I'm receiving in my serial port the message "Hello World!CRLF" (no quotes) at every 1 second, and I'm using ReadExisting() to read the message, but I can't understand why I'm receiving lots of "\0" before every character.
PuTTy seems to handle the messages just fine, so my code must be the problem. Could someone please help me to figure this out?
Part of my code:
void button1_Click(object sender, EventArgs e)
{
try
{
_serialPort = new SerialPort(cbPort.Text);
_serialPort.BaudRate = Int32.Parse(cbBaudrate.SelectedItem.ToString());
_serialPort.Parity = Parity.None;
_serialPort.StopBits = StopBits.One;
_serialPort.DataBits = 8;
_serialPort.ReadTimeout = 500;
_serialPort.Open();
if (_serialPort.IsOpen)
{
try
{
ReadSerialData();
}
catch (TimeoutException) { }
}
}
catch (Exception er){}
}
private void ReadSerialData()
{
try
{
ReadSerialDataThread = new Thread(ReadSerial);
ReadSerialDataThread.Start();
}
catch (Exception e){}
}
private void ReadSerial()
{
try
{
while (_serialPort.BytesToRead >= 0)
{
readserialvalue = _serialPort.ReadExisting();
ShowSerialData(readserialvalue);
Thread.Sleep(1);
}
}
catch (Exception e){}
}
public delegate void ShowSerialDatadelegate(string r);
private void ShowSerialData(string s)
{
if (rtb_msg.InvokeRequired)
{
ShowSerialDatadelegate SSDD = ShowSerialData;
Invoke(SSDD, s);
}
else
{
rtb_msg.AppendText(readserialvalue);
}
}
As sugested by #Hans Passant changing the encoding to BigEndian solved the main issue.
Still getting lots of invalid unicode chars, but I think is best to open another thread. Thank you all for the support.
_serialPort.Encoding = System.Text.Encoding.BigEndianUnicode;
Are you sure that you want to read from the serial port even if there are 0 bytes to be read? If not, you might want to try changing:
while (_serialPort.BytesToRead >= 0)
to
while (_serialPort.BytesToRead > 0)
I suspect you may be reading from the serial port with 0 bytes to be read, which could return a null (\0) value
private void Serial_Event_1(object sender, SerialDataReceivedEventArgs e)
{
bytes1 = 0;
if (received_Sequence == 0)
{
SerialPort sData = sender as SerialPort;
var th1 = new Thread(Serial_Event_Thread1);
try
{
bytes1 = sData.BytesToRead;
}
catch { }
byte[] read_data_ = new byte[bytes1];
linef_1 = new byte[bytes1];
try
{
// sData.Read(read_data_, 0, bytes1);
sData.Read(linef_1, 0, bytes2);
// linef_1 = read_data_;
}
catch
{
MessageBox.Show("1 handle error");
}
Invoke((MethodInvoker)delegate
{
th1.Start();
});
if (port_numbering > 1)
{
received_Sequence ++;
}
}
if (port_numbering == 1)
received_Sequence = 0;
}
private void Serial_Event_2(object sender, SerialDataReceivedEventArgs e)
{
//Same as receivedevent 1
}
private void Serial_Event_Thread1()
{
// The incoming data packets are analyzed and written to the richtextbox.
//Even when using two or more serial communication without `enter code here`analyzing packets, only one port can communicate smoothly.
//The `enter code here`other ports are not well received or do not work.
}
enter code here
The length of the data received is 18 bytes.
I've done it a lot with one Serialport communication.
Please give me a hint if you have implemented two or more Serial communications.
It uses a total of four " ReceivedEvent " and handles data with separate threads.
If you use two or more ports, the data is normally sent from one port to another, and the data is not broken or data is not received.
We try to connect a total of four ports using the " multi-serialport " approach.
You want to receive data sequentially from each number to a sample of 20 ms.
Each " serialdatareceivevent " occurs, and data is displayed once a second.
I'm not sure how to correct it, but please help me.
Thank you for reading it here.
I'll be looking forward to your help.
private void Serial_btn_1_Click(object sender, EventArgs e)
{
Test_Timer.Interval = 15;
Test_Timer.Tick += new System.EventHandler(TimerEventProcessor);
Test_Timer.Start();
}
private void TimerEventProcessor(object sender, EventArgs e)
{
try
{
bytes1 = serialPort1.BytesToRead;
bytes1 = serialPort2.BytesToRead;
bytes1 = serialPort3.BytesToRead;
bytes1 = serialPort4.BytesToRead;
linef_1 = new byte[bytes1];
linef_2 = new byte[bytes2];
linef_3 = new byte[bytes3];
linef_4 = new byte[bytes4];
}
catch { }
try
{
serialPort1.Read(linef_1, 0, bytes1);
serialPort2.Read(linef_2, 0, bytes2);
serialPort3.Read(linef_3, 0, bytes3);
serialPort4.Read(linef_4, 0, bytes4);
}
catch
{
// MessageBox.Show("Read_data no");
}
Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(ByteToHex(linef_1));
richTextBox2.AppendText(ByteToHex(linef_2));
richTextBox3.AppendText(ByteToHex(linef_3));
richTextBox4.AppendText(ByteToHex(linef_4));
});
}
Timer speed 15ms.
Changed to the above source.
Can I get a problem when I receive data using a timer?
I have a C# application which accepts data from a port(9100 ie, uses data when printer print something) and use it into an application. The problem is, sometimes it doesn't receiving data completely from printer and I have seen some questions regarding the difficulties in reading data at one time in TCP.
As I am not familiar with this, somebody please suggest me a better way to fix it.
Thanks in advance..
Here is my code
TcpListener Listener = null;
public Thread T = null;
public FeederControlMonitor()
{
InitializeComponent();
}
private void FeederControlMonitor_Load(object sender, EventArgs e)
{
txtStatus.Text = "Feeder waiting for data...";
ThreadStart Ts = new ThreadStart(StartReceiving);
T = new Thread(Ts);
T.Start();
}
public void StartReceiving()
{
ReceiveTCP(9100);
}
public void ReceiveTCP(int portN)
{
try
{
Listener = new TcpListener(IPAddress.Any, portN);
Listener.Start();
}
catch (Exception ex)
{
File.WriteAllText(#"C:\\Drive\\ex.txt", ex.Message);
Console.WriteLine(ex.Message);
}
try
{
while (true)
{
Socket client = Listener.AcceptSocket();
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[20000];
int size = client.Receive(data);
ParseData(System.Text.Encoding.Default.GetString(data));
//Here some process will do with received data
client.Close();
});
childSocketThread.IsBackground = true;
childSocketThread.Start();
}
Listener.Stop();
}
catch (Exception ex)
{
File.WriteAllText(#"C:\\ex.txt", ex.Message);
}
}
I'm new in socket programming. I want to create an application for PC using C# and an application for android phones witch can communicate with other via wireless network(LAN).
For sending data to android app, I'm using this code in PC side:
private void sendButton_Click(object sender, EventArgs e)
{
try
{
Object objData = messageTextBox.Text;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString ());
_socket.Send (byData);
}
catch(SocketException se)
{
MessageBox.Show (se.Message );
}
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.18"), 2001);
_socket.Connect(_ipEndPoint);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
In android app, I want to receive data with this code:
Handler myUpdateHandler = new Handler()
{
public void handleMessage(Message msg)
{
Log.d(appTag, "setting textview");
TextView tv = (TextView) findViewById(R.id.messageText);
tv.setText(mClientMsg);
}
};
class CommsThread implements Runnable
{
public void run()
{
try
{
Socket s = null;
try
{
ss = new ServerSocket(2001);
}
catch (IOException e)
{
Log.d(appTag, e.toString());
}
while (!Thread.currentThread().isInterrupted())
{
Message m = new Message();
Log.d(appTag, "message m = new message()");
try
{
if (s == null) s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = in.readLine()) != null)
{
Log.d(appTag, line);
mClientMsg = line;
}
myUpdateHandler.sendMessage(m);
}
catch (IOException e)
{
Log.d(appTag, e.toString());
}
}
}
catch (Exception e)
{
Log.d(appTag, e.toString());
}
}
}
But android application will not receive any data.
can anyone help me to solve my problem?
I'm very noob in socket programming.
sorry for bad english.
thanks.
If you update your reader to just read characters, and spit them out, what does it show? e.g.
try
{
if (s == null) s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
char[] recvd = new char[1];
while (in.read(recvd, 1, 1) != -1)
{
String line = new String(recvd);
Log.d(appTag, line);
mClientMsg = line;
}
myUpdateHandler.sendMessage(m);
}
catch (IOException e)
{
Log.d(appTag, e.toString());
}
I have a problem with a small C# application.
The application has to connect through a serial port to a bar code scanner which reads a Data Matrix code. The Data Matrix code represents an array of bytes which is a zip archive. I read a lot about the way SerialPort.DataReceived work but I can't find an elegant solution to my problem. And the application should work with different bar code scanners so i can't make it scanner specific. Here is some of my code:
using System;
using System.IO;
using System.IO.Ports;
using System.Windows.Forms;
using Ionic.Zip;
namespace SIUI_PE
{
public partial class Form1 : Form
{
SerialPort _serialPort;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
_serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.ToString());
return;
}
_serialPort.Handshake = Handshake.None;
_serialPort.ReadBufferSize = 10000;
_serialPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
_serialPort.Open();
}
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[10000];
_serialPort.Read(data, 0, 10000);
File.WriteAllBytes(Directory.GetCurrentDirectory() + "/temp/fis.zip", data);
try
{
using (ZipFile zip = ZipFile.Read(Directory.GetCurrentDirectory() + "/temp/fis.zip"))
{
foreach (ZipEntry ZE in zip)
{
ZE.Extract(Directory.GetCurrentDirectory() + "/temp");
}
}
File.Delete(Directory.GetCurrentDirectory() + "/temp/fis.zip");
}
catch (Exception ex1)
{
MessageBox.Show("Corrupt Archive: " + ex1.ToString());
}
}
}
}
So my question is: How can I know that I read all the bytes the scanner sent?
The code I've got for reading barcode data, which has been working flawlessly in production for several years looks like this:
Note, my app has to read standard UPC barcodes as well as GS1 DataBar, so there's a bit of code you may not need...
The key line in this is:
string ScanData = ScannerPort.ReadExisting();
which is found in the DoScan section, and simply reads the scan data as a string. It bypasses the need to know how many bytes are sent, and makes the rest of the code easier to deal with.
// This snippet is in the Form_Load event, and it initializes teh scanner
InitializeScanner();
ScannerPort.ReadExisting();
System.Threading.Thread.Sleep(1000);
// ens snippet from Form_Load.
this.ScannerPort.DataReceived += new SerialDataReceivedEventHandler(ScannerPort_DataReceived);
delegate void DoScanCallback(); // used for updating the form UI
void DoScan()
{
if (this.txtCouponCount.InvokeRequired)
{
DoScanCallback d = new DoScanCallback(DoScan);
this.Invoke(d);
return;
}
System.Threading.Thread.Sleep(100);
string ScanData = ScannerPort.ReadExisting();
if (isInScanMode)
{
try
{
HandleScanData(ScanData);
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show("Invalid Scan");
}
}
}
void ScannerPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// this call to sleep allows the scanner to receive the entire scan.
// without this sleep, we've found that we get only a partial scan.
try
{
DoScan();
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show("Unable to handle scan event in ScannerPort_DataReceived." + System.Environment.NewLine + ex.ToString());
}
}
void Port_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show(e.EventType.ToString());
}
private void HandleScanData(string ScanData)
{
//MessageBox.Show(ScanData + System.Environment.NewLine + ScanData.Length.ToString());
//Determine which type of barcode has been scanned, and handle appropriately.
if (ScanData.StartsWith("A") && ScanData.Length == 14)
{
try
{
ProcessUpcCoupon(ScanData);
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show("Unable to process UPC coupon data" + System.Environment.NewLine + ex.ToString());
}
}
else if (ScanData.StartsWith("8110"))
{
try
{
ProcessDataBarCoupon(ScanData);
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show("Unable to process DataBar coupon data" + System.Environment.NewLine + ex.ToString());
}
}
else
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show("Invalid Scan" + System.Environment.NewLine + ScanData);
}
}
private void InitializeScanner()
{
try
{
ScannerPort.PortName = Properties.Settings.Default.ScannerPort;
ScannerPort.ReadBufferSize = Properties.Settings.Default.ScannerReadBufferSize;
ScannerPort.Open();
ScannerPort.BaudRate = Properties.Settings.Default.ScannerBaudRate;
ScannerPort.DataBits = Properties.Settings.Default.ScannerDataBit;
ScannerPort.StopBits = Properties.Settings.Default.ScannerStopBit;
ScannerPort.Parity = Properties.Settings.Default.ScannerParity;
ScannerPort.ReadTimeout = Properties.Settings.Default.ScannerReadTimeout;
ScannerPort.DtrEnable = Properties.Settings.Default.ScannerDtrEnable;
ScannerPort.RtsEnable = Properties.Settings.Default.ScannerRtsEnable;
}
catch (Exception ex)
{
MessageBox.Show("Unable to initialize scanner. The error message received will be shown next. You should close this program and try again. If the problem persists, please contact support.", "Error initializing scanner");
MessageBox.Show(ex.Message);
Application.Exit();
}
}
As stated in the doc for SerialPort.DataReceived, "Use the BytesToRead property to determine how much data is left to be read in the buffer."
here is the doc for SerialPort.BytesToRead
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.bytestoread.aspx