Sending serial command to trigger scanner Honeywell 1900 - c#

The problem is, that I can trigger scanner using Serial Port software "Hercules" sending command <SYN>T<CR><LF>, in datasheet is said to use command [SYN]T[CR] to trigger scanner, but I cant trigger it (both commands) using my serial port comunication bellow.
I get input when use scanner manually but can't trigger it... What is a problem?
(The port is virtual)
private static SerialPort port;
private static bool _continue = false;
public static void Main(string[] args)
{
port = new SerialPort();
port.PortName = "COM8";
port.BaudRate = 115200;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Handshake = Handshake.None;
port.RtsEnable = true;
port.DtrEnable = true;
port.ReadTimeout = 500;
port.WriteTimeout = 500;
port.Open();
_continue = true;
Thread thr = new Thread(SerialPortProgram);
thr.Start();
}
private static void SerialPortProgram()
{
Console.WriteLine("Writing to port: <SYN>T<CR><LF>");
string command = "<SYN>T<CR><LF>";
port.WriteLine(command);
while (_continue)
{
try
{
string input = port.ReadLine();
Console.WriteLine("Input is - " + input);
}
catch (TimeoutException) { }
}
}

Python barcode scanner serial trigger is an article that I answered similar Python question.
The contents are shown below.
This happens because you coded the abstract expression written in the document as raw output data.
The document represents 3 bytes of data transmission.
'SYN' and 'CR' are the following hexadecimal numbers.
'SYN' = \x16
'CR' = \x0d or escape sequence \r
'T' is an ordinary ASCII character.
Whitespace and < > [ ] { } are used to delimit the data in the document, not the data to send.
And, even you need to command prefix it.
Also use Write instead of WriteLine as written by #Turbofant.
You should write like this. Please try it.
string command = "\x16M\x0d\x16T\x0d";
port.Write(command);

I guess the problem is, that you are sending the wrong command string.
The <Syn>, <CR> and <LF> stands for the special, non printable ascii characters synchronous idle, Carriage return and line feed.
You need to encode them correctly in the string
Try sending:
string command = "\x16t\r\n";
port.Write(command);
\x16is <Syn> (Because Syn is ascii character 0x16, or 22 in decimal )
\r is <CR>
\n is <LN>
And use port.Write instead of port.WriteLine, because WriteLine automatically adds the \r\n at the end of the string.

Related

read data from serialport

I am new to C# and programming in general.
I am trying to communicate with a ohmmeter which is conneted via usb to my computer.
I am able to configurate the device and even recieve data.
But i can not acces this data. I can just print it on to the console.
(Was inspired by the code on the microsoft site)
Here is the constructer of my "communication"-class where i configurate the port:
public SCPI_Commands()
{
_SerialPort.PortName = SetPortName(_SerialPort.PortName);
_SerialPort.BaudRate = 115200;
_SerialPort.Parity = Parity.None;
_SerialPort.DataBits = 8;
_SerialPort.StopBits = StopBits.One;
_SerialPort.Handshake = Handshake.None;
_SerialPort.ReadTimeout = 500;
_SerialPort.WriteTimeout = 500;
_SerialPort.Open();
_SerialPort.DataReceived += _serialPort_DataReceived;
}
Here is my function which sends a query to the device (The constant Measurment_Value represents a scpi command which is understood by my ohmmeter) :
public void get_measurement()
{
_SerialPort.WriteLine(Measurment_Value);
}
And here is the private function which checks if the device is sending data and printing it on the console (not sure how this function works) :
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(_SerialPort.ReadLine());
}
Unfortunately i am not able to return the data as a string. My goal is to do some calculations with the received data.
Does someone has any ideas ?
Greetings from Germany.
Luke
You can read from buffer to temp byte array and then get it as string, see the below example. Put this in _serialPort_DataReceived
// this the read buffer
byte[] buff = new byte[9600];
int readByteCount = _serialPort.BaseStream.Read(buff, 0, _serialPort.BytesToRead);
// you can specify other encodings, or use default
string response = System.Text.Encoding.UTF8.GetString(buff);
Side Note
If you want to keep your sanity while working with SerialPort, always send and receive as byte array. Then, get the equivalent string using Encoding.

How to send ctrl+z to serial port using c#

I have tried the following:
(This "whatever" is a 4 digit pin asked to enter after sending a AT+STGR=3,1 to the port)
1. this.port.WriteLine("whatever\0x1A");
2. this.port.WriteLine("whatever"+ char.ConvertFromUtf32(26));
3. this.port.WriteLine("whatever\u0001");
4. this.port.WriteLine("whatever"+(char)26);
5. this.port.WriteLine("whatever");
SendKeys.Send("^(z)");
6. this.port.WriteLine("whatever");
this.port.Write(new byte[] { 0x1A }, 0, 1);
7. this.port.WriteLine("whatever");
this.port.Write(new byte[] { 0x26}, 0, 1);
None of them works, but when using putty and entering the code followed by ctrl+z key everything works perfectly, so can anyone tell me exactly how does putty sends this ctrl+z to the serial port? Or if possible give a solution to this problem in c#?
The reply back from the modem every time I try the c# codes given above is:
+CME ERROR: 100
Serial Port Initialization:
port.PortName = "COM3";
port.BaudRate = 115200;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Parity = Parity.None;
port.ReadTimeout = 300;
port.WriteTimeout = 300;
port.Encoding = Encoding.GetEncoding("iso-8859-1");
port.DataReceived += new SerialDataReceivedEventHandler(this.port_DataReceived);
port.Open();
port.DtrEnable = true;
port.RtsEnable = true;
Find a ASCII map like this for the ctrl codes. Looks like for ctrl Z you need an ASCII 0x26. I would define it something like
char CtrlZ = (char)26;
char CR = (char)13;
serialport1.WriteLine(string.Format("whatever{0}{1}",CtrlZ, CR));
Try "whatever\u001A" or "whatever" Sleep "\u001A".
Also check the whole sequence of commands/responses you're sending/receiving through the connection.
This is an example, to be adapted to your specific case.
//TODO initialize the serialConnection and open it
//TODO specific commands...
serialConnection.WriteLine("AT+CPIN=\"1234\""); // replace according to your real situation
var response = serialConnection.ReadExisting();
Console.WriteLine("pin resp: " + response);
Thread.Sleep(200);
//TODO other specific commands?
serialConnection.Write("whatever");
//Thread.Sleep(200); uncomment this if it helps
serialConnection.Write(new byte[]{26}, 0, 1); // or Write("\u001A")
response = serialConnection.ReadExisting();
Console.WriteLine("ctrl-z resp: {0}", response);
//closing stuff, etc...

C# Serial Port Data, Format received data

So I'm reading data from the serial port, so far so good, but the data coming from the serial port is chunked, I've this protocol that states that every messages begin with SOH (\u0001 byte) and ends with EOT(\u0004), I tried to split the message by the SOH byte, but still having issues with that.
There's a more elegant and safe way to do this?
private void RecebendoDados(object sender, SerialDataReceivedEventArgs e)
{
try
{
var id_prova = Form1._Form1.IDPROVA;
var serie = Form1._Form1.SERIE;
var fase = Form1._Form1.FASE;
var http = new ComunicacaoWeb();
var sp = (SerialPort)sender;
var indata = sp.ReadExisting();
Console.WriteLine(indata+"\n\r");
if (!sp.IsOpen) {
sp.Open();
}
var pacotes = indata.Split(new[] { "\u0004" }, StringSplitOptions.None);
1
Theres a more elegant and safe way to do this?
If your message end with the EOT control code then SerialPort allows you to read exactly up to the first occurrence of this char.
SerialPort sp = (SerialPort)sender;
// this lines converts the hex-code of EOT to a char and read the incoming
// message only up to this point
string indata = sp.ReadTo(Convert.ToChar(0x04));
now you need only to get rid of the SOT:
indata = indata.TrimStart(Convert.ToChar(0x01));
at this point you should have on clean message.
The property BytesToRead will tell you whether there is still data in the buffer:
int stillToBeRead = sp.BytesToRead;
you can check it and repeat the reading procedure if necessary.
2.
Theres a more ellegant and safe way to do this?
if you try to read from a closed port then it will fail with a System.InvalidOperationException. By this logic the if-condition in your code will never be entered to reopen the port.
var sp = (SerialPort)sender;
var indata = sp.ReadExisting();
if (!sp.IsOpen) {
// this will never be executed
sp.Open();
}
you should check whether the port is open and there is data to read before attempting to read from it. I guess RecebendoDados is the DataReceived event, so the probability of having a closed port and no data to read is low, but still: the devil sleeps in the detail ;)

SerialPort read just first character of string

I create small test app to test connection between app and some device which measure temperature. When I write some command to device it's ok, but when device return me response, a string, for that I use ReadExisting() method. But app reads just first character of the string. If I send command again, it's same situation. I try to test connection with program called Terminal.exe, it's happens the same. But when I change BaudRate at some value and return BaudRate on 9600 ( it's ok rate ), then it's worked fine. Also I try to change BaudRate in my app, but it give me the same, just first character of string. Also I have an app written in LabView which works fine.
Also I tested my app with another PC with Terminal.exe , and it's worked fine.
private void SetUpPort()
{
port = new SerialPort();
port.PortName = port_name;
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Handshake = Handshake.None;
port.ReadTimeout = 1000;
p.DataReceived += new SerialDataReceivedEventHandler(PortDataReceived);
}
private void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
recived_data += port.ReadExisting();
}
I would be very thankful for any help.
That is not how to use the SerialPort component. You need to attach the DataReceived event handler, which is called every time data comes in on the serial port. An example is found on the page I linked.
You need to append data until you know you're done! You can't just call ReadExisting and assume you get all the information. Do something like this:
private string inBuffer = String.Empty;
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
inBuffer += indata;
if (<inBuffer fulfills some criteria that tells you it's a complete message>)
{
ProcessInBuffer(inBuffer);
inBuffer = String.Empty;
}
}
It is your task to determine the criteria to fulfill. This may be that the received data as a certain length (if the records are fixed length), or maybe they end with newline characters or something else.
you will use datareceived event to store all the data in a array or string and after you can use every data of that string indata += sp.ReadExisting();

Problem with receiving data form serial port in c#?

hello i have problem with receiving data from serial port in c# in am inserting a new line operator at the end of data buffer. then i send this data buffer on serial port, after this my c# GUI receiver will take this data via Readline() function but it always give me raw data not the actual one how to resolve this problem.
//configuring the serial port this code in c# with problem
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
//opening the serial port
if(!serialPort.IsOpen)
serialPort.Open();
//read 2byte data for msG code from serial port
string strReadData=serialPort.ReadLine();
char[] temp=new char[350];
//strReadData.CopyTo(1, temp, 0, strReadData.Length - 2);
//strReadData = temp.ToString();
//string strReadData = serialPort.ReadExisting();
//strReadData.Replace(' ', '\0');
//strReadData.Replace(' ', '');
byte[] RecievedData = Encoding.ASCII.GetBytes(strReadData);
RecievedDataDecoder(RecievedData);
//close the port
if(serialPort.IsOpen)
serialPort.Close();
but my c++ receiver is working perfectly i dont know what is the problem here is working c++ code
// variables used with the com port
BOOL m_bPortReady;
HANDLE m_hCom;
DCB m_dcb;
COMMTIMEOUTS m_CommTimeouts;
BOOL bWriteRC;
BOOL bReadRC;
DWORD iBytesWritten;
DWORD iBytesRead;
DWORD dwCommEvent;
DWORD dwRead;
char sBuffer[128];
m_hCom = CreateFile("Com1",
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security
OPEN_EXISTING,
0, // no overlapped I/O
NULL); // null template
m_bPortReady = SetupComm(m_hCom, 128, 128); // set buffer sizes
m_bPortReady = GetCommState(m_hCom, &m_dcb);
m_dcb.BaudRate = 9600;
m_dcb.ByteSize = 8;
m_dcb.Parity = NOPARITY;
m_dcb.StopBits = ONESTOPBIT;
m_dcb.fAbortOnError = TRUE;
m_bPortReady = SetCommState(m_hCom, &m_dcb);
m_bPortReady = GetCommTimeouts (m_hCom, &m_CommTimeouts);
m_CommTimeouts.ReadIntervalTimeout = 50;
m_CommTimeouts.ReadTotalTimeoutConstant = 50;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 10;
m_CommTimeouts.WriteTotalTimeoutConstant = 50;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 10;
m_bPortReady = SetCommTimeouts (m_hCom, &m_CommTimeouts);
if (!SetCommMask(m_hCom, EV_RXCHAR))
{
printf("Error in set comm mask");
}
while(1)
{
if (WaitCommEvent(m_hCom, &dwCommEvent, NULL))
{
if (ReadFile(m_hCom, &sBuffer, 128, &iBytesRead, NULL))
printf("");
else
{
printf("Error in reading");
break;
}
}
else
{
printf("Error in Waiting");
break;
}
printf("%s",sBuffer);
strcpy(sBuffer,"");
}
CloseHandle(m_hCom);
getch();
exit(0);
Your question is a bit vague, but the ReadLine() method will return when the port receives a carriage return and line feed byte combination by default on Windows. Or \r\n, or 0x0d 0x0a if you prefer.
If the 'buffer' you are sending in the fist place contains several messages delimited by \r\n, then ReadLine() will only return the first one, then the port will close in the C# code you have posted.
Maybe your code is in a loop, but it is not shown.
Beyond that, after any data that you have received, your are converting it back to an array of bytes, determined by ASCII encoding. Are you sending ASCII in the first place? If not, it is likely that you could be missing information.
Also, if all you do is convert the received string into bytes, you could just receive the data as bytes in the first place.
I think you need to explain in a bit more detail exactly what is in the buffer you are sending, and what exactly do you receive.
Most of my serial port errors are caused by bad baude rate settings. This might be your problem too. (You can set the baude rate in some constructors of the SerialPort class, or with the BaudRate property)

Categories

Resources