I have a barcode Scanner and I want to read the Barcode Prefix from the Hardware
on the hardware set, a two character like "01" or "AA" as a Prefix
I receive from comport "\u0002\0\0\u0001\031" what is it? Hex? Or Unicode?
Hex must be Like this : 0x30 // 0
0x31 // 1
Documentation
Here is my Write method an the Comport
public void GetPrefix(SerialPort serialPort)
{
try
{
if (serialPort.IsOpen)
{
Thread.Sleep(100);
Console.WriteLine("Open");
byte[] my_byte = new byte[9];
my_byte[0] = 0x7E;//Header
my_byte[1] = 0x00;//Header
my_byte[2] = 0x08;//Type
my_byte[3] = 0x01;//Lens
my_byte[4] = 0x63;//add
my_byte[5] = 0x71;//add
my_byte[6] = 0x08;//data : The data read
my_byte[7] = 0xAB;//CRC
my_byte[8] = 0xCD;//
serialPort.Write(my_byte, 0, 9);
rx_message = serialPort.ReadExisting();
Console.WriteLine(rx_message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Here is a DataReceivedHandler method
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep(1000);
SerialPort sp = (SerialPort)sender;
unicode = sp.ReadExisting(); //Read the data
Console.WriteLine(unicode);
}
catch (Exception)
{
throw;
}
}
What you received is what is written on page 68 of the document.
It indicates that the processing of the write command you sent has completed normally.
However, this is a strange phenomenon. The documentation only lists addresses from 0x0000 to 0x00E5, and the 0x6371(or 0x7163?) you specify is a private address.
You may have broken something in the barcode scanner by doing this.
And you sent a write command, which you wouldn't be able to use to read your intended barcode prefix.
You should use the read command, which is written from page 64 of the document.
By reading 0x11 bytes from 0x0060 of the address, you will be able to check the presence/absence, length, and data of the prefix.
Details of them can be found on pages 87-88 of the documentation.
Related
I have built application forms that use a serial port C#.
I want to save the last serial port number used and COM data in the .ini file when I close the executable.
So, I can use the same data for the next use of the application
private void btnSave_Click(object sender, EventArgs e)
{
try
{
_Ser.PortName = cBoxPort.Text;
_Ser.BaudRate = Convert.ToInt32(cBoxBaud.Text);
_Ser.DataBits = Convert.ToInt32(cBoxDatabits.Text);
_Ser.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBits.Text);
_Ser.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParitybits.Text);
this.Close();
string[] data = { cBoxPort.Text, cBoxDatabits.Text, cBoxStopBits.Text, cBoxParitybits.Text };
}
catch (Exception err)
{
MessageBox.Show(err.Message, ("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
MessageBox.Show("Configuration has been saved","Status");
}
I think the best way is for you to serialize the object with the data you want to save and to retrieve it, just deserialize the object.
Here is an example of how to do it with XML file:How to serialize/deserialize simple classes to XML and back
A simpler way is with JSON, here is an example applied to your code.
You will need the reference Newtonsoft.Json;
_Ser.PortName = cBoxPort.Text;
_Ser.BaudRate = Convert.ToInt32(cBoxBaud.Text);
_Ser.DataBits = Convert.ToInt32(cBoxDatabits.Text);
_Ser.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBits.Text);
_Ser.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParitybits.Text);
Serializing the object to a .json file
string dataFile = #"c:\DataFile.json";
string jsonString = JsonConvert.SerializeObject(_Ser);
File.WriteAllText(dataFile, jsonString);
Retrieving data from a .json file
string recoverdata = File.ReadAllText(dataFile);
_Ser = JsonConvert.DeserializeObject<[put here the type of your object "_ser"] >(recoverdata);
you need to generate a json and then save the port you last committed on that json.
When the program opens, you should read the last recorded port from the json and open the port again.
I want to do serial port communication with a machine which uses RS232-USB ports.
I am using serial port class. I am very new to the concept. In my first Machine interfacing I only had to do the serialport.readLine( to get the readings from the machine and there was no need to send ACK /NAK). but for the new machine interface the document says following things:
The following is an example of the RA500 communication:
Computer :<05h 31h 0dh>
RA500 :1st line of information
Computer :<06h 0dh>
RA500 :2nd line of information
Computer :<06h 0dh>
RA500 :”EOF”<0dh>
What i understood from this is i have to write to comport before reading from it. this is what i am doing in my code:
ACK = "06 0d"; NAK = "15 0d"; str = "05 31 0d";
while (count <= 5)
{
rx = ComPortDataReceived(str);
if (!string.IsNullOrEmpty(rx))
{
str = ACK;
returnReading += rx;
}
else if (string.IsNullOrEmpty(rx)) str = NAK;
count++;
}
private string ComPortDataReceived(string str)
{
string Rx = string.Empty;
string exceptionMessage = string.Empty;
try
{
byte[] bytes = str.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
comPort.Write(bytes, 0, bytes.Length);
Rx = comPort.ReadExisting();
PEHRsLibrary.writeTextFile(DateTime.Now + " RxString :" + Rx);
return Rx;
}
catch(Exception e){}
when i use this code i am receiving empty strings as responce. but if i use comPort.ReadExisting() only without using comPort.Write i am receving a string with all the readings but the probblem is it only gives one line of information and dosnt give 2nd or 3rd line readings.
when i try using comPort.ReadLine() after Write() I am getting Timeout exception.
i dont know what i am doing wrong in this case. I am writing ACk after receving 1st line but not receving 2nd line. Next thing i am gonna try is read() as byte and then convert it to string instead of using ReadExisting(). Any other way i can do this?
This is my first time integrating Serial to USB in a C# application, so please pardon me if this sounds like a stupid question.
I have Class IV laser. I am integrating that in to my C# application.
My problem is I can connect to the laser, I can send data to the laser but i don't get any return from the laser.
private void Bt_Start_Click(object sender, EventArgs e)
{
SerialPort serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.XOnXOff;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
serialPort.ReadTimeout = 500;
serialPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
ConenctToLaser("COM3", serialPort);
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buffer = new byte[sp.BytesToRead];
int bytesRead = sp.Read(buffer, 0, buffer.Length);
var message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
MessageBox.Show(message);
}
public void ConenctToLaser(string port, SerialPort serialPort)
{
StreamReader openfile = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\commands.txt");
if (serialPort.IsOpen == false)
{
serialPort.Open();
string command = "";
command = openfile.ReadLine();
while(command!=null)
{
byte[] buffer = Encoding.ASCII.GetBytes(command);
serialPort.Write(buffer, 0, buffer.Length);
command = openfile.ReadLine();
}
}
}
The commands.txt includes my commands. which are
\r
MTT\r
MCM\r
SPR300\r
on different lines
When i send these commands to the laser all i get back is the echo. So in reality when i send ("MTT\r") i should get back the temperature of the hardware. When i test my hardware in putty it works i get return for all the commands above. Here's the definition for one of the commands from the .pdf they have provided.
Laser Temperature Command: MTT\r
Description: The laser actual laser temperature expressed in XX.X degC
After hours of researching I found the answer to my question. From what i read online it seems like the SerialPort class by Microsoft doesn't work very well with all the serial Hardware. So I would need to use a wrapper class to work with Win32 API.
I found this article which explains how to use Win32 class to communicate with the serial device. It also has a wrapper to call the Win32 methods. You can read all about it and download all the code from the below link.
https://msdn.microsoft.com/en-us/magazine/cc301786.aspx
Hope this helps somebody who's having the same problem.
I am developing an application for GSM Modems (D-Link DWM-156) in C#.Net using AT commands. I have a problem sending English SMS.
I try to send "hello", But I receive □□□□ in my phone or ...exept hello.
serialPort1.DataBits = 8;
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
serialPort1.DiscardInBuffer();
serialPort1.DiscardOutBuffer();
serialPort1.WriteLine("AT\r");
Thread.Sleep(2000);
serialPort1.WriteLine("AT+CMGF=1\r");
Thread.Sleep(1000);
serialPort1.WriteLine("AT+CMGS=\"09390149196\"\r")
Thread.Sleep(2000);
serialPort1.WriteLine("hello" + "\x1A");
Thread.Sleep(1000);
Few fixes (maybe more but I don't see full-code).
Do not use WriteLine() but Write() because for \r (alone) is the command line and result code terminator character.
SerialPort.WriteLine() by default writes a usASCII encoded string but your GSM modem expect strings encoded as specified with an AT command. Set SerialPort.Encoding property to a specific encoding and send CSCS command. You can ask supported encodings with CSCS=? AT command. Even if default GSM should apply I'd avoid to rely implicitly on this.
You do not need to wait after each command but you have to wait for modem answer (checking for OK or ERROR strings).
From docs:
A command line is made up of three elements: the prefix, the body, and the termination character. The command line prefix consists of the characters "AT" or "at" [...] The termination character may be selected by a user option (parameter S3), the default being CR.
In pseudo-code:
void SendCommand(string command) {
serialPort.Write(command + "\r");
// Do not put here an arbitrary wait, check modem's response
// Reading from serial port (use timeout).
CheckResponse();
}
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.BaudRate = 9600;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.GetEncoding("iso-8859-1");
serialPort.DiscardInBuffer();
serialPort.DiscardOutBuffer();
SendCommand("AT"); // "Ping"
SendCommand("AT+CMGF=1"); // Message format
SendCommand("AT+CSCS=\"PCCP437\""); // Character set
SendCommand("AT+CMGS=\"123456\"") // Phone number
SendCommand("hello" + "\x1A"); // Message
To check response (absolutely avoid arbitrary waits!) you can start with something like this (raw untested adaption so you may need some debugging, see also this post):
AutoResetEvent _receive;
string ReadResponse(int timeout)
{
string response = string.Empty;
while (true)
{
if (_receive.WaitOne(timeout, false))
{
response += _port.ReadExisting();
}
else
{
if (response.Length > 0)
throw new InvalidOperationException("Incomplete response.");
else
throw new InvalidOperationException("No response.");
}
// Pretty raw implementation, I'm not even sure it covers
// all cases, a better parsing would be appreciated here.
// Also note I am assuming verbose V1 output with both \r and \n.
if (response.EndsWith("\r\nOK\r\n"))
break;
if (response.EndsWith("\r\n> "))
break;
if (response.EndsWith("\r\nERROR\r\n"))
break;
}
return response;
}
Adding _receive.Reset() just before you send your command and of course also adding OnPortDataReceived as handler for SerialPort.DataReceived event:
void OnPortDataReceived(object sender,
SerialDataReceivedEventArgs e)
{
if (e.EventType == SerialData.Chars)
_receive.Set();
}
If you have some trouble (but you can connect) you may replace \r with \n. Some modems incorrectly (assuming <CR> has not been mapped to anything else than 13 using S3 parameter) use this character as command line terminator by default (even if it should be present in output only for V1 verbose output). Either change your code or send appropriate S3.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a device that can communicate trough RS232. and it comes with the communication protocol to access the data.
I'm writing a simple c# program to connect and get the status from the device and Im not quite sure whether Im on the right path.
Below is the sample they have given.
Command 50: status request
The status request command is used to request the register response package, without later actions that may alter the status of the system.
0 1 2 3 4 5 6 7 8 9 10 11 12 13
STX ADDR ADDR CMOD "5" "0" "0" "3" TKN1 TKN0 TYPE CHKL CHKH 0X0D
STX = Start byte of the frame (0x02)
ADDR = TE550 logical address [2 bytes]
CMOD = CMOD to refer [1 byte]
TKN1/0 = Frame identification bytes [2 bytes]
TYPE = Selection byte for customizable box (RiqA/B)* [1 byte]
CHKH/L = Checksum [2 bytes]
END = End byte of the frame (0x0D)
Example:
status request from PC to TE550 (address 01), CMOD 1, Token 01, Type 1
[0x02]0115003011EE[0x0D]
I can connect to the com port using the serial port.
I am referring to the answer by DesMy "RS232 serial port communication c# win7 .net framework 3.5 sp1"
So far Im not getting any signal once write to the COM port. However I'm not quite sure whether Im sending the correct data to the com port. Currently Im sending data as below
comPort.Write("20115003011EE3");
Any help / sample code etc would be much appreciated.
public void ConnectRS232 ()
{
try
{
SerialPort mySerialPort = new SerialPort("COM1");
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 += DataReceivedHandler;
mySerialPort.Write("20115003011EE3");
}
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 });
}
private void DisplayToUI(string displayData)
{
textBox1.Text += displayData.Trim();
}
When dealing with low level port I/O, characters are not bytes!
Do not send strings. Create a byte stream containing the correct characters and send that.
[In .NET characters are shorts, not bytes. Doesn't matter. Use bytes.]