What I'm trying to do is send 1 in ASCII value, my mk waiting for that char.
But when I press a button nothing happens. But When I send a byte to toggle a PORT, everything is works. SO I wonder how to send in ASCII, 1 value.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) // Here i send a byte to MK
{
// serialPort1.RtsEnable = true; serialPort1.DtrEnable = true;
// var content = new List<byte>();
// content.AddRange(Encoding.ASCII.GetBytes("1"));
// content.Add(3); // ASCII ETX
//byte[] buffer = content.ToArray();
// serialPort1.Write(buffer, 0, buffer.Length);
serialPort1.Write("1");
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e) // choosing a right com port
{
serialPort1.PortName = textBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(textBox2.Text);
}
string rs;
byte re;
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) // Da
{
try
{
//rs = serialPort1.ReadByte();
//re = Convert.ToByte(serialPort1.ReadByte());
rs = serialPort1.ReadExisting();
// System.Text.Encoding.ASCII.GetString(new[] { re });
this.Invoke(new EventHandler(type));
}
catch (System.TimeoutException) { }
}
void type(object s,EventArgs e) // receive data
{
textBox4.Text += rs;
}
private void button3_Click(object sender, EventArgs e) // OPen port
{
serialPort1.Open();
}
private void button4_Click(object sender, EventArgs e) // Close port
{
serialPort1.Close();
}
}
You can write a string to the serial port in that way: the string must contain only ASCII characters in the range 0x00 to 0x7F since the ASCII encoding is used by default (you can change the encoding by setting the SerialPort.Encoding property).
As others have said in the comments, you need to append the ETX character to match the commented-out code, which you can do as follows:
serialPort1.Write("1\x03");
Or, more generally, if you want to build a string containing control characters, you can do something like:
const char STX = '\x02';
const char ETX = '\x03';
... etc, other control characters you want to use
...
var s = String.Format("1{0}", ETX);
serialPort1.Write(s);
Related
I will be glad if you tell me what I need to edit on the code. I want to separate the data I receive byte by byte, how do I do it?
namespace _1993
{
public partial class Form1 : Form
{
string[] ports = SerialPort.GetPortNames(); //Port Numaralarını ports isimli diziye atıyoruz.
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (string port in ports)
{
comboBox1.Items.Add(port); // Port isimlerini combobox1'de gösteriyoruz.
comboBox1.SelectedIndex = 0;
}
comboBox2.Items.Add("2400"); // Baudrate'leri kendimiz combobox2'ye giriyoruz.
comboBox2.Items.Add("4800");
comboBox2.Items.Add("9600");
comboBox2.Items.Add("19200");
comboBox2.Items.Add("115200");
comboBox2.SelectedIndex = 2;
label3.Text = "Bağlantı Kapalı"; //Bu esnada bağlantı yok.
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// Form kapandığında Seri Port Kapatılmış Olacak.
if (serialPort1.IsOpen == true)
{
serialPort1.Close();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
try
{
string sonuc = serialPort1.ReadExisting();//Serial.print kodu ile gelen analog veriyi alıyoruz,string formatında sonuc'a atıyoruz
if (sonuc != "")
{
label1.Text = sonuc + ""; //Labele yazdırıyoruz.
listBox1.Items.Add(sonuc); //labele yazdırdığını listboxa ekle
byte[] ba = Encoding.Default.GetBytes(sonuc);
var hexString = BitConverter.ToString(ba);
if (ba[0] == 0XFF)
{
Console.WriteLine(ba);
}
else
{
Console.WriteLine("hatalı");
}
//Console.WriteLine(ba[0]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); // basarısız olursa hata verecek.
timer1.Stop();
}
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start(); //250 ms olarak ayarladım timer'ı.
if (serialPort1.IsOpen == false)
{
if (comboBox1.Text == "")
return;
serialPort1.PortName = comboBox1.Text; // combobox1'e zaten port isimlerini aktarmıştık.
serialPort1.BaudRate = Convert.ToInt16(comboBox2.Text); //Seri Haberleşme baudrate'i combobox2 'de seçilene göre belirliyoruz.
try
{
serialPort1.Open(); //Haberleşme için port açılıyor
label3.ForeColor = Color.Green;
label3.Text = "Bağlantı Açık";
}
catch (Exception hata)
{
MessageBox.Show("Hata:" + hata.Message);
}
}
else
{
label3.Text = "Bağlantı kurulu !!!";
}
}
private void button2_Click(object sender, EventArgs e)
{
//BAĞLANTIYI KES BUTONU
timer1.Stop();
if (serialPort1.IsOpen == true)
{
serialPort1.Close();
label3.ForeColor = Color.Red;
label3.Text = "Bağlantı Kapalı";
}
}
private void button3_Click(object sender, EventArgs e)
{
listBox1.Items.Add(label1.Text); //Okunan veri listbox'a atılıyor
}
private void button4_Click(object sender, EventArgs e)
{
listBox1.Items.Clear(); // listbox temizleniyor.
}
private void label2_Click(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
SerialPort already returns bytes reads and returns bytes. ReadExisting converts those bytes to a string using the SerialPort.Encoding. To get the raw bytes use Read or ReadByte instead :
var buffer=byte[1024];
var read=port.Read(buffer,0,buffer.Length);
if (read>0 && buffer[0] == 0XFF)
{
....
}
You'll have to convert the bytes to a string explicitly using Encoding.GetString if you want to display the or write them to the console. :
var str=SerialPort.Encoding.GetString(buffer,0,read);
Be careful though.
The default for SerialPort.Encoding is ASCIIEncoding, the 7-bit US-ASCII encoding. This will mangle all non-Latin characters. If the port returnes non-US-ASCII text you'll have to find the proper encoding and use it. On a POS this would mangle non-English product names.
I'm currently working on a C# application and where I read Serial Data send through the USB port, where this data is to be shown on a textbox then eventually into a database. The code I have right now has it refresh to read serial data coming in every 2 seconds, but I cannot get the data onto the textBox. I'm fairly new to C# development so I am unsure as to what the best way to output my data onto a textbox or how to fix my problem in the first place. My code is below.
public partial class Form1 : Form
{
SerialPort mySerialPort = new SerialPort("COM3");
OleDbConnection connection = new OleDbConnection();
public Form1()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
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);
if (mySerialPort.IsOpen == false)
{
mySerialPort.Open();
}
}
public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
//gets data values from serial port
SerialPort sp = (SerialPort)sender;
string data = sp.ReadExisting();
string time = GetTimestamp(DateTime.Now);
int indata;
long timeStamp;
//parses strings to integers
indata = Int32.Parse(data);
timeStamp = Int64.Parse(time);
//writes to console
Console.WriteLine(indata);
Console.WriteLine(timeStamp);
//writes to text box
textBox1.Text = data;
Thread.Sleep(2000);
}
private void button3_Click(object sender, EventArgs e)
{
mySerialPort.Close();
}
private void label1_Click(object sender, EventArgs e)
{
}
public static string GetTimestamp(DateTime value)
{
return value.ToString("yyyyMMddHHmmss");
}
private void label1_Click_1(object sender, EventArgs e)
{
}
}
The event DataReceived is handled with the method DataReceivedHandler on a different thread than the control textBox1 is created. So when running your program you should have get a System.InvalidOperationException. Which states exactly what I just described.
To get out of this dilemma you can use the Control.BeginInvoke method which would:
Execute the specified delegate asynchronously on the thread that the control's underlying handle was created on.
Basically it would drag the piece of code down to the thread that cretated the control. In this case the main thread. This is how you would use it:
//writes to text box
textBox1.BeginInvoke(new Action(() => { textBox1.Text = data; }));
I hope it helps.
I'm back again with a little project I am stuck on at the moment, trying to receive and then acknowledge the receipt to get the next set of data from the COM1 device.
Basically the device is a Motorola MC1000 hand held barcode scanning device, the software that is on it, is linked to this program which no longer works but sends the data output via serial, and I have managed to get the data out manually by connecting to the port and then manually sending "%0" to the device to output all the data from memory.
So far, I have coded a program to connect to the com device, open the com port, and receive the buffer information, but I need to send an automatic acknowledgement to get all the data out.
The data is in the format of Barcode Qty.
Here is my code so far:
<!-- language: c# -->
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Add this variable
string RxString;
SerialPort ComPort = new SerialPort();
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ComPort.PortName = Convert.ToString(cboPorts.Text);
serialPort1.PortName = ComPort.PortName;
serialPort1.BaudRate = 9600;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
textBox1.ReadOnly = true;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// If the port is closed, don't try to send a character.
if(!serialPort1.IsOpen) return;
// If the port is Open, declare a char[] array with one element.
char[] buff = new char[1];
// Load element 0 with the key character.
buff[0] = e.KeyChar;
// Send the one character buffer.
//serialPort1.Write(buff, 0, 1);
if (e.KeyChar == (char)13) // enter key
{
serialPort1.Write("%0");
//textBox1.Text = "";
}
else if (e.KeyChar < 32 || e.KeyChar > 126)
{
e.Handled = true; // ignores anything else outside printable ASCII range
}
else
{
serialPort1.Write(e.KeyChar.ToString());
}
// Set the KeyPress event as handled so the character won't
// display locally. If you want it to display, omit the next line.
//e.Handled = true;
}
private void DisplayText(object sender, EventArgs e)
{
textBox1.AppendText(RxString);
}
private void serialPort1_DataReceived
(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting() + "\n";
this.Invoke(new EventHandler(DisplayText));
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ArrayComPortsNames = null;
int index = -1;
string ComPortName = null;
//Com Ports
ArrayComPortsNames = SerialPort.GetPortNames();
do
{
index += 1;
cboPorts.Items.Add(ArrayComPortsNames[index]);
} while (!((ArrayComPortsNames[index] == ComPortName) ||
(index == ArrayComPortsNames.GetUpperBound(0))));
Array.Sort(ArrayComPortsNames);
if (index == ArrayComPortsNames.GetUpperBound(0))
{
ComPortName = ArrayComPortsNames[0];
}
//get first item print in text
cboPorts.Text = ArrayComPortsNames[0];
}
private void cboPorts_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
I just somehow need to output this all automatically.
The following code is called several times to read data from a serial port in response to different commands sent to an attached chip & pin terminal.
However it fails to report any further responses after the 1st command.
Although there is data there, for the following commands, is not picked up or read.
How can I fix that?
I'm using ReadExisting serial port property.
private void MySerialReader()
{
ip_serialport.Open();
ip_serialport.DataReceived += serialPort_DataReceived;
//ip_serialport.Close(); //This causes the problems
}
public string RxString;
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = ip_serialport.ReadExisting();
this.Invoke(new EventHandler(DisplayText_RX)); //<<-- ????!!!
}
private void DisplayText_RX(object sender, EventArgs e)
{
RX_Box.Items.Add(RxString);
}
I think if you use timer then you can read remaining data
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = ip_serialport.ReadExisting();
this.Invoke(new EventHandler(DisplayText_RX));
}
private void DisplayText_RX(object sender, EventArgs e)
{
RX_Box.Items.Add(RxString);
if(RxString!="")
timer.start();
}
void timer_Tick(object sender, EventArgs e)
{
if(serialport.isopen)//check for open
{
RxString = ip_serialport.ReadExisting();
this.Invoke(new EventHandler(DisplayText_RX));
}
timer.stop();
}
I'm developing an application which communicates with my electronic circuit via Port 4. I can send data from the PC to the circuit without a problem; I then get data back from the circuit. However, when I try to get data from my circuit for the second time, I receive incorrect data from it. Any pointers on how to solve this?
This is C# code:
byte[] Sent_Byte = {1,2,3,4,5,6};
byte[] Received_Byte = new byte[10];
private void button_sendData_Click(object sender, EventArgs e)
{
// I send this data because the circuit is ready to get data
serialPort1.Write("G");
serialPort1.Write(Sent_Byte, 0, 6);
}
private void button_getData_Click(object sender, EventArgs e)
{
// I send this data because the circuit is ready to send data
serialPort1.Write("A");
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialPort1.Read(Received_Byte, 0, 10);
}
This is Arduino code:
char Control_OP=0;
char Received_Data[6];
byte Sent_Data[10];
void loop()
{
while(Serial.available())
{
Control_OP = Serial.read(); // determines whether receiving data or sending data
if(Control_OP=='G') // receiving data
{
Number=Serial.readBytes(Received_Data,6);
}
else if(Control_OP=='A') // sending data
{
Serial.write(Sent_Data,10);
}
}
}
I found the solution.
I changed this code
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialPort1.Read(Received_Byte, 0, 10);
}
into this one
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (int i = 0; i <Received_Byte.Length; i++)
{
Received_Byte[i] = Convert.ToByte(serialPort1.ReadByte());
}
}
Thanks everyone for helping me